Version Description
- Enhancement: The WordPress visual editor now displays a full gallery preview.
-
Enhancement: You can now paginate your galleries. This is especially useful in large multi-hundred item galleries.
To enable pagination in your galleries, simply use
limit=##
. - Enhancement: All CSS & JavaScript is now served minified to ensure the fastest possible load time for your site.
- Enhancement: When using taxonomies to generate your galleries (eg: media categories) you can now use term slug instead of the name. Thanks andremalenfant for suggesting this!
- Enhancement: The structure of the gallery output has been cleaned up, making it easier to style if you chose to use custom CSS. NOTE: This modified structure may break existing custom CSS or PHP filtering, so be sure to check this if you're using either of those features.
- Bug Fix: The storage of the DG thumbnail cache was very broken. Due to how the cache was originally designed, it ran into issues at large scale and on busy sites, which resulted in difficult to track bugs. The entire storage mechanism for the cache has been rewritten from the ground up to address this issue, which will result in faster gallery generation and more reliable performance.
- Bug Fix: In the thumbnail management tab of the DG settings, sorting by title was broken. This has been fixed.
-
Bug Fix:
Limit
was not working in cases where theids
orinclude
attribute were present. This has been fixed. - Tested Up To: Document Gallery has been tested in WP 4.4 beta.
Download this release
Release Info
Developer | dan.rossiter |
Plugin | Document Gallery |
Version | 4.0 |
Comparing to | |
See all releases |
Code changes from version 3.5.4 to 4.0
- README.txt +34 -12
- admin/class-admin.php +143 -111
- admin/class-ajax-handler.php +51 -0
- admin/media-manager-template.php +73 -30
- assets/css/admin.css +5 -5
- assets/css/admin.min.css +1 -1
- assets/css/style.css +19 -13
- assets/css/style.min.css +1 -1
- assets/js/gallery.js +95 -18
- assets/js/gallery.min.js +3 -2
- assets/js/media_manager.js +238 -67
- assets/js/media_manager.min.js +15 -10
- document-gallery.php +7 -8
- inc/class-document-gallery.php +6 -26
- inc/class-document.php +31 -23
- inc/class-gallery-sanitization.php +496 -0
- inc/class-gallery.php +133 -486
- inc/class-image-editor-imagick.php +2 -3
- inc/class-setup.php +52 -30
- inc/class-thumb.php +412 -0
- inc/class-thumber.php +47 -71
- inc/class-util.php +17 -19
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¤cy_code=USD&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted
|
5 |
Requires at least: 4.1
|
6 |
-
Tested up to: 4.
|
7 |
-
Stable tag:
|
8 |
License: GPLv2
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
@@ -186,8 +186,8 @@ documents are displayed in ascending or descending order.
|
|
186 |
The relation option should only be used when also using the *category or custom
|
187 |
taxonomy* option (see above).
|
188 |
|
189 |
-
When using multiple taxa this option allows you to decide whether the attachments
|
190 |
-
returned must match all of the different taxa specified (AND) or a minimum of one
|
191 |
taxa match (OR).
|
192 |
|
193 |
*NOTE: This has no bearing on the relationship between different terms for a single
|
@@ -239,10 +239,6 @@ of a gallery: `dg_gallery_template`, `dg_row_template`, and `dg_icon_template`.
|
|
239 |
These filtered templates are used when dynamically generating output for each
|
240 |
gallery.
|
241 |
|
242 |
-
*NOTE: The `dg_doc_icon` has been deprecated with the release and is
|
243 |
-
scheduled to be removed in a future release. If you are using this
|
244 |
-
filter, you are encouraged to replace its usages with `dg_icon_template`.*
|
245 |
-
|
246 |
Each of the following filters provides an bool argument which indicates
|
247 |
whither the gallery being generated will display descriptions, which
|
248 |
allows you to handle galleries with and without descriptions differently.
|
@@ -253,10 +249,12 @@ content prior to or following your document galleries. The filter
|
|
253 |
exposes 2 special tags which are replaced during gallery generation
|
254 |
with data specific to that gallery. The tag is described below:
|
255 |
|
256 |
-
* **%id%**:
|
|
|
|
|
257 |
* **%rows%**: This tag is replaced by all of the document gallery rows.
|
258 |
-
Everything before this string will be rendered before the gallery and
|
259 |
-
everything after this string will be rendered following the gallery.
|
260 |
|
261 |
|
262 |
If you wish to modify how gallery rows are generated, `dg_row_template`,
|
@@ -299,7 +297,7 @@ for a given attachment.
|
|
299 |
|
300 |
The value being filtered is an associative array with keys equal to a regular
|
301 |
expression matching all file extensions supported by the generator and values
|
302 |
-
equal to [callables](http://www.php.net/manual/en/language.types.callable.php)
|
303 |
which take an **attachment ID** and a **file page number** as arguments.
|
304 |
|
305 |
The callable given should return false if thumbnail generation fails or
|
@@ -378,6 +376,12 @@ CSS being loaded by returning false in `dg_use_default_gallery_style` filter, li
|
|
378 |
== Frequently Asked Questions ==
|
379 |
|
380 |
|
|
|
|
|
|
|
|
|
|
|
|
|
381 |
= Q: Ghostscript is installed on my server, but it's not working! =
|
382 |
|
383 |
A: Document Gallery does a pretty good job of detecting where Ghostscript is installed,
|
@@ -439,6 +443,24 @@ To see a list of features planned for the future as well as to propose your own
|
|
439 |
ideas for future Document Gallery development, take a look at our
|
440 |
[issue tracker](https://github.com/thenadz/document-gallery/issues).
|
441 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
442 |
= 3.5.4 =
|
443 |
* **Bug Fix:** There were issues in the structure of HTML generated for galleries. This resulted in issues
|
444 |
with icon generation.
|
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¤cy_code=USD&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted
|
5 |
Requires at least: 4.1
|
6 |
+
Tested up to: 4.4
|
7 |
+
Stable tag: 4.0
|
8 |
License: GPLv2
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
186 |
The relation option should only be used when also using the *category or custom
|
187 |
taxonomy* option (see above).
|
188 |
|
189 |
+
When using multiple taxa this option allows you to decide whether the attachments
|
190 |
+
returned must match all of the different taxa specified (AND) or a minimum of one
|
191 |
taxa match (OR).
|
192 |
|
193 |
*NOTE: This has no bearing on the relationship between different terms for a single
|
239 |
These filtered templates are used when dynamically generating output for each
|
240 |
gallery.
|
241 |
|
|
|
|
|
|
|
|
|
242 |
Each of the following filters provides an bool argument which indicates
|
243 |
whither the gallery being generated will display descriptions, which
|
244 |
allows you to handle galleries with and without descriptions differently.
|
249 |
exposes 2 special tags which are replaced during gallery generation
|
250 |
with data specific to that gallery. The tag is described below:
|
251 |
|
252 |
+
* **%id%**: The id attribute value for this gallery.
|
253 |
+
* **%class%**: The class attribute value for this gallery.
|
254 |
+
* **%data%**: The one ore more data-* attributes for the gallery, which are necessary for client-side operations.
|
255 |
* **%rows%**: This tag is replaced by all of the document gallery rows.
|
256 |
+
Everything before this string will be rendered before the gallery and
|
257 |
+
everything after this string will be rendered following the gallery.
|
258 |
|
259 |
|
260 |
If you wish to modify how gallery rows are generated, `dg_row_template`,
|
297 |
|
298 |
The value being filtered is an associative array with keys equal to a regular
|
299 |
expression matching all file extensions supported by the generator and values
|
300 |
+
equal to [callables](http://www.php.net/manual/en/language.types.callable.php)
|
301 |
which take an **attachment ID** and a **file page number** as arguments.
|
302 |
|
303 |
The callable given should return false if thumbnail generation fails or
|
376 |
== Frequently Asked Questions ==
|
377 |
|
378 |
|
379 |
+
= Q: I'm using taxonomies, but nothing is showing up in my gallery =
|
380 |
+
|
381 |
+
A: Remember that Document Gallery defaults to retrieving just attachments for the current post/page.
|
382 |
+
If you want a broader scope of attachments, you'll also need tell Document Gallery to search everywhere
|
383 |
+
like so: `[dg id=-1 category="My Awesome Category"]`.
|
384 |
+
|
385 |
= Q: Ghostscript is installed on my server, but it's not working! =
|
386 |
|
387 |
A: Document Gallery does a pretty good job of detecting where Ghostscript is installed,
|
443 |
ideas for future Document Gallery development, take a look at our
|
444 |
[issue tracker](https://github.com/thenadz/document-gallery/issues).
|
445 |
|
446 |
+
= 4.0 =
|
447 |
+
* **Enhancement:** The WordPress visual editor now displays a full gallery preview.
|
448 |
+
* **Enhancement:** You can now paginate your galleries. This is especially useful in large multi-hundred item galleries.
|
449 |
+
To enable pagination in your galleries, simply use `limit=##`.
|
450 |
+
* **Enhancement:** All CSS & JavaScript is now served minified to ensure the fastest possible load time for your site.
|
451 |
+
* **Enhancement:** When using taxonomies to generate your galleries (eg: media categories) you can now use term slug
|
452 |
+
instead of the name. *Thanks andremalenfant for suggesting this!*
|
453 |
+
* **Enhancement:** The structure of the gallery output has been cleaned up, making it easier to style if you chose to
|
454 |
+
use custom CSS. *NOTE: This modified structure may break existing custom CSS or PHP filtering, so be sure to check
|
455 |
+
this if you're using either of those features.*
|
456 |
+
* **Bug Fix:** The storage of the DG thumbnail cache was very broken. Due to how the cache was originally designed, it
|
457 |
+
ran into issues at large scale and on busy sites, which resulted in difficult to track bugs. The entire storage
|
458 |
+
mechanism for the cache has been rewritten from the ground up to address this issue, which will result in faster
|
459 |
+
gallery generation and more reliable performance.
|
460 |
+
* **Bug Fix:** In the thumbnail management tab of the DG settings, sorting by title was broken. This has been fixed.
|
461 |
+
* **Bug Fix:** `Limit` was not working in cases where the `ids` or `include` attribute were present. This has been fixed.
|
462 |
+
* **Tested Up To:** Document Gallery has been tested in WP 4.4 beta.
|
463 |
+
|
464 |
= 3.5.4 =
|
465 |
* **Bug Fix:** There were issues in the structure of HTML generated for galleries. This resulted in issues
|
466 |
with icon generation.
|
admin/class-admin.php
CHANGED
@@ -72,6 +72,8 @@ class DG_Admin {
|
|
72 |
|
73 |
/**
|
74 |
* Adds settings link to main plugin view.
|
|
|
|
|
75 |
*/
|
76 |
public static function addSettingsLink( $links ) {
|
77 |
$settings = '<a href="options-general.php?page=' . DG_OPTION_NAME . '">' .
|
@@ -83,6 +85,9 @@ class DG_Admin {
|
|
83 |
|
84 |
/**
|
85 |
* Adds donate link to main plugin view.
|
|
|
|
|
|
|
86 |
*/
|
87 |
public static function addDonateLink( $links, $file ) {
|
88 |
if ( $file === DG_BASENAME ) {
|
@@ -110,23 +115,13 @@ class DG_Admin {
|
|
110 |
|
111 |
/**
|
112 |
* Enqueues styles and scripts for the admin settings page.
|
|
|
113 |
*/
|
114 |
public static function enqueueScriptsAndStyles( $hook ) {
|
115 |
if ( in_array( $hook, array( DG_Admin::$hook, 'post.php', 'post-new.php' ), true ) ) {
|
116 |
// Settings Page
|
117 |
DG_Util::enqueueAsset( 'document-gallery-admin', 'assets/css/admin.css' );
|
118 |
|
119 |
-
// gracefully degrade for older WP versions
|
120 |
-
if ( version_compare( get_bloginfo( 'version' ), '3.8', '<' ) ) { ?>
|
121 |
-
<style type="text/css">
|
122 |
-
.dashicons, .nav-tab:before, .deleteSelected:before, .clearLog:before, .expandAll:before,
|
123 |
-
.collapseAll:before, .logLabel.date:before, .collapser:after, .expander:after,
|
124 |
-
#ThumbsTable .title a:after, #LogTable>tbody a:after {
|
125 |
-
display: none !important;
|
126 |
-
}
|
127 |
-
</style>
|
128 |
-
<?php }
|
129 |
-
|
130 |
DG_Util::enqueueAsset( 'document-gallery-admin', 'assets/js/admin.js', array( 'jquery' ) );
|
131 |
wp_localize_script( 'document-gallery-admin', 'dg_admin_vars', array( 'upload_limit' => wp_max_upload_size() ) );
|
132 |
if ( $hook !== self::$hook ) { //if $hook is 'post.php' or 'post-new.php'
|
@@ -134,22 +129,58 @@ class DG_Admin {
|
|
134 |
|
135 |
// Media Manager
|
136 |
global $dg_options;
|
137 |
-
DG_Util::enqueueAsset( '
|
138 |
-
wp_localize_script( '
|
139 |
-
'
|
140 |
-
'
|
141 |
-
'
|
142 |
-
'
|
143 |
-
'
|
144 |
-
'
|
145 |
-
'
|
146 |
-
'
|
|
|
|
|
|
|
147 |
) );
|
148 |
-
wp_localize_script( '
|
|
|
|
|
|
|
|
|
149 |
}
|
150 |
}
|
151 |
}
|
152 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
153 |
/**
|
154 |
* Load Document Gallery Custom templates.
|
155 |
*/
|
@@ -181,6 +212,7 @@ class DG_Admin {
|
|
181 |
global $dg_options;
|
182 |
|
183 |
include_once DG_PATH . 'inc/class-gallery.php';
|
|
|
184 |
include_once DG_PATH . 'inc/class-thumber.php';
|
185 |
|
186 |
$defaults = $dg_options['gallery'];
|
@@ -207,7 +239,7 @@ class DG_Admin {
|
|
207 |
'name' => 'gallery_defaults][attachment_pg',
|
208 |
'value' => esc_attr( $defaults['attachment_pg'] ),
|
209 |
'option_name' => DG_OPTION_NAME,
|
210 |
-
'description' => __( 'Link to attachment page rather than to file', 'document-gallery' )
|
211 |
) );
|
212 |
|
213 |
add_settings_field(
|
@@ -232,7 +264,7 @@ class DG_Admin {
|
|
232 |
'name' => 'gallery_defaults][descriptions',
|
233 |
'value' => esc_attr( $defaults['descriptions'] ),
|
234 |
'option_name' => DG_OPTION_NAME,
|
235 |
-
'description' => __( 'Include document descriptions', 'document-gallery' )
|
236 |
) );
|
237 |
|
238 |
add_settings_field(
|
@@ -244,7 +276,7 @@ class DG_Admin {
|
|
244 |
'name' => 'gallery_defaults][fancy',
|
245 |
'value' => esc_attr( $defaults['fancy'] ),
|
246 |
'option_name' => DG_OPTION_NAME,
|
247 |
-
'description' => __( 'Use auto-generated document thumbnails', 'document-gallery' )
|
248 |
) );
|
249 |
|
250 |
add_settings_field(
|
@@ -255,9 +287,9 @@ class DG_Admin {
|
|
255 |
'label_for' => 'label_gallery_defaults_order',
|
256 |
'name' => 'gallery_defaults][order',
|
257 |
'value' => esc_attr( $defaults['order'] ),
|
258 |
-
'options' =>
|
259 |
'option_name' => DG_OPTION_NAME,
|
260 |
-
'description' => __( 'Ascending or descending sorting of documents', 'document-gallery' )
|
261 |
) );
|
262 |
|
263 |
add_settings_field(
|
@@ -268,9 +300,9 @@ class DG_Admin {
|
|
268 |
'label_for' => 'label_gallery_defaults_orderby',
|
269 |
'name' => 'gallery_defaults][orderby',
|
270 |
'value' => esc_attr( $defaults['orderby'] ),
|
271 |
-
'options' =>
|
272 |
'option_name' => DG_OPTION_NAME,
|
273 |
-
'description' => __( 'Which field to order documents by', 'document-gallery' )
|
274 |
) );
|
275 |
|
276 |
add_settings_field(
|
@@ -281,9 +313,9 @@ class DG_Admin {
|
|
281 |
'label_for' => 'label_gallery_defaults_relation',
|
282 |
'name' => 'gallery_defaults][relation',
|
283 |
'value' => esc_attr( $defaults['relation'] ),
|
284 |
-
'options' =>
|
285 |
'option_name' => DG_OPTION_NAME,
|
286 |
-
'description' => __( 'Whether matched documents must have all taxa_names (AND) or at least one (OR)', 'document-gallery' )
|
287 |
) );
|
288 |
|
289 |
add_settings_field(
|
@@ -321,7 +353,19 @@ class DG_Admin {
|
|
321 |
'name' => 'gallery_defaults][new_window',
|
322 |
'value' => esc_attr( $defaults['new_window'] ),
|
323 |
'option_name' => DG_OPTION_NAME,
|
324 |
-
'description' => __( 'Open thumbnail links in new window', 'document-gallery' )
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
325 |
) );
|
326 |
|
327 |
add_settings_field(
|
@@ -332,7 +376,7 @@ class DG_Admin {
|
|
332 |
'label_for' => 'label_gallery_defaults_post_status',
|
333 |
'name' => 'gallery_defaults][post_status',
|
334 |
'value' => esc_attr( $defaults['post_status'] ),
|
335 |
-
'options' =>
|
336 |
'option_name' => DG_OPTION_NAME,
|
337 |
'description' => __( 'Which post status to look for when querying documents.', 'document-gallery' )
|
338 |
) );
|
@@ -345,7 +389,7 @@ class DG_Admin {
|
|
345 |
'label_for' => 'label_gallery_defaults_post_type',
|
346 |
'name' => 'gallery_defaults][post_type',
|
347 |
'value' => esc_attr( $defaults['post_type'] ),
|
348 |
-
'options' =>
|
349 |
'option_name' => DG_OPTION_NAME,
|
350 |
'description' => __( 'Which post type to look for when querying documents.', 'document-gallery' )
|
351 |
) );
|
@@ -506,7 +550,7 @@ class DG_Admin {
|
|
506 |
global $dg_options;
|
507 |
return $dg_options;
|
508 |
} else {
|
509 |
-
if (
|
510 |
unset( $values['ajax'] );
|
511 |
define( 'DOING_AJAX', true );
|
512 |
}
|
@@ -571,16 +615,8 @@ class DG_Admin {
|
|
571 |
|
572 |
// delete thumb cache to force regeneration if max dimensions changed
|
573 |
if ( $ret['thumber']['width'] !== $dg_options['thumber']['width'] ||
|
574 |
-
$ret['thumber']['height'] !== $dg_options['thumber']['height']
|
575 |
-
|
576 |
-
foreach ( $ret['thumber']['thumbs'] as $v ) {
|
577 |
-
if ( isset( $v['thumber'] ) ) {
|
578 |
-
@unlink( $v['thumb_path'] );
|
579 |
-
}
|
580 |
-
}
|
581 |
-
|
582 |
-
$ret['thumber']['thumbs'] = array();
|
583 |
-
$thumbs_cleared = true;
|
584 |
}
|
585 |
|
586 |
// handle setting the active thumbers
|
@@ -590,16 +626,7 @@ class DG_Admin {
|
|
590 |
|
591 |
// if new thumbers available, clear failed thumbnails for retry
|
592 |
if ( ! $thumbs_cleared ) {
|
593 |
-
|
594 |
-
if ( ! $v && $ret['thumber']['active'][ $k ] ) {
|
595 |
-
foreach ( $dg_options['thumber']['thumbs'] as $k2 => $v2 ) {
|
596 |
-
if ( empty( $v['thumber'] ) ) {
|
597 |
-
unset( $ret['thumber']['thumbs'][ $k2 ] );
|
598 |
-
}
|
599 |
-
}
|
600 |
-
break;
|
601 |
-
}
|
602 |
-
}
|
603 |
}
|
604 |
|
605 |
// handle modified CSS
|
@@ -631,16 +658,8 @@ class DG_Admin {
|
|
631 |
// Thumbnail(s) cleanup;
|
632 |
// cleanup value is a marker
|
633 |
if ( isset( $values['cleanup'] ) && isset( $values['ids'] ) ) {
|
634 |
-
$deleted = array_values( array_intersect( array_keys(
|
635 |
-
|
636 |
-
foreach ( $deleted as $k ) {
|
637 |
-
if ( isset( $ret['thumber']['thumbs'][ $k ]['thumber'] ) ) {
|
638 |
-
@unlink( $ret['thumber']['thumbs'][ $k ]['thumb_path'] );
|
639 |
-
}
|
640 |
-
|
641 |
-
unset( $ret['thumber']['thumbs'][ $k ] );
|
642 |
-
}
|
643 |
-
|
644 |
$responseArr['result'] = true;
|
645 |
$responseArr['deleted'] = $deleted;
|
646 |
}
|
@@ -671,17 +690,12 @@ class DG_Admin {
|
|
671 |
|
672 |
// Thumbnail file manual refresh (one at a time)
|
673 |
// upload value is a marker
|
674 |
-
elseif ( isset( $values['upload'] ) && isset( $_FILES['file'] ) &&
|
675 |
-
$old_path = DG_Util::hasThumb( $ID ) ? $ret['thumber']['thumbs'][ $ID ]['thumb_path'] : null;
|
676 |
$uploaded_filename = self::validateUploadedFile();
|
677 |
-
|
678 |
-
|
679 |
-
|
680 |
-
|
681 |
-
$responseArr['result'] = true;
|
682 |
-
$responseArr['url'] = $dg_options['thumber']['thumbs'][ $ID ]['thumb_url'];
|
683 |
-
$ret['thumber']['thumbs'][ $ID ] = $dg_options['thumber']['thumbs'][ $ID ];
|
684 |
-
}
|
685 |
}
|
686 |
|
687 |
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
|
@@ -904,13 +918,13 @@ class DG_Admin {
|
|
904 |
self::$URL_params = array( 'page' => DG_OPTION_NAME, 'tab' => 'Thumbnail' );
|
905 |
$orderby = self::$URL_params['orderby'] = self::getOrderbyParam($orderby_options);
|
906 |
$order = self::$URL_params['order'] = self::getOrderParam($order_options);
|
907 |
-
$limit = self::$URL_params['limit'] = self::getLimitParam(
|
908 |
|
909 |
-
$thumbs = $options['
|
910 |
uasort( $thumbs, array( __CLASS__, 'cmpThumb' ) );
|
911 |
-
$thumbs_number = count( $
|
912 |
$lastsheet = ceil( $thumbs_number / $limit );
|
913 |
-
$sheet =
|
914 |
if ( $sheet === 0 || $sheet > $lastsheet ) {
|
915 |
$sheet = 1;
|
916 |
}
|
@@ -934,13 +948,14 @@ class DG_Admin {
|
|
934 |
foreach ( $posts as $post ) {
|
935 |
$path_parts = pathinfo( $post->guid );
|
936 |
|
937 |
-
$
|
938 |
-
$
|
939 |
-
$t
|
|
|
|
|
|
|
940 |
$t['description'] = $post->post_content;
|
941 |
-
$t['icon'] =
|
942 |
-
? $t['thumb_url']
|
943 |
-
: DG_Thumber::getDefaultThumbnail( $post->ID );
|
944 |
}
|
945 |
unset( $posts );
|
946 |
|
@@ -969,7 +984,7 @@ class DG_Admin {
|
|
969 |
|
970 |
$pagination = '<div class="alignleft bulkactions"><button class="button action deleteSelected">' . __( 'Delete Selected', 'document-gallery' ) . '</button></div><div class="tablenav-pages">' .
|
971 |
'<span class="displaying-num">' .
|
972 |
-
$thumbs_number . ' ' . _n( 'item', 'items', $thumbs_number ) .
|
973 |
'</span>' . ( $lastsheet > 1 ?
|
974 |
'<span class="pagination-links">' .
|
975 |
'<a class="first-page' . ( $sheet == 1 ? ' disabled' : '' ) . '" title="' . __( 'Go to the first page', 'document-gallery' ) . '"' . ( $sheet == 1 ? '' : ' href="?' . http_build_query( self::$URL_params ) . '"' ) . '>«</a>' .
|
@@ -1065,12 +1080,17 @@ class DG_Admin {
|
|
1065 |
<?php }
|
1066 |
|
1067 |
/**
|
1068 |
-
* @param $limit_options array The possible options for limit. If no limit was provided then this is used to find a default limit.
|
1069 |
-
*
|
1070 |
* @return int The limit, which may or may not be a member of $limit_options.
|
1071 |
*/
|
1072 |
-
private static function getLimitParam(
|
1073 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1074 |
}
|
1075 |
|
1076 |
/**
|
@@ -1079,7 +1099,7 @@ class DG_Admin {
|
|
1079 |
* @return string The order value.
|
1080 |
*/
|
1081 |
private static function getOrderParam($order_options) {
|
1082 |
-
$ret =
|
1083 |
return in_array($ret, $order_options) ? $ret : $order_options[0];
|
1084 |
}
|
1085 |
|
@@ -1089,8 +1109,8 @@ class DG_Admin {
|
|
1089 |
* @return string The orderby value.
|
1090 |
*/
|
1091 |
private static function getOrderbyParam($orderby_options) {
|
1092 |
-
$ret =
|
1093 |
-
return in_array($ret, $orderby_options) ? $ret : $orderby_options[0];
|
1094 |
}
|
1095 |
|
1096 |
/**
|
@@ -1112,12 +1132,16 @@ class DG_Admin {
|
|
1112 |
|
1113 |
/**
|
1114 |
* Render a Meta Box.
|
|
|
1115 |
*/
|
1116 |
public static function renderMetaBox( $post ) {
|
1117 |
-
global $dg_options;
|
1118 |
wp_nonce_field( DG_OPTION_NAME . '_meta_box', DG_OPTION_NAME . '_meta_box_nonce' );
|
1119 |
-
$ID
|
1120 |
-
$
|
|
|
|
|
|
|
|
|
1121 |
|
1122 |
echo '<table id="ThumbsTable" class="wp-list-table widefat fixed media" cellpadding="0" cellspacing="0">' .
|
1123 |
'<tbody><tr data-entry="' . $ID . '"><td class="column-icon media-icon"><img src="' .
|
@@ -1131,7 +1155,7 @@ class DG_Admin {
|
|
1131 |
'</span>' .
|
1132 |
'</span>' .
|
1133 |
'</td></tr></tbody></table>' .
|
1134 |
-
(
|
1135 |
}
|
1136 |
|
1137 |
/**
|
@@ -1145,7 +1169,6 @@ class DG_Admin {
|
|
1145 |
return;
|
1146 |
}
|
1147 |
|
1148 |
-
global $dg_options;
|
1149 |
$responseArr = array( 'result' => false );
|
1150 |
if ( isset( $_POST[ DG_OPTION_NAME ]['entry'] ) ) {
|
1151 |
$ID = intval( $_POST[ DG_OPTION_NAME ]['entry'] );
|
@@ -1153,15 +1176,12 @@ class DG_Admin {
|
|
1153 |
$ID = - 1;
|
1154 |
}
|
1155 |
|
1156 |
-
|
1157 |
-
|
1158 |
$uploaded_filename = self::validateUploadedFile();
|
1159 |
-
if ( $uploaded_filename && DG_Thumber::setThumbnail( $ID, $uploaded_filename ) ) {
|
1160 |
-
if ( ! is_null($old_path) && $dg_options['thumber']['thumbs'][ $ID ]['thumb_path'] !== $old_path ) {
|
1161 |
-
@unlink( $old_path );
|
1162 |
-
}
|
1163 |
$responseArr['result'] = true;
|
1164 |
-
$responseArr['url'] = $
|
1165 |
}
|
1166 |
}
|
1167 |
|
@@ -1229,7 +1249,7 @@ class DG_Admin {
|
|
1229 |
<?php echo $thead; ?>
|
1230 |
</tfoot>
|
1231 |
<tbody><?php
|
1232 |
-
for ( $i = count( $log_list ); $i > 0; $i
|
1233 |
$log_entry = $log_list[ $i - 1 ];
|
1234 |
$date = DocumentGallery::localDateTimeFromTimestamp( $log_entry[0] );
|
1235 |
|
@@ -1340,26 +1360,38 @@ class DG_Admin {
|
|
1340 |
}
|
1341 |
|
1342 |
/**
|
1343 |
-
* @param $t1
|
1344 |
-
* @param $t2
|
1345 |
*
|
1346 |
-
* @return int The result of comparing the two
|
1347 |
*/
|
1348 |
public static function cmpThumb($t1, $t2) {
|
1349 |
$ret = 0;
|
1350 |
switch (self::$URL_params['orderby']) {
|
1351 |
case 'date':
|
1352 |
-
$ret = $t1
|
1353 |
break;
|
1354 |
|
1355 |
case 'title':
|
1356 |
-
$ret = strcmp(
|
1357 |
break;
|
1358 |
}
|
1359 |
|
1360 |
return 'asc' === self::$URL_params['order'] ? $ret : -$ret;
|
1361 |
}
|
1362 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1363 |
/**
|
1364 |
* Wraps the PHP exit language construct.
|
1365 |
*/
|
72 |
|
73 |
/**
|
74 |
* Adds settings link to main plugin view.
|
75 |
+
* @param $links array The links being prepended.
|
76 |
+
* @return array The given array with settings link prepended.
|
77 |
*/
|
78 |
public static function addSettingsLink( $links ) {
|
79 |
$settings = '<a href="options-general.php?page=' . DG_OPTION_NAME . '">' .
|
85 |
|
86 |
/**
|
87 |
* Adds donate link to main plugin view.
|
88 |
+
* @param $links array The links.
|
89 |
+
* @param $file string The file.
|
90 |
+
* @return array The given array with donate link appended.
|
91 |
*/
|
92 |
public static function addDonateLink( $links, $file ) {
|
93 |
if ( $file === DG_BASENAME ) {
|
115 |
|
116 |
/**
|
117 |
* Enqueues styles and scripts for the admin settings page.
|
118 |
+
* @param $hook string The hook.
|
119 |
*/
|
120 |
public static function enqueueScriptsAndStyles( $hook ) {
|
121 |
if ( in_array( $hook, array( DG_Admin::$hook, 'post.php', 'post-new.php' ), true ) ) {
|
122 |
// Settings Page
|
123 |
DG_Util::enqueueAsset( 'document-gallery-admin', 'assets/css/admin.css' );
|
124 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
125 |
DG_Util::enqueueAsset( 'document-gallery-admin', 'assets/js/admin.js', array( 'jquery' ) );
|
126 |
wp_localize_script( 'document-gallery-admin', 'dg_admin_vars', array( 'upload_limit' => wp_max_upload_size() ) );
|
127 |
if ( $hook !== self::$hook ) { //if $hook is 'post.php' or 'post-new.php'
|
129 |
|
130 |
// Media Manager
|
131 |
global $dg_options;
|
132 |
+
DG_Util::enqueueAsset( 'dg-media-manager', 'assets/js/media_manager.js', array( 'media-views' ) );
|
133 |
+
wp_localize_script( 'dg-media-manager', 'DGl10n', array(
|
134 |
+
'dgMenuTitle' => __( 'Create Document Gallery', 'document-gallery' ),
|
135 |
+
'dgButton' => __( 'Create a new Document Gallery', 'document-gallery' ),
|
136 |
+
'canceldgTitle' => '← ' . __( 'Cancel Document Gallery', 'document-gallery' ),
|
137 |
+
'updatedg' => __( 'Update Document Gallery', 'document-gallery' ),
|
138 |
+
'insertdg' => __( 'Insert Document Gallery', 'document-gallery' ),
|
139 |
+
'addTodg' => __( 'Add to Document Gallery', 'document-gallery' ),
|
140 |
+
'addTodgTitle' => __( 'Add to Document Gallery', 'document-gallery' ),
|
141 |
+
'editdgTitle' => __( 'Edit Document Gallery', 'document-gallery' ),
|
142 |
+
'unfitSCalert' => __( 'This DG shortcode is an advanced one. '.
|
143 |
+
'Sorry there is no way to use standard edit dialog for it. '.
|
144 |
+
'You should switch to text mode to edit shortcode itself.', 'document-gallery' ),
|
145 |
) );
|
146 |
+
wp_localize_script( 'dg-media-manager', 'dgDefaults', $dg_options['gallery'] );
|
147 |
+
|
148 |
+
// TinyMCE visual editor
|
149 |
+
add_filter( 'mce_external_plugins', array( __CLASS__, 'mce_external_plugins' ) );
|
150 |
+
add_filter( 'mce_css', array( __CLASS__, 'dg_plugin_mce_css' ) );
|
151 |
}
|
152 |
}
|
153 |
}
|
154 |
|
155 |
+
/**
|
156 |
+
* Adds assets/js/gallery.js as registered TinyMCE plugin
|
157 |
+
*
|
158 |
+
* @param array $plugin_array Previously registered plugins
|
159 |
+
*
|
160 |
+
* @return array Total set of plugins
|
161 |
+
*/
|
162 |
+
public static function mce_external_plugins( $plugin_array ) {
|
163 |
+
$plugin_array['dg'] = DG_Util::getAssetPath( 'assets/js/gallery.js' );
|
164 |
+
|
165 |
+
return $plugin_array;
|
166 |
+
}
|
167 |
+
|
168 |
+
/**
|
169 |
+
* Adds assets/css/style.css as registered TinyMCE CSS
|
170 |
+
*
|
171 |
+
* @param array $mce_css Previously registered CSS
|
172 |
+
*
|
173 |
+
* @return array Total set of CSS
|
174 |
+
*/
|
175 |
+
public static function dg_plugin_mce_css( $mce_css ) {
|
176 |
+
if ( ! empty( $mce_css ) ) {
|
177 |
+
$mce_css .= ',';
|
178 |
+
}
|
179 |
+
$mce_css .= str_replace( ',', '%2C', DG_Util::getAssetPath( 'assets/css/style.css' ) );
|
180 |
+
|
181 |
+
return $mce_css;
|
182 |
+
}
|
183 |
+
|
184 |
/**
|
185 |
* Load Document Gallery Custom templates.
|
186 |
*/
|
212 |
global $dg_options;
|
213 |
|
214 |
include_once DG_PATH . 'inc/class-gallery.php';
|
215 |
+
include_once DG_PATH . 'inc/class-gallery-sanitization.php';
|
216 |
include_once DG_PATH . 'inc/class-thumber.php';
|
217 |
|
218 |
$defaults = $dg_options['gallery'];
|
239 |
'name' => 'gallery_defaults][attachment_pg',
|
240 |
'value' => esc_attr( $defaults['attachment_pg'] ),
|
241 |
'option_name' => DG_OPTION_NAME,
|
242 |
+
'description' => __( 'Link to attachment page rather than to file.', 'document-gallery' )
|
243 |
) );
|
244 |
|
245 |
add_settings_field(
|
264 |
'name' => 'gallery_defaults][descriptions',
|
265 |
'value' => esc_attr( $defaults['descriptions'] ),
|
266 |
'option_name' => DG_OPTION_NAME,
|
267 |
+
'description' => __( 'Include document descriptions.', 'document-gallery' )
|
268 |
) );
|
269 |
|
270 |
add_settings_field(
|
276 |
'name' => 'gallery_defaults][fancy',
|
277 |
'value' => esc_attr( $defaults['fancy'] ),
|
278 |
'option_name' => DG_OPTION_NAME,
|
279 |
+
'description' => __( 'Use auto-generated document thumbnails.', 'document-gallery' )
|
280 |
) );
|
281 |
|
282 |
add_settings_field(
|
287 |
'label_for' => 'label_gallery_defaults_order',
|
288 |
'name' => 'gallery_defaults][order',
|
289 |
'value' => esc_attr( $defaults['order'] ),
|
290 |
+
'options' => DG_GallerySanitization::getOrderOptions(),
|
291 |
'option_name' => DG_OPTION_NAME,
|
292 |
+
'description' => __( 'Ascending or descending sorting of documents.', 'document-gallery' )
|
293 |
) );
|
294 |
|
295 |
add_settings_field(
|
300 |
'label_for' => 'label_gallery_defaults_orderby',
|
301 |
'name' => 'gallery_defaults][orderby',
|
302 |
'value' => esc_attr( $defaults['orderby'] ),
|
303 |
+
'options' => DG_GallerySanitization::getOrderbyOptions(),
|
304 |
'option_name' => DG_OPTION_NAME,
|
305 |
+
'description' => __( 'Which field to order documents by.', 'document-gallery' )
|
306 |
) );
|
307 |
|
308 |
add_settings_field(
|
313 |
'label_for' => 'label_gallery_defaults_relation',
|
314 |
'name' => 'gallery_defaults][relation',
|
315 |
'value' => esc_attr( $defaults['relation'] ),
|
316 |
+
'options' => DG_GallerySanitization::getRelationOptions(),
|
317 |
'option_name' => DG_OPTION_NAME,
|
318 |
+
'description' => __( 'Whether matched documents must have all taxa_names (AND) or at least one (OR).', 'document-gallery' )
|
319 |
) );
|
320 |
|
321 |
add_settings_field(
|
353 |
'name' => 'gallery_defaults][new_window',
|
354 |
'value' => esc_attr( $defaults['new_window'] ),
|
355 |
'option_name' => DG_OPTION_NAME,
|
356 |
+
'description' => __( 'Open thumbnail links in new window.', 'document-gallery' )
|
357 |
+
) );
|
358 |
+
|
359 |
+
add_settings_field(
|
360 |
+
'gallery_defaults_paginate', 'paginate',
|
361 |
+
array( __CLASS__, 'renderCheckboxField' ),
|
362 |
+
DG_OPTION_NAME, 'gallery_defaults',
|
363 |
+
array(
|
364 |
+
'label_for' => 'label_gallery_defaults_paginate',
|
365 |
+
'name' => 'gallery_defaults][paginate',
|
366 |
+
'value' => esc_attr( $defaults['paginate'] ),
|
367 |
+
'option_name' => DG_OPTION_NAME,
|
368 |
+
'description' => __( 'When a limit exists, paginate rather than truncating gallery.', 'document-gallery' )
|
369 |
) );
|
370 |
|
371 |
add_settings_field(
|
376 |
'label_for' => 'label_gallery_defaults_post_status',
|
377 |
'name' => 'gallery_defaults][post_status',
|
378 |
'value' => esc_attr( $defaults['post_status'] ),
|
379 |
+
'options' => DG_GallerySanitization::getPostStatuses(),
|
380 |
'option_name' => DG_OPTION_NAME,
|
381 |
'description' => __( 'Which post status to look for when querying documents.', 'document-gallery' )
|
382 |
) );
|
389 |
'label_for' => 'label_gallery_defaults_post_type',
|
390 |
'name' => 'gallery_defaults][post_type',
|
391 |
'value' => esc_attr( $defaults['post_type'] ),
|
392 |
+
'options' => DG_GallerySanitization::getPostTypes(),
|
393 |
'option_name' => DG_OPTION_NAME,
|
394 |
'description' => __( 'Which post type to look for when querying documents.', 'document-gallery' )
|
395 |
) );
|
550 |
global $dg_options;
|
551 |
return $dg_options;
|
552 |
} else {
|
553 |
+
if ( isset( $values['ajax'] ) ) {
|
554 |
unset( $values['ajax'] );
|
555 |
define( 'DOING_AJAX', true );
|
556 |
}
|
615 |
|
616 |
// delete thumb cache to force regeneration if max dimensions changed
|
617 |
if ( $ret['thumber']['width'] !== $dg_options['thumber']['width'] ||
|
618 |
+
$ret['thumber']['height'] !== $dg_options['thumber']['height'] ) {
|
619 |
+
DG_Thumb::purgeThumbs();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
620 |
}
|
621 |
|
622 |
// handle setting the active thumbers
|
626 |
|
627 |
// if new thumbers available, clear failed thumbnails for retry
|
628 |
if ( ! $thumbs_cleared ) {
|
629 |
+
DG_Thumb::purgeFailedThumbs();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
630 |
}
|
631 |
|
632 |
// handle modified CSS
|
658 |
// Thumbnail(s) cleanup;
|
659 |
// cleanup value is a marker
|
660 |
if ( isset( $values['cleanup'] ) && isset( $values['ids'] ) ) {
|
661 |
+
$deleted = array_values( array_intersect( array_keys( DG_Thumb::getThumbs() ), $values['ids'] ) );
|
662 |
+
DG_Thumb::purgeThumbs( $deleted );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
663 |
$responseArr['result'] = true;
|
664 |
$responseArr['deleted'] = $deleted;
|
665 |
}
|
690 |
|
691 |
// Thumbnail file manual refresh (one at a time)
|
692 |
// upload value is a marker
|
693 |
+
elseif ( isset( $values['upload'] ) && isset( $_FILES['file'] ) && array_key_exists( $ID, DG_Thumb::getThumbs() ) ) {
|
|
|
694 |
$uploaded_filename = self::validateUploadedFile();
|
695 |
+
if ( $uploaded_filename && ( $thumb = DG_Thumber::setThumbnail( $ID, $uploaded_filename ) ) ) {
|
696 |
+
$responseArr['result'] = true;
|
697 |
+
$responseArr['url'] = $thumb->getUrl();
|
698 |
+
}
|
|
|
|
|
|
|
|
|
699 |
}
|
700 |
|
701 |
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
|
918 |
self::$URL_params = array( 'page' => DG_OPTION_NAME, 'tab' => 'Thumbnail' );
|
919 |
$orderby = self::$URL_params['orderby'] = self::getOrderbyParam($orderby_options);
|
920 |
$order = self::$URL_params['order'] = self::getOrderParam($order_options);
|
921 |
+
$limit = self::$URL_params['limit'] = self::getLimitParam();
|
922 |
|
923 |
+
$thumbs = DG_Thumb::getThumbs( $options['width'] . 'x' . $options['height'] );
|
924 |
uasort( $thumbs, array( __CLASS__, 'cmpThumb' ) );
|
925 |
+
$thumbs_number = count( $thumbs );
|
926 |
$lastsheet = ceil( $thumbs_number / $limit );
|
927 |
+
$sheet = isset( $_REQUEST['sheet'] ) ? absint( $_REQUEST['sheet'] ) : 1;
|
928 |
if ( $sheet === 0 || $sheet > $lastsheet ) {
|
929 |
$sheet = 1;
|
930 |
}
|
948 |
foreach ( $posts as $post ) {
|
949 |
$path_parts = pathinfo( $post->guid );
|
950 |
|
951 |
+
$thumb = $thumbs[$post->ID];
|
952 |
+
$thumbs[$post->ID] = array();
|
953 |
+
$t = &$thumbs[$post->ID];
|
954 |
+
$t['timestamp'] = $thumb->getTimestamp();
|
955 |
+
$t['title'] = self::getTitle( $post );
|
956 |
+
$t['ext'] = isset( $path_parts['extension'] ) ? $path_parts['extension'] : '';
|
957 |
$t['description'] = $post->post_content;
|
958 |
+
$t['icon'] = $thumb->isSuccess() ? $thumb->getUrl() : DG_Thumber::getDefaultThumbnail( $post->ID );
|
|
|
|
|
959 |
}
|
960 |
unset( $posts );
|
961 |
|
984 |
|
985 |
$pagination = '<div class="alignleft bulkactions"><button class="button action deleteSelected">' . __( 'Delete Selected', 'document-gallery' ) . '</button></div><div class="tablenav-pages">' .
|
986 |
'<span class="displaying-num">' .
|
987 |
+
$thumbs_number . ' ' . _n( 'item', 'items', $thumbs_number, 'document-gallery' ) .
|
988 |
'</span>' . ( $lastsheet > 1 ?
|
989 |
'<span class="pagination-links">' .
|
990 |
'<a class="first-page' . ( $sheet == 1 ? ' disabled' : '' ) . '" title="' . __( 'Go to the first page', 'document-gallery' ) . '"' . ( $sheet == 1 ? '' : ' href="?' . http_build_query( self::$URL_params ) . '"' ) . '>«</a>' .
|
1080 |
<?php }
|
1081 |
|
1082 |
/**
|
|
|
|
|
1083 |
* @return int The limit, which may or may not be a member of $limit_options.
|
1084 |
*/
|
1085 |
+
private static function getLimitParam() {
|
1086 |
+
global $dg_options;
|
1087 |
+
$limit = isset( $_REQUEST['limit'] ) ? DG_Util::posint( $_REQUEST['limit'] ) : $dg_options['meta']['items_per_page'];
|
1088 |
+
if ( $limit !== $dg_options['meta']['items_per_page'] ) {
|
1089 |
+
$dg_options['meta']['items_per_page'] = $limit;
|
1090 |
+
DocumentGallery::setOptions( $dg_options );
|
1091 |
+
}
|
1092 |
+
|
1093 |
+
return $limit;
|
1094 |
}
|
1095 |
|
1096 |
/**
|
1099 |
* @return string The order value.
|
1100 |
*/
|
1101 |
private static function getOrderParam($order_options) {
|
1102 |
+
$ret = isset( $_REQUEST['order'] ) ? strtolower( $_REQUEST['order'] ) : '';
|
1103 |
return in_array($ret, $order_options) ? $ret : $order_options[0];
|
1104 |
}
|
1105 |
|
1109 |
* @return string The orderby value.
|
1110 |
*/
|
1111 |
private static function getOrderbyParam($orderby_options) {
|
1112 |
+
$ret = isset( $_REQUEST['orderby'] ) ? strtolower( $_REQUEST['orderby'] ) : '';
|
1113 |
+
return in_array( $ret, $orderby_options ) ? $ret : $orderby_options[0];
|
1114 |
}
|
1115 |
|
1116 |
/**
|
1132 |
|
1133 |
/**
|
1134 |
* Render a Meta Box.
|
1135 |
+
* @param $post WP_Post The post.
|
1136 |
*/
|
1137 |
public static function renderMetaBox( $post ) {
|
|
|
1138 |
wp_nonce_field( DG_OPTION_NAME . '_meta_box', DG_OPTION_NAME . '_meta_box_nonce' );
|
1139 |
+
$ID = $post->ID;
|
1140 |
+
$options = DG_Thumber::getOptions();
|
1141 |
+
$thumb = DG_Thumb::getThumb( $ID, $options['width'] . 'x' . $options['height'] );
|
1142 |
+
$icon = ! is_null( $thumb ) && $thumb->isSuccess()
|
1143 |
+
? $thumb->getUrl()
|
1144 |
+
: DG_Thumber::getDefaultThumbnail( $ID );
|
1145 |
|
1146 |
echo '<table id="ThumbsTable" class="wp-list-table widefat fixed media" cellpadding="0" cellspacing="0">' .
|
1147 |
'<tbody><tr data-entry="' . $ID . '"><td class="column-icon media-icon"><img src="' .
|
1155 |
'</span>' .
|
1156 |
'</span>' .
|
1157 |
'</td></tr></tbody></table>' .
|
1158 |
+
( is_null( $thumb ) ? '<span class="dashicons dashicons-info"></span><span class="">Please note this attachment hasn't been used in any Document Gallery instance and so there is no autogenerated thumbnail, in the meantime default one is used instead.</span>' : '' ) . PHP_EOL;
|
1159 |
}
|
1160 |
|
1161 |
/**
|
1169 |
return;
|
1170 |
}
|
1171 |
|
|
|
1172 |
$responseArr = array( 'result' => false );
|
1173 |
if ( isset( $_POST[ DG_OPTION_NAME ]['entry'] ) ) {
|
1174 |
$ID = intval( $_POST[ DG_OPTION_NAME ]['entry'] );
|
1176 |
$ID = - 1;
|
1177 |
}
|
1178 |
|
1179 |
+
$thumbs = DG_Thumb::getThumbs();
|
1180 |
+
if ( isset( $_POST[DG_OPTION_NAME]['upload'] ) && isset( $_FILES['file'] ) && isset( $thumbs[$ID] ) ) {
|
1181 |
$uploaded_filename = self::validateUploadedFile();
|
1182 |
+
if ( $uploaded_filename && ( $thumb = DG_Thumber::setThumbnail( $ID, $uploaded_filename ) ) ) {
|
|
|
|
|
|
|
1183 |
$responseArr['result'] = true;
|
1184 |
+
$responseArr['url'] = $thumb->getUrl();
|
1185 |
}
|
1186 |
}
|
1187 |
|
1249 |
<?php echo $thead; ?>
|
1250 |
</tfoot>
|
1251 |
<tbody><?php
|
1252 |
+
for ( $i = count( $log_list ); $i > 0; $i-- ) {
|
1253 |
$log_entry = $log_list[ $i - 1 ];
|
1254 |
$date = DocumentGallery::localDateTimeFromTimestamp( $log_entry[0] );
|
1255 |
|
1360 |
}
|
1361 |
|
1362 |
/**
|
1363 |
+
* @param $t1 DG_Thumb Thumbnail #1.
|
1364 |
+
* @param $t2 DG_Thumb Thumbnail #2
|
1365 |
*
|
1366 |
+
* @return int The result of comparing the two thumbs using arguments in $URL_params.
|
1367 |
*/
|
1368 |
public static function cmpThumb($t1, $t2) {
|
1369 |
$ret = 0;
|
1370 |
switch (self::$URL_params['orderby']) {
|
1371 |
case 'date':
|
1372 |
+
$ret = $t1->getTimestamp() - $t2->getTimestamp();
|
1373 |
break;
|
1374 |
|
1375 |
case 'title':
|
1376 |
+
$ret = strcmp( self::getTitle( $t1->getPostId() ), self::getTitle( $t2->getPostId() ) );
|
1377 |
break;
|
1378 |
}
|
1379 |
|
1380 |
return 'asc' === self::$URL_params['order'] ? $ret : -$ret;
|
1381 |
}
|
1382 |
|
1383 |
+
/**
|
1384 |
+
* @param $post int|WP_Post The post to get title of.
|
1385 |
+
* @return string The title.
|
1386 |
+
*/
|
1387 |
+
private static function getTitle( $post ) {
|
1388 |
+
if ( is_numeric( $post ) ) {
|
1389 |
+
$post = get_post( $post );
|
1390 |
+
}
|
1391 |
+
|
1392 |
+
return ! empty( $post->post_title ) ? $post->post_title : pathinfo( $post->guid, PATHINFO_FILENAME );
|
1393 |
+
}
|
1394 |
+
|
1395 |
/**
|
1396 |
* Wraps the PHP exit language construct.
|
1397 |
*/
|
admin/class-ajax-handler.php
ADDED
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
defined( 'WPINC' ) OR exit;
|
3 |
+
|
4 |
+
// register for all handled actions
|
5 |
+
add_action( 'wp_ajax_dg_generate_icons', array( 'DG_AjaxHandler', 'generateIcons' ) );
|
6 |
+
add_action( 'wp_ajax_nopriv_dg_generate_icons', array( 'DG_AjaxHandler', 'generateIcons' ) );
|
7 |
+
|
8 |
+
add_action( 'wp_ajax_dg_generate_gallery', array( 'DG_AjaxHandler', 'generateGallery' ) );
|
9 |
+
add_action( 'wp_ajax_nopriv_dg_generate_gallery', array( 'DG_AjaxHandler', 'generateGallery' ) );
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Handler to isolate AJAX request handling.
|
13 |
+
*
|
14 |
+
* @author drossiter
|
15 |
+
*/
|
16 |
+
class DG_AjaxHandler {
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Accepts AJAX request containing list of IDs to be generated and returned.
|
20 |
+
* Returns associative array mapping ID to thumbnail URL for all icons that were generated,
|
21 |
+
* skipping any that could not be processed.
|
22 |
+
*/
|
23 |
+
public static function generateIcons() {
|
24 |
+
$ret = array();
|
25 |
+
|
26 |
+
if ( isset( $_REQUEST['ids'] ) ) {
|
27 |
+
foreach ( $_REQUEST['ids'] as $id ) {
|
28 |
+
// only return URL if different from default -- default image is already displayed on the client side
|
29 |
+
$url = DG_Thumber::getThumbnail( $id, 1, true, $is_default );
|
30 |
+
if ( ! $is_default ) {
|
31 |
+
$ret[$id] = $url;
|
32 |
+
}
|
33 |
+
}
|
34 |
+
}
|
35 |
+
|
36 |
+
wp_send_json($ret);
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Accepts AJAX request containing an array matching any allowable params for the [dg] shortcode.
|
41 |
+
* Returns the resultant gallery HTML.
|
42 |
+
*/
|
43 |
+
public static function generateGallery() {
|
44 |
+
if ( isset( $_REQUEST['atts'] ) ) {
|
45 |
+
@header( 'Content-Type: text/html; charset=' . get_option( 'blog_charset' ) );
|
46 |
+
echo DocumentGallery::doShortcode( $_REQUEST['atts'] );
|
47 |
+
}
|
48 |
+
|
49 |
+
wp_die();
|
50 |
+
}
|
51 |
+
}
|
admin/media-manager-template.php
CHANGED
@@ -1,19 +1,23 @@
|
|
1 |
<?php /* Custom templates into the DOM */
|
2 |
include_once DG_PATH . 'inc/class-gallery.php';
|
3 |
?>
|
4 |
-
<script type="text/html" id="tmpl-
|
5 |
<h3><?php _e('Document Gallery Settings', 'document-gallery'); ?></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" <#
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
|
|
|
|
|
|
|
|
17 |
</select></td>
|
18 |
</tr></table>
|
19 |
</label>
|
@@ -23,16 +27,16 @@
|
|
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' ==
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
<?php for ( $i = 1; $i <= 9; $i++ ) : ?>
|
31 |
<option value="<?php echo esc_attr( $i ); ?>" <#
|
32 |
-
if ( <?php echo $i ?> ==
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
<?php endfor; ?>
|
37 |
</select></td>
|
38 |
</tr></table>
|
@@ -41,34 +45,46 @@
|
|
41 |
<label class="setting">
|
42 |
<table><tr>
|
43 |
<td><span><?php _e('Open thumbnail links in new window', 'document-gallery'); ?></span></td>
|
44 |
-
<td><input type="checkbox" data-setting="new_window" <#
|
|
|
|
|
|
|
|
|
45 |
</tr></table>
|
46 |
</label>
|
47 |
|
48 |
<label class="setting">
|
49 |
<table><tr>
|
50 |
<td><span><?php _e('Include document descriptions', 'document-gallery'); ?></span></td>
|
51 |
-
<td><input type="checkbox" data-setting="descriptions" <#
|
|
|
|
|
|
|
|
|
52 |
</tr></table>
|
53 |
</label>
|
54 |
|
55 |
<label class="setting">
|
56 |
<table><tr>
|
57 |
<td><span><?php _e('Use auto-generated document thumbnails', 'document-gallery'); ?></span></td>
|
58 |
-
<td><input type="checkbox" data-setting="fancy" <#
|
|
|
|
|
|
|
|
|
59 |
</tr></table>
|
60 |
</label>
|
61 |
|
62 |
<label class="setting">
|
63 |
<table><tr>
|
64 |
<td><span><?php _e('Which field to order documents by', 'document-gallery'); ?></span></td>
|
65 |
-
<td><select
|
66 |
-
<?php foreach (
|
67 |
<option value="<?php echo esc_attr( $i ); ?>" <#
|
68 |
-
if ( '<?php echo $i ?>' ==
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
<?php endforeach; ?>
|
73 |
</select></td>
|
74 |
</tr></table>
|
@@ -77,15 +93,42 @@
|
|
77 |
<label class="setting">
|
78 |
<table><tr>
|
79 |
<td><span><?php _e('Ascending or descending sorting of documents', 'document-gallery'); ?></span></td>
|
80 |
-
<td><select
|
81 |
-
<?php foreach (
|
82 |
<option value="<?php echo esc_attr( $i ); ?>" <#
|
83 |
-
if ( '<?php echo $i ?>' ==
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
<?php endforeach; ?>
|
88 |
</select></td>
|
89 |
</tr></table>
|
90 |
</label>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
91 |
</script>
|
1 |
<?php /* Custom templates into the DOM */
|
2 |
include_once DG_PATH . 'inc/class-gallery.php';
|
3 |
?>
|
4 |
+
<script type="text/html" id="tmpl-dg-settings">
|
5 |
<h3><?php _e('Document Gallery Settings', 'document-gallery'); ?></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" <#
|
12 |
+
if ( !wp.media.dgDefaults.attachment_pg ) {
|
13 |
+
#>selected="selected"<#
|
14 |
+
}
|
15 |
+
#>><?php esc_attr_e('Media File'); ?></option>
|
16 |
+
<option value="true" <#
|
17 |
+
if ( wp.media.dgDefaults.attachment_pg ) {
|
18 |
+
#>selected="selected"<#
|
19 |
+
}
|
20 |
+
#>><?php esc_attr_e('Attachment Page'); ?></option>
|
21 |
</select></td>
|
22 |
</tr></table>
|
23 |
</label>
|
27 |
<td><span><?php _e('Columns'); ?></span></td>
|
28 |
<td><select class="columns" name="columns" data-setting="columns">
|
29 |
<option value="-1" <#
|
30 |
+
if ( '-1' == wp.media.dgDefaults.columns ) {
|
31 |
+
#>selected="selected"<#
|
32 |
+
}
|
33 |
+
#>>∞</option>
|
34 |
<?php for ( $i = 1; $i <= 9; $i++ ) : ?>
|
35 |
<option value="<?php echo esc_attr( $i ); ?>" <#
|
36 |
+
if ( <?php echo $i ?> == wp.media.dgDefaults.columns ) {
|
37 |
+
#>selected="selected"<#
|
38 |
+
}
|
39 |
+
#>><?php echo esc_html( $i ); ?></option>
|
40 |
<?php endfor; ?>
|
41 |
</select></td>
|
42 |
</tr></table>
|
45 |
<label class="setting">
|
46 |
<table><tr>
|
47 |
<td><span><?php _e('Open thumbnail links in new window', 'document-gallery'); ?></span></td>
|
48 |
+
<td><input type="checkbox" data-setting="new_window" <#
|
49 |
+
if ( wp.media.dgDefaults.new_window ) {
|
50 |
+
#>checked="checked"<#
|
51 |
+
} #> />
|
52 |
+
</td>
|
53 |
</tr></table>
|
54 |
</label>
|
55 |
|
56 |
<label class="setting">
|
57 |
<table><tr>
|
58 |
<td><span><?php _e('Include document descriptions', 'document-gallery'); ?></span></td>
|
59 |
+
<td><input type="checkbox" data-setting="descriptions" <#
|
60 |
+
if ( wp.media.dgDefaults.descriptions ) {
|
61 |
+
#>checked="checked"<#
|
62 |
+
} #> />
|
63 |
+
</td>
|
64 |
</tr></table>
|
65 |
</label>
|
66 |
|
67 |
<label class="setting">
|
68 |
<table><tr>
|
69 |
<td><span><?php _e('Use auto-generated document thumbnails', 'document-gallery'); ?></span></td>
|
70 |
+
<td><input type="checkbox" data-setting="fancy" <#
|
71 |
+
if ( wp.media.dgDefaults.fancy ) {
|
72 |
+
#>checked="checked"<#
|
73 |
+
} #> />
|
74 |
+
</td>
|
75 |
</tr></table>
|
76 |
</label>
|
77 |
|
78 |
<label class="setting">
|
79 |
<table><tr>
|
80 |
<td><span><?php _e('Which field to order documents by', 'document-gallery'); ?></span></td>
|
81 |
+
<td><select data-setting="dgorderby">
|
82 |
+
<?php foreach ( DG_GallerySanitization::getOrderbyOptions() as $i ) : ?>
|
83 |
<option value="<?php echo esc_attr( $i ); ?>" <#
|
84 |
+
if ( '<?php echo $i ?>' == wp.media.dgDefaults.dgorderby ) {
|
85 |
+
#>selected="selected"<#
|
86 |
+
}
|
87 |
+
#>><?php echo esc_html( $i ); ?></option>
|
88 |
<?php endforeach; ?>
|
89 |
</select></td>
|
90 |
</tr></table>
|
93 |
<label class="setting">
|
94 |
<table><tr>
|
95 |
<td><span><?php _e('Ascending or descending sorting of documents', 'document-gallery'); ?></span></td>
|
96 |
+
<td><select data-setting="dgorder">
|
97 |
+
<?php foreach ( DG_GallerySanitization::getOrderOptions() as $i ) : ?>
|
98 |
<option value="<?php echo esc_attr( $i ); ?>" <#
|
99 |
+
if ( '<?php echo $i ?>' == wp.media.dgDefaults.dgorder ) {
|
100 |
+
#>selected="selected"<#
|
101 |
+
}
|
102 |
+
#>><?php echo esc_html( $i ); ?></option>
|
103 |
<?php endforeach; ?>
|
104 |
</select></td>
|
105 |
</tr></table>
|
106 |
</label>
|
107 |
+
|
108 |
+
<label class="setting">
|
109 |
+
<table><tr>
|
110 |
+
<td><span><?php _e('Paginate', 'document-gallery'); ?></span></td>
|
111 |
+
<td><select data-setting="paginate">
|
112 |
+
<option value="false" <#
|
113 |
+
if ( !wp.media.dgDefaults.paginate ) {
|
114 |
+
#>selected="selected"<#
|
115 |
+
}
|
116 |
+
#>><?php _e('No', 'document-gallery'); ?></option>
|
117 |
+
<option value="true" <#
|
118 |
+
if ( wp.media.dgDefaults.paginate ) {
|
119 |
+
#>selected="selected"<#
|
120 |
+
}
|
121 |
+
#>><?php _e('Yes', 'document-gallery'); ?></option>
|
122 |
+
</select></td>
|
123 |
+
</tr></table>
|
124 |
+
</label>
|
125 |
+
|
126 |
+
<label class="setting">
|
127 |
+
<table><tr>
|
128 |
+
<td><span><?php _e('Limit', 'document-gallery'); ?></span></td>
|
129 |
+
<td><input data-setting="limit" type="number" min="-1" step="1" value="{{ wp.media.dgDefaults.limit }}" /></td>
|
130 |
+
</tr></table>
|
131 |
+
</label>
|
132 |
+
</script>
|
133 |
+
<script type="text/html" id="tmpl-editor-dg">
|
134 |
</script>
|
assets/css/admin.css
CHANGED
@@ -627,26 +627,26 @@ td.column-title input {
|
|
627 |
-webkit-border-radius: 5px;
|
628 |
}
|
629 |
|
630 |
-
.
|
631 |
margin: 2px 0;
|
632 |
}
|
633 |
|
634 |
-
.
|
635 |
width: 100%;
|
636 |
padding-right: 8px;
|
637 |
}
|
638 |
|
639 |
-
.
|
640 |
text-align: right !important;
|
641 |
float: none !important;
|
642 |
margin: auto 0 !important;
|
643 |
}
|
644 |
|
645 |
-
.
|
646 |
max-width: none !important;
|
647 |
}
|
648 |
|
649 |
-
.
|
650 |
text-align: left !important;
|
651 |
float: none !important;
|
652 |
}
|
627 |
-webkit-border-radius: 5px;
|
628 |
}
|
629 |
|
630 |
+
.dg-settings label.setting {
|
631 |
margin: 2px 0;
|
632 |
}
|
633 |
|
634 |
+
.dg-settings label.setting table {
|
635 |
width: 100%;
|
636 |
padding-right: 8px;
|
637 |
}
|
638 |
|
639 |
+
.dg-settings label.setting table tr td:last-of-type, .dg-settings label.setting table tr td:last-of-type * {
|
640 |
text-align: right !important;
|
641 |
float: none !important;
|
642 |
margin: auto 0 !important;
|
643 |
}
|
644 |
|
645 |
+
.dg-settings label.setting table tr td:last-of-type select {
|
646 |
max-width: none !important;
|
647 |
}
|
648 |
|
649 |
+
.dg-settings label.setting table tr td span {
|
650 |
text-align: left !important;
|
651 |
float: none !important;
|
652 |
}
|
assets/css/admin.min.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
@media screen and (max-width:782px){.column-title{width:150px}.column-date{display:table-cell !important;width:auto !important}.nav-tab-wrapper{padding-left:5px !important;padding-right:5px !important}.top .tablenav-pages{display:none}.bottom .tablenav-pages{width:auto !important;margin-top:0 !important}.bottom .displaying-num{position:inherit !important}}@media screen and (max-width:979px){.column-thumbupload{display:none}.thumbs-list-wrapper{margin-top:0 !important}}div.thumbs-list-wrapper,div.log-list-wrapper{text-align:center;margin-top:1.5em}div.thumbs-list-wrapper>div,div.log-list-wrapper>div{margin:0 auto;display:inline-block}#ThumbsTable,#LogTable{border:0;box-shadow:none;-webkit-box-shadow:none;-moz-box-shadow:none;border-radius:10px;-webkit-border-radius:10px;-moz-border-radius:10px;background:#b9c9fe;color:#039;width:100%;margin:10px auto}#ThumbsTable tbody,#LogTable tbody{background:#e8edff;color:#669}#ThumbsTable>tbody>tr:hover,#LogTable>tbody>tr:hover{background:#d0dafd}#ThumbsTable>tbody>tr:not(:last-child) td,#LogTable>tbody>tr:not(:last-child) td{border-bottom:1px solid #b9c9fe}#ThumbsTable td,#ThumbsTable th,#LogTable td,#LogTable th{text-align:center;vertical-align:middle;margin:0;padding:4px}#LogTable td{text-align:left}td.title.column-title,.column-thumbupload{text-align:left !important}td.column-icon.media-icon{height:70px}td.media-icon img{width:auto;height:auto;max-width:80px;max-height:60px;border:0}#ThumbsTable img{display:block;margin:5px auto}#LogTable td>pre,.spoiler-body>pre,.expander pre,.collapser pre{margin:0;display:inline-block;white-space:pre-line}tr.selected{background:#b6adce}tr.selected:hover{background:#d8d3e5 !important}.check-column,.column-icon{white-space:nowrap;width:80px}.column-thumbupload{white-space:nowrap;width:35%}#document_gallery_gen_box .column-thumbupload{width:auto;padding-left:7em}.nav-tab:before,.deleteSelected:before,.clearLog:before,.expandAll:before,.collapseAll:before,.logLabel.date:before,.collapser:after,.expander:after{display:inline-block;-webkit-font-smoothing:antialiased;font:normal 20px/1 'dashicons';vertical-align:text-bottom;padding-right:5px}.General-tab:before{content:'\f108'}.Thumbnail-tab:before{content:'\f233'}.Logging-tab:before{content:'\f163'}.Advanced-tab:before{content:'\f332'}.deleteSelected:before,.clearLog:before{content:'\f182'}.expandAll:before{content:'\f211'}.collapseAll:before{content:'\f506'}.expandAll,.collapseAll{display:none}#ThumbsTable .title a:after,#LogTable>tbody a:after{content:'\f504';display:inline-block;-webkit-font-smoothing:antialiased;font-family:'dashicons';font-size:inherit;font-style:normal;font-variant:normal;font-weight:normal;line-height:1;vertical-align:inherit;padding-left:5px}#LogTable>tbody a{-webkit-transition:none;transition:none;text-decoration:none;outline:0}#LogTable>tbody pre strong{font-weight:bolder}#LogTable>tbody a:active,#LogTable>tbody a:hover{color:#2ea2cc}.levelSelector{float:right}.logLabel{padding:0 10px;color:#fff !important;text-decoration:none;font-weight:bolder;border:none !important;float:left;margin-left:1px;margin-top:1px;-webkit-border-radius:100px;-moz-border-radius:100px;border-radius:100px;cursor:context-menu}.logLabel.warning{background:#f89406}.logLabel.detail{background:#3a87ad}.logLabel.error{background:#c00}.logLabel.date{background:#999;font-weight:inherit}.logLabel.date:before{font-size:inherit;vertical-align:middle;padding-bottom:.2em;content:'\f469'}.spoiler-body{padding:1px 6px 2px;display:none;border-top:1px solid #c3cbd1;background:#f5f5f5}.column-entry{text-align:left !important}.expander pre,.collapser pre{vertical-align:middle;float:left;white-space:pre-wrap}.expander,.collapser{display:table;vertical-align:middle;width:100%;cursor:pointer}.expander>div,.collapser>div{display:table-cell;vertical-align:middle;height:100%}.dashicons.dashicons-arrow-down-alt2,.dashicons.dashicons-arrow-up-alt2{float:right;padding-right:15px}.levelSelector>*,.dashicons{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.levelSelector>input[type=checkbox]{display:none}.levelSelector>input[type=checkbox]+label{color:#6b6b6b;font-weight:bolder;margin:4px 0;overflow:auto;text-align:center;padding:3px 8px;display:table-cell;background-color:#f5f5f5;background-image:-moz-linear-gradient(top,#FFF,#e6e6e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#FFF),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#FFF,#e6e6e6);background-image:-o-linear-gradient(top,#FFF,#e6e6e6);background-image:linear-gradient(to bottom,#FFF,#e6e6e6);background-repeat:repeat-x;border:1px solid #CCC;border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);border-bottom-color:#b3b3b3;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF',endColorstr='#FFE6E6E6',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.levelSelector>input[type=checkbox]+label:first-of-type{border-top-left-radius:4px;border-bottom-left-radius:4px}.levelSelector>input[type=checkbox]+label:last-of-type{border-top-right-radius:4px;border-bottom-right-radius:4px}.levelSelector>input[type=checkbox]:checked+label{background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.levelSelector>input[type=checkbox]+label.errorLevel{color:#c00}.levelSelector>input[type=checkbox]:checked+label.errorLevel{background-color:#c00;color:#FFF}.levelSelector>input[type=checkbox]+label.warningLevel{color:#f89406}.levelSelector>input[type=checkbox]:checked+label.warningLevel{background-color:#f89406;color:#FFF}.levelSelector>input[type=checkbox]+label.detailLevel{color:#3a87ad}.levelSelector>input[type=checkbox]:checked+label.detailLevel{background-color:#3a87ad;color:#FFF}.noLog{font-size:x-large;display:block;width:100%;text-align:center;margin-top:20ex;line-height:150%}.loggingON,.loggingOFF{font-weight:bolder}.loggingON{color:green}.loggingOFF{color:red}th input{margin-left:0 !important;margin-top:1px !important}td input{margin-right:0 !important}textarea[readonly],input[readonly],select[readonly]{background-color:#dcdcdc}.nowrap{white-space:nowrap}.column-level{white-space:nowrap;width:6em}.column-date{width:16em !important}.column-thumbupload{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:default}.column-thumbupload>*{visibility:hidden}.column-thumbupload .dashicons{font-size:x-large;padding-top:2px;padding-left:16px;padding-right:10px;vertical-align:text-bottom}#ThumbsTable tr:hover .column-thumbupload>*,#document_gallery_gen_box #ThumbsTable tr .column-thumbupload>*{visibility:visible}.dragover{outline:3px dashed #83b4d8}.html5dndmarker span{padding:0 10px}.buttons-area input:first-child,.invis{display:none !important}#document_gallery_gen_box h3 span{font-weight:100}#document_gallery_gen_box h3 span i b{font-weight:500}th.column-description{text-align:left !important}.editable-description{max-height:70px;overflow-y:auto;text-align:justify}.column-description textarea{height:65px;width:100%}td.column-title,td.column-description{position:relative}td.column-title.trans,td.column-description.trans{background-color:inherit;transition:background-color 1s linear;-o-transition:background-color 1s linear;-moz-transition:background-color 1s linear;-webkit-transition:background-color 1s linear}td .dashicons-edit,td .edit-controls{display:none;position:absolute;top:5px;right:12px}td .dashicons-edit,.edit-controls .dashicons-yes,.edit-controls .dashicons-no,.edit-controls .dashicons-update{z-index:100;font-size:x-large;cursor:pointer;width:auto;height:auto}td .dashicons-edit,.edit-controls .dashicons-update{color:#0074a2}.edit-controls:hover,.edit-controls.waiting{opacity:1}.edit-controls{opacity:.1}.edit-controls .dashicons-yes{color:green}.edit-controls .dashicons-no{color:red}.edit-controls.waiting .dashicons-yes,.edit-controls.waiting .dashicons-no{display:none}.edit-controls .dashicons-update{display:none;cursor:default}.edit-controls.waiting .dashicons-update,.deleteSelected.waiting:before{display:block;-webkit-animation:spin 1s linear infinite;-moz-animation:spin 1s linear infinite;animation:spin 1s linear infinite}.deleteSelected.waiting:before{content:'\f463';width:auto;height:auto;display:inline-block;padding:0}@-moz-keyframes spin{100%{-moz-transform:rotate(360deg)}}@-webkit-keyframes spin{100%{-webkit-transform:rotate(360deg)}}@keyframes spin{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.responseSuccess{background-color:greenyellow !important}.responseFail{background-color:crimson !important}td.column-title .dashicons-edit,td.column-description .dashicons-edit{height:0;opacity:0;display:block;overflow:hidden;transition:opacity 1s ease-out;-o-transition:opacity 1s ease-out;-moz-transition:opacity 1s ease-out;-webkit-transition:opacity 1s ease-out}td.column-title:hover .dashicons-edit,td.column-description:hover .dashicons-edit{opacity:1;height:auto}td.column-title input{width:75%}.manual-download{display:block;text-align:center}.editable-description::-webkit-scrollbar,.column-description textarea::-webkit-scrollbar{width:5px;height:5px}.editable-description::-webkit-scrollbar-track-piece,.column-description textarea::-webkit-scrollbar-track-piece{background-color:#fff;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.editable-description::-webkit-scrollbar-thumb:vertical,.column-description textarea::-webkit-scrollbar-thumb:vertical{height:5px;background-color:#9b9b9b;-webkit-border-radius:5px}.document-gallery-settings label.setting{margin:2px 0}.document-gallery-settings label.setting table{width:100%;padding-right:8px}.document-gallery-settings label.setting table tr td:last-of-type,.document-gallery-settings label.setting table tr td:last-of-type *{text-align:right !important;float:none !important;margin:auto 0 !important}.document-gallery-settings label.setting table tr td:last-of-type select{max-width:none !important}.document-gallery-settings label.setting table tr td span{text-align:left !important;float:none !important}.progress{border:0;width:100%;height:18px;position:relative;background-color:#f1f1f1;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px;-webkit-box-shadow:inset 0 -1px 1px rgba(255,255,255,0.3);-moz-box-shadow:inset 0 -1px 1px rgba(255,255,255,0.3);box-shadow:inset 0 -1px 1px rgba(255,255,255,0.3)}.column-thumbupload .progress{visibility:visible !important}.progress>span{border:0;height:100%;display:block;overflow:hidden;position:relative;-webkit-transition:width .5s linear;-moz-transition:width .5s linear;-o-transition:width .5s linear;transition:width .5s linear;background-color:#7ad03a;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px;background-image:linear-gradient(90deg,#2bc253 37%,#54f054 69%);background-image:-moz-linear-gradient(90deg,#2bc253 37%,#54f054 69%);background-image:-o-linear-gradient(90deg,#2bc253 37%,#54f054 69%);background-image:-webkit-gradient(linear,left bottom,left top,color-stop(0,#2bc253),color-stop(1,#54f054));-webkit-box-shadow:inset 0 2px 9px rgba(255,255,255,0.3),inset 0 -2px 6px rgba(0,0,0,0.4);-moz-box-shadow:inset 0 2px 9px rgba(255,255,255,0.3),inset 0 -2px 6px rgba(0,0,0,0.4);box-shadow:inset 0 2px 9px rgba(255,255,255,0.3),inset 0 -2px 6px rgba(0,0,0,0.4)}.progress>span:after,.progress.animate>span>span{top:0;left:0;right:0;bottom:0;z-index:1;content:'';overflow:hidden;position:absolute;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px;background-image:-webkit-gradient(linear,0 0,100% 100%,color-stop(.25,rgba(255,255,255,.2)),color-stop(.25,transparent),color-stop(.5,transparent),color-stop(.5,rgba(255,255,255,.2)),color-stop(.75,rgba(255,255,255,.2)),color-stop(.75,transparent),to(transparent));background-image:-moz-linear-gradient(315deg,rgba(255,255,255,.2) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.2) 50%,rgba(255,255,255,.2) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(315deg,rgba(255,255,255,.2) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.2) 50%,rgba(255,255,255,.2) 75%,transparent 75%,transparent);background-image:linear-gradient(315deg,rgba(255,255,255,.2) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.2) 50%,rgba(255,255,255,.2) 75%,transparent 75%,transparent);-webkit-background-size:50px 50px;-moz-background-size:50px 50px;background-size:50px 50px;-webkit-animation:move 2s linear infinite;-moz-animation:move 2s linear infinite;-ms-animation:move 2s linear infinite;animation:move 2s linear infinite}@-webkit-keyframes move{0{background-position:0 0}100%{background-position:50px 50px}}@-moz-keyframes move{0{background-position:0 0}100%{background-position:50px 50px}}@-ms-keyframes move{0{background-position:0 0}100%{background-position:50px 50px}}@keyframes move{0{background-position:0 0}100%{background-position:50px 50px}}.progress.animate>span:after{display:none}.progress.success>span{background-color:green;width:100% !important;background-image:none !important}.progress.fail>span{background-color:red;background-image:none !important}.progress.nostripes>span>span,.progress.nostripes>span:after,.progress.success>span>span,.progress.success>span:after,.progress.fail>span>span,.progress.fail>span:after{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none;background-image:none}
|
1 |
+
@media screen and (max-width:782px){.column-title{width:150px}.column-date{display:table-cell !important;width:auto !important}.nav-tab-wrapper{padding-left:5px !important;padding-right:5px !important}.top .tablenav-pages{display:none}.bottom .tablenav-pages{width:auto !important;margin-top:0 !important}.bottom .displaying-num{position:inherit !important}}@media screen and (max-width:979px){.column-thumbupload{display:none}.thumbs-list-wrapper{margin-top:0 !important}}div.thumbs-list-wrapper,div.log-list-wrapper{text-align:center;margin-top:1.5em}div.thumbs-list-wrapper>div,div.log-list-wrapper>div{margin:0 auto;display:inline-block}#ThumbsTable,#LogTable{border:0;box-shadow:none;-webkit-box-shadow:none;-moz-box-shadow:none;border-radius:10px;-webkit-border-radius:10px;-moz-border-radius:10px;background:#b9c9fe;color:#039;width:100%;margin:10px auto}#ThumbsTable tbody,#LogTable tbody{background:#e8edff;color:#669}#ThumbsTable>tbody>tr:hover,#LogTable>tbody>tr:hover{background:#d0dafd}#ThumbsTable>tbody>tr:not(:last-child) td,#LogTable>tbody>tr:not(:last-child) td{border-bottom:1px solid #b9c9fe}#ThumbsTable td,#ThumbsTable th,#LogTable td,#LogTable th{text-align:center;vertical-align:middle;margin:0;padding:4px}#LogTable td{text-align:left}td.title.column-title,.column-thumbupload{text-align:left !important}td.column-icon.media-icon{height:70px}td.media-icon img{width:auto;height:auto;max-width:80px;max-height:60px;border:0}#ThumbsTable img{display:block;margin:5px auto}#LogTable td>pre,.spoiler-body>pre,.expander pre,.collapser pre{margin:0;display:inline-block;white-space:pre-line}tr.selected{background:#b6adce}tr.selected:hover{background:#d8d3e5 !important}.check-column,.column-icon{white-space:nowrap;width:80px}.column-thumbupload{white-space:nowrap;width:35%}#document_gallery_gen_box .column-thumbupload{width:auto;padding-left:7em}.nav-tab:before,.deleteSelected:before,.clearLog:before,.expandAll:before,.collapseAll:before,.logLabel.date:before,.collapser:after,.expander:after{display:inline-block;-webkit-font-smoothing:antialiased;font:normal 20px/1 'dashicons';vertical-align:text-bottom;padding-right:5px}.General-tab:before{content:'\f108'}.Thumbnail-tab:before{content:'\f233'}.Logging-tab:before{content:'\f163'}.Advanced-tab:before{content:'\f332'}.deleteSelected:before,.clearLog:before{content:'\f182'}.expandAll:before{content:'\f211'}.collapseAll:before{content:'\f506'}.expandAll,.collapseAll{display:none}#ThumbsTable .title a:after,#LogTable>tbody a:after{content:'\f504';display:inline-block;-webkit-font-smoothing:antialiased;font-family:'dashicons';font-size:inherit;font-style:normal;font-variant:normal;font-weight:normal;line-height:1;vertical-align:inherit;padding-left:5px}#LogTable>tbody a{-webkit-transition:none;transition:none;text-decoration:none;outline:0}#LogTable>tbody pre strong{font-weight:bolder}#LogTable>tbody a:active,#LogTable>tbody a:hover{color:#2ea2cc}.levelSelector{float:right}.logLabel{padding:0 10px;color:#fff !important;text-decoration:none;font-weight:bolder;border:none !important;float:left;margin-left:1px;margin-top:1px;-webkit-border-radius:100px;-moz-border-radius:100px;border-radius:100px;cursor:context-menu}.logLabel.warning{background:#f89406}.logLabel.detail{background:#3a87ad}.logLabel.error{background:#c00}.logLabel.date{background:#999;font-weight:inherit}.logLabel.date:before{font-size:inherit;vertical-align:middle;padding-bottom:.2em;content:'\f469'}.spoiler-body{padding:1px 6px 2px;display:none;border-top:1px solid #c3cbd1;background:#f5f5f5}.column-entry{text-align:left !important}.expander pre,.collapser pre{vertical-align:middle;float:left;white-space:pre-wrap}.expander,.collapser{display:table;vertical-align:middle;width:100%;cursor:pointer}.expander>div,.collapser>div{display:table-cell;vertical-align:middle;height:100%}.dashicons.dashicons-arrow-down-alt2,.dashicons.dashicons-arrow-up-alt2{float:right;padding-right:15px}.levelSelector>*,.dashicons{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.levelSelector>input[type=checkbox]{display:none}.levelSelector>input[type=checkbox]+label{color:#6b6b6b;font-weight:bolder;margin:4px 0;overflow:auto;text-align:center;padding:3px 8px;display:table-cell;background-color:#f5f5f5;background-image:-moz-linear-gradient(top,#FFF,#e6e6e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#FFF),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#FFF,#e6e6e6);background-image:-o-linear-gradient(top,#FFF,#e6e6e6);background-image:linear-gradient(to bottom,#FFF,#e6e6e6);background-repeat:repeat-x;border:1px solid #CCC;border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);border-bottom-color:#b3b3b3;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF',endColorstr='#FFE6E6E6',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.levelSelector>input[type=checkbox]+label:first-of-type{border-top-left-radius:4px;border-bottom-left-radius:4px}.levelSelector>input[type=checkbox]+label:last-of-type{border-top-right-radius:4px;border-bottom-right-radius:4px}.levelSelector>input[type=checkbox]:checked+label{background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.levelSelector>input[type=checkbox]+label.errorLevel{color:#c00}.levelSelector>input[type=checkbox]:checked+label.errorLevel{background-color:#c00;color:#FFF}.levelSelector>input[type=checkbox]+label.warningLevel{color:#f89406}.levelSelector>input[type=checkbox]:checked+label.warningLevel{background-color:#f89406;color:#FFF}.levelSelector>input[type=checkbox]+label.detailLevel{color:#3a87ad}.levelSelector>input[type=checkbox]:checked+label.detailLevel{background-color:#3a87ad;color:#FFF}.noLog{font-size:x-large;display:block;width:100%;text-align:center;margin-top:20ex;line-height:150%}.loggingON,.loggingOFF{font-weight:bolder}.loggingON{color:green}.loggingOFF{color:red}th input{margin-left:0 !important;margin-top:1px !important}td input{margin-right:0 !important}textarea[readonly],input[readonly],select[readonly]{background-color:#dcdcdc}.nowrap{white-space:nowrap}.column-level{white-space:nowrap;width:6em}.column-date{width:16em !important}.column-thumbupload{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:default}.column-thumbupload>*{visibility:hidden}.column-thumbupload .dashicons{font-size:x-large;padding-top:2px;padding-left:16px;padding-right:10px;vertical-align:text-bottom}#ThumbsTable tr:hover .column-thumbupload>*,#document_gallery_gen_box #ThumbsTable tr .column-thumbupload>*{visibility:visible}.dragover{outline:3px dashed #83b4d8}.html5dndmarker span{padding:0 10px}.buttons-area input:first-child,.invis{display:none !important}#document_gallery_gen_box h3 span{font-weight:100}#document_gallery_gen_box h3 span i b{font-weight:500}th.column-description{text-align:left !important}.editable-description{max-height:70px;overflow-y:auto;text-align:justify}.column-description textarea{height:65px;width:100%}td.column-title,td.column-description{position:relative}td.column-title.trans,td.column-description.trans{background-color:inherit;transition:background-color 1s linear;-o-transition:background-color 1s linear;-moz-transition:background-color 1s linear;-webkit-transition:background-color 1s linear}td .dashicons-edit,td .edit-controls{display:none;position:absolute;top:5px;right:12px}td .dashicons-edit,.edit-controls .dashicons-yes,.edit-controls .dashicons-no,.edit-controls .dashicons-update{z-index:100;font-size:x-large;cursor:pointer;width:auto;height:auto}td .dashicons-edit,.edit-controls .dashicons-update{color:#0074a2}.edit-controls:hover,.edit-controls.waiting{opacity:1}.edit-controls{opacity:.1}.edit-controls .dashicons-yes{color:green}.edit-controls .dashicons-no{color:red}.edit-controls.waiting .dashicons-yes,.edit-controls.waiting .dashicons-no{display:none}.edit-controls .dashicons-update{display:none;cursor:default}.edit-controls.waiting .dashicons-update,.deleteSelected.waiting:before{display:block;-webkit-animation:spin 1s linear infinite;-moz-animation:spin 1s linear infinite;animation:spin 1s linear infinite}.deleteSelected.waiting:before{content:'\f463';width:auto;height:auto;display:inline-block;padding:0}@-moz-keyframes spin{100%{-moz-transform:rotate(360deg)}}@-webkit-keyframes spin{100%{-webkit-transform:rotate(360deg)}}@keyframes spin{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.responseSuccess{background-color:greenyellow !important}.responseFail{background-color:crimson !important}td.column-title .dashicons-edit,td.column-description .dashicons-edit{height:0;opacity:0;display:block;overflow:hidden;transition:opacity 1s ease-out;-o-transition:opacity 1s ease-out;-moz-transition:opacity 1s ease-out;-webkit-transition:opacity 1s ease-out}td.column-title:hover .dashicons-edit,td.column-description:hover .dashicons-edit{opacity:1;height:auto}td.column-title input{width:75%}.manual-download{display:block;text-align:center}.editable-description::-webkit-scrollbar,.column-description textarea::-webkit-scrollbar{width:5px;height:5px}.editable-description::-webkit-scrollbar-track-piece,.column-description textarea::-webkit-scrollbar-track-piece{background-color:#fff;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.editable-description::-webkit-scrollbar-thumb:vertical,.column-description textarea::-webkit-scrollbar-thumb:vertical{height:5px;background-color:#9b9b9b;-webkit-border-radius:5px}.dg-settings label.setting{margin:2px 0}.dg-settings label.setting table{width:100%;padding-right:8px}.dg-settings label.setting table tr td:last-of-type,.dg-settings label.setting table tr td:last-of-type *{text-align:right !important;float:none !important;margin:auto 0 !important}.dg-settings label.setting table tr td:last-of-type select{max-width:none !important}.dg-settings label.setting table tr td span{text-align:left !important;float:none !important}.progress{border:0;width:100%;height:18px;position:relative;background-color:#f1f1f1;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px;-webkit-box-shadow:inset 0 -1px 1px rgba(255,255,255,0.3);-moz-box-shadow:inset 0 -1px 1px rgba(255,255,255,0.3);box-shadow:inset 0 -1px 1px rgba(255,255,255,0.3)}.column-thumbupload .progress{visibility:visible !important}.progress>span{border:0;height:100%;display:block;overflow:hidden;position:relative;-webkit-transition:width .5s linear;-moz-transition:width .5s linear;-o-transition:width .5s linear;transition:width .5s linear;background-color:#7ad03a;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px;background-image:linear-gradient(90deg,#2bc253 37%,#54f054 69%);background-image:-moz-linear-gradient(90deg,#2bc253 37%,#54f054 69%);background-image:-o-linear-gradient(90deg,#2bc253 37%,#54f054 69%);background-image:-webkit-gradient(linear,left bottom,left top,color-stop(0,#2bc253),color-stop(1,#54f054));-webkit-box-shadow:inset 0 2px 9px rgba(255,255,255,0.3),inset 0 -2px 6px rgba(0,0,0,0.4);-moz-box-shadow:inset 0 2px 9px rgba(255,255,255,0.3),inset 0 -2px 6px rgba(0,0,0,0.4);box-shadow:inset 0 2px 9px rgba(255,255,255,0.3),inset 0 -2px 6px rgba(0,0,0,0.4)}.progress>span:after,.progress.animate>span>span{top:0;left:0;right:0;bottom:0;z-index:1;content:'';overflow:hidden;position:absolute;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px;background-image:-webkit-gradient(linear,0 0,100% 100%,color-stop(.25,rgba(255,255,255,.2)),color-stop(.25,transparent),color-stop(.5,transparent),color-stop(.5,rgba(255,255,255,.2)),color-stop(.75,rgba(255,255,255,.2)),color-stop(.75,transparent),to(transparent));background-image:-moz-linear-gradient(315deg,rgba(255,255,255,.2) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.2) 50%,rgba(255,255,255,.2) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(315deg,rgba(255,255,255,.2) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.2) 50%,rgba(255,255,255,.2) 75%,transparent 75%,transparent);background-image:linear-gradient(315deg,rgba(255,255,255,.2) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.2) 50%,rgba(255,255,255,.2) 75%,transparent 75%,transparent);-webkit-background-size:50px 50px;-moz-background-size:50px 50px;background-size:50px 50px;-webkit-animation:move 2s linear infinite;-moz-animation:move 2s linear infinite;-ms-animation:move 2s linear infinite;animation:move 2s linear infinite}@-webkit-keyframes move{0{background-position:0 0}100%{background-position:50px 50px}}@-moz-keyframes move{0{background-position:0 0}100%{background-position:50px 50px}}@-ms-keyframes move{0{background-position:0 0}100%{background-position:50px 50px}}@keyframes move{0{background-position:0 0}100%{background-position:50px 50px}}.progress.animate>span:after{display:none}.progress.success>span{background-color:green;width:100% !important;background-image:none !important}.progress.fail>span{background-color:red;background-image:none !important}.progress.nostripes>span>span,.progress.nostripes>span:after,.progress.success>span>span,.progress.success>span:after,.progress.fail>span>span,.progress.fail>span:after{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none;background-image:none}
|
assets/css/style.css
CHANGED
@@ -1,30 +1,36 @@
|
|
1 |
-
|
2 |
text-align: center;
|
3 |
}
|
4 |
|
5 |
-
|
6 |
width: 89px;
|
7 |
max-width: 100%;
|
8 |
border: none;
|
|
|
9 |
}
|
10 |
|
11 |
-
|
12 |
font-size: 10px;
|
13 |
line-height: 12px;
|
14 |
}
|
15 |
|
16 |
-
|
17 |
margin: 5px 0 0;
|
18 |
}
|
19 |
|
|
|
|
|
|
|
|
|
|
|
20 |
/* WITHOUT DESCRIPTION */
|
21 |
-
|
22 |
display: inline-block;
|
23 |
vertical-align: top;
|
24 |
overflow: hidden;
|
25 |
}
|
26 |
|
27 |
-
|
28 |
width: 100%;
|
29 |
padding: 0;
|
30 |
text-align: left;
|
@@ -33,18 +39,18 @@ div.document-icon-wrapper {
|
|
33 |
/* END WITHOUT DESCRIPTION */
|
34 |
|
35 |
/* WITH DESCRIPTION */
|
36 |
-
|
37 |
max-width: 115px;
|
38 |
padding: 0 3px 0 0;
|
39 |
float: left;
|
40 |
}
|
41 |
|
42 |
-
|
43 |
vertical-align: middle;
|
44 |
text-align: inherit;
|
45 |
}
|
46 |
|
47 |
-
|
48 |
width: 65px;
|
49 |
max-width: 100%;
|
50 |
}
|
@@ -52,17 +58,17 @@ div.descriptions.document-icon-wrapper img {
|
|
52 |
/* clearfix */
|
53 |
/* can't depend on theme having a clearfix class,
|
54 |
so build it into dg css */
|
55 |
-
|
56 |
-
|
57 |
content: "";
|
58 |
display: table;
|
59 |
}
|
60 |
|
61 |
-
|
62 |
clear: both;
|
63 |
}
|
64 |
|
65 |
-
|
66 |
zoom: 1; /* For IE 6/7 (trigger hasLayout) */
|
67 |
}
|
68 |
|
1 |
+
.document-gallery .document-icon {
|
2 |
text-align: center;
|
3 |
}
|
4 |
|
5 |
+
.document-gallery .document-icon img {
|
6 |
width: 89px;
|
7 |
max-width: 100%;
|
8 |
border: none;
|
9 |
+
margin: 0 auto;
|
10 |
}
|
11 |
|
12 |
+
.document-gallery .document-icon a {
|
13 |
font-size: 10px;
|
14 |
line-height: 12px;
|
15 |
}
|
16 |
|
17 |
+
.document-gallery .document-icon {
|
18 |
margin: 5px 0 0;
|
19 |
}
|
20 |
|
21 |
+
.document-gallery .document-icon .title {
|
22 |
+
display: block;
|
23 |
+
text-align: center;
|
24 |
+
}
|
25 |
+
|
26 |
/* WITHOUT DESCRIPTION */
|
27 |
+
.document-gallery .document-icon {
|
28 |
display: inline-block;
|
29 |
vertical-align: top;
|
30 |
overflow: hidden;
|
31 |
}
|
32 |
|
33 |
+
.document-gallery .document-icon-row {
|
34 |
width: 100%;
|
35 |
padding: 0;
|
36 |
text-align: left;
|
39 |
/* END WITHOUT DESCRIPTION */
|
40 |
|
41 |
/* WITH DESCRIPTION */
|
42 |
+
.document-gallery .descriptions.document-icon-row .document-icon {
|
43 |
max-width: 115px;
|
44 |
padding: 0 3px 0 0;
|
45 |
float: left;
|
46 |
}
|
47 |
|
48 |
+
.document-gallery .descriptions.document-icon-row {
|
49 |
vertical-align: middle;
|
50 |
text-align: inherit;
|
51 |
}
|
52 |
|
53 |
+
.document-gallery .descriptions.document-icon-row img {
|
54 |
width: 65px;
|
55 |
max-width: 100%;
|
56 |
}
|
58 |
/* clearfix */
|
59 |
/* can't depend on theme having a clearfix class,
|
60 |
so build it into dg css */
|
61 |
+
.document-gallery .descriptions.document-icon-row:before,
|
62 |
+
.document-gallery .descriptions.document-icon-row:after {
|
63 |
content: "";
|
64 |
display: table;
|
65 |
}
|
66 |
|
67 |
+
.document-gallery .descriptions.document-icon-row:after {
|
68 |
clear: both;
|
69 |
}
|
70 |
|
71 |
+
.document-gallery .descriptions.document-icon-row {
|
72 |
zoom: 1; /* For IE 6/7 (trigger hasLayout) */
|
73 |
}
|
74 |
|
assets/css/style.min.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
|
1 |
+
.document-gallery .document-icon{text-align:center}.document-gallery .document-icon img{width:89px;max-width:100%;border:0;margin:0 auto}.document-gallery .document-icon a{font-size:10px;line-height:12px}.document-gallery .document-icon{margin:5px 0 0}.document-gallery .document-icon .title{display:block;text-align:center}.document-gallery .document-icon{display:inline-block;vertical-align:top;overflow:hidden}.document-gallery .document-icon-row{width:100%;padding:0;text-align:left}.document-gallery .descriptions.document-icon-row .document-icon{max-width:115px;padding:0 3px 0 0;float:left}.document-gallery .descriptions.document-icon-row{vertical-align:middle;text-align:inherit}.document-gallery .descriptions.document-icon-row img{width:65px;max-width:100%}.document-gallery .descriptions.document-icon-row:before,.document-gallery .descriptions.document-icon-row:after{content:"";display:table}.document-gallery .descriptions.document-icon-row:after{clear:both}.document-gallery .descriptions.document-icon-row{zoom:1}
|
assets/js/gallery.js
CHANGED
@@ -1,24 +1,98 @@
|
|
1 |
-
(function() {
|
2 |
-
// distinct list of all
|
3 |
-
var ids
|
4 |
|
5 |
-
// current index in
|
6 |
-
var i
|
7 |
|
8 |
// find all document-icons without icons generated and start processing
|
9 |
-
|
10 |
-
|
11 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
|
13 |
// if we have multiple galleries, we could have multiple elements
|
14 |
-
// needing the same icon
|
15 |
-
if (-1 ===
|
16 |
ids.push(id);
|
17 |
}
|
18 |
});
|
19 |
|
20 |
retrieveNextIcons();
|
21 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
|
23 |
/**
|
24 |
* Sends AJAX request to server requesting some of the not-yet-generated icons (if any).
|
@@ -40,7 +114,7 @@
|
|
40 |
|
41 |
if (idBatch.length != 0) {
|
42 |
// request the next batch of icons
|
43 |
-
|
44 |
}
|
45 |
}
|
46 |
|
@@ -51,12 +125,15 @@
|
|
51 |
function processRetrievedThumbnails(response) {
|
52 |
for (var id in response) {
|
53 |
if (response.hasOwnProperty(id)) {
|
54 |
-
var target =
|
|
|
|
|
55 |
(function(id, target) {
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
|
|
60 |
})(id, target);
|
61 |
}
|
62 |
}
|
@@ -64,4 +141,4 @@
|
|
64 |
// start next batch once this response is processed
|
65 |
retrieveNextIcons();
|
66 |
}
|
67 |
-
})();
|
1 |
+
(function($) {
|
2 |
+
// distinct list of all document IDs to be fetched via AJAX requests
|
3 |
+
var ids;
|
4 |
|
5 |
+
// current index in ids array
|
6 |
+
var i;
|
7 |
|
8 |
// find all document-icons without icons generated and start processing
|
9 |
+
$(document).ready(function() {
|
10 |
+
sizeGalleryIcons();
|
11 |
+
resetPendingIcons();
|
12 |
+
handleVisualEditor();
|
13 |
+
registerPaginationHandler();
|
14 |
+
});
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Sets the size of the gallery icons based on the column count.
|
18 |
+
* @param gallery If given, the target gallery. Otherwise all galleries on page.
|
19 |
+
*/
|
20 |
+
function sizeGalleryIcons(gallery) {
|
21 |
+
(gallery || $('.document-gallery[data-icon-width]')).each(function() {
|
22 |
+
var icon_width = $(this).data('icon-width') + '%';
|
23 |
+
$(this).find('.document-icon').width(icon_width);
|
24 |
+
});
|
25 |
+
}
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Handles necessary logic for when we're rendering gallery preview within visual editor.
|
29 |
+
*/
|
30 |
+
function handleVisualEditor() {
|
31 |
+
if (typeof tinymce !== 'undefined') {
|
32 |
+
tinymce.PluginManager.add('dg', function (editor, url) {
|
33 |
+
editor.on('LoadContent dgUpdate undo', function (e) {
|
34 |
+
$(e.target.contentDocument).find('.wpview-type-dg > [data-shortcode]').each(function () {
|
35 |
+
retrieveGallery($.parseJSON(decodeURIComponent($(this).data('shortcode'))), $(this));
|
36 |
+
});
|
37 |
+
});
|
38 |
+
});
|
39 |
+
}
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Listen for all pagination clicks in current DOM and any future DOM elements.
|
44 |
+
*/
|
45 |
+
function registerPaginationHandler() {
|
46 |
+
$('body').delegate('.dg-paginate-wrapper a.paginate', 'click', function (e) {
|
47 |
+
var target = $(this).closest('.dg-paginate-wrapper');
|
48 |
+
var atts = target.data('shortcode');
|
49 |
+
|
50 |
+
if ($(this).hasClass('left')) {
|
51 |
+
atts['skip'] -= atts['limit'];
|
52 |
+
} else {
|
53 |
+
atts['skip'] += atts['limit'];
|
54 |
+
}
|
55 |
+
|
56 |
+
retrieveGallery(atts, target);
|
57 |
+
e.preventDefault();
|
58 |
+
});
|
59 |
+
}
|
60 |
+
|
61 |
+
/**
|
62 |
+
* Collects all of the DG icons that need to be generated and starts requesting them via AJAX.
|
63 |
+
*/
|
64 |
+
function resetPendingIcons() {
|
65 |
+
ids = [];
|
66 |
+
i = 0;
|
67 |
+
|
68 |
+
$('.document-gallery img[data-id]').each(function() {
|
69 |
+
var id = $(this).data('id');
|
70 |
|
71 |
// if we have multiple galleries, we could have multiple elements
|
72 |
+
// needing the same icon and no need to request multiple times
|
73 |
+
if (-1 === $.inArray(id, ids)) {
|
74 |
ids.push(id);
|
75 |
}
|
76 |
});
|
77 |
|
78 |
retrieveNextIcons();
|
79 |
+
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
* Requests a gallery generated with the given attributes to populate the given target element.
|
83 |
+
* @param atts array The gallery shortcode attributes.
|
84 |
+
* @param target element The element to be updated with the AJAX HTML response.
|
85 |
+
*/
|
86 |
+
function retrieveGallery(atts, target) {
|
87 |
+
// TODO: Cache already-retrieved gallery pages. Need to be careful not to keep too many at a time
|
88 |
+
// (could consume a lot of memory) & handle caching pages for multiple galleries on a single pages.
|
89 |
+
$.post(ajaxurl, { action: 'dg_generate_gallery', atts: atts }, function(html) {
|
90 |
+
var jobj = $(html);
|
91 |
+
target.replaceWith(jobj);
|
92 |
+
sizeGalleryIcons(jobj);
|
93 |
+
resetPendingIcons();
|
94 |
+
});
|
95 |
+
}
|
96 |
|
97 |
/**
|
98 |
* Sends AJAX request to server requesting some of the not-yet-generated icons (if any).
|
114 |
|
115 |
if (idBatch.length != 0) {
|
116 |
// request the next batch of icons
|
117 |
+
$.post(ajaxurl, { action: 'dg_generate_icons', ids: idBatch }, processRetrievedThumbnails);
|
118 |
}
|
119 |
}
|
120 |
|
125 |
function processRetrievedThumbnails(response) {
|
126 |
for (var id in response) {
|
127 |
if (response.hasOwnProperty(id)) {
|
128 |
+
var target = $('.document-gallery img[data-id="' + id + '"]');
|
129 |
+
target.removeAttr('data-id');
|
130 |
+
|
131 |
(function(id, target) {
|
132 |
+
var speed = 'fast';
|
133 |
+
target.fadeOut(speed, function () {
|
134 |
+
$(this).attr('src', response[id]);
|
135 |
+
$(this).fadeIn(speed);
|
136 |
+
});
|
137 |
})(id, target);
|
138 |
}
|
139 |
}
|
141 |
// start next batch once this response is processed
|
142 |
retrieveNextIcons();
|
143 |
}
|
144 |
+
})(jQuery);
|
assets/js/gallery.min.js
CHANGED
@@ -1,2 +1,3 @@
|
|
1 |
-
(function(){function
|
2 |
-
-1===
|
|
1 |
+
(function(b){function g(a){(a||b(".document-gallery[data-icon-width]")).each(function(){var a=b(this).data("icon-width")+"%";b(this).find(".document-icon").width(a)})}function m(){"undefined"!==typeof tinymce&&tinymce.PluginManager.add("dg",function(a,d){a.on("LoadContent dgUpdate undo",function(a){b(a.target.contentDocument).find(".wpview-type-dg > [data-shortcode]").each(function(){h(b.parseJSON(decodeURIComponent(b(this).data("shortcode"))),b(this))})})})}function n(){b("body").delegate(".dg-paginate-wrapper a.paginate",
|
2 |
+
"click",function(a){var d=b(this).closest(".dg-paginate-wrapper"),c=d.data("shortcode");b(this).hasClass("left")?c.skip-=c.limit:c.skip+=c.limit;h(c,d);a.preventDefault()})}function k(){e=[];f=0;b(".document-gallery img[data-id]").each(function(){var a=b(this).data("id");-1===b.inArray(a,e)&&e.push(a)});l()}function h(a,d){b.post(ajaxurl,{action:"dg_generate_gallery",atts:a},function(a){a=b(a);d.replaceWith(a);g(a);k()})}function l(){for(var a=[];f<e.length&&2!==a.length;f++)a.push(e[f]);0!=a.length&&
|
3 |
+
b.post(ajaxurl,{action:"dg_generate_icons",ids:a},p)}function p(a){for(var d in a)if(a.hasOwnProperty(d)){var c=b('.document-gallery img[data-id="'+d+'"]');c.removeAttr("data-id");(function(c,d){d.fadeOut("fast",function(){b(this).attr("src",a[c]);b(this).fadeIn("fast")})})(d,c)}l()}var e,f;b(document).ready(function(){g();k();m();n()})})(jQuery);
|
assets/js/media_manager.js
CHANGED
@@ -1,14 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
( function ($, _) {
|
2 |
-
var
|
|
|
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.
|
10 |
*
|
11 |
-
* A state for editing a
|
12 |
*
|
13 |
* @class
|
14 |
* @augments wp.media.controller.Library
|
@@ -16,36 +26,36 @@
|
|
16 |
* @augments Backbone.Model
|
17 |
*
|
18 |
* @param {object} [attributes] The attributes hash passed to the state.
|
19 |
-
* @param {string} [attributes.id=
|
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
|
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
|
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
|
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.
|
40 |
defaults: {
|
41 |
-
id: '
|
42 |
-
title: l10n.
|
43 |
multiple: false,
|
44 |
searchable: false,
|
45 |
sortable: true,
|
46 |
display: false,
|
47 |
content: 'browse',
|
48 |
-
toolbar: '
|
49 |
describe: true,
|
50 |
displaySettings: true,
|
51 |
dragInfo: true,
|
@@ -76,12 +86,12 @@
|
|
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.
|
85 |
|
86 |
media.controller.Library.prototype.activate.apply(this, arguments);
|
87 |
},
|
@@ -93,7 +103,7 @@
|
|
93 |
// Stop watching for uploaded attachments.
|
94 |
this.get('library').unobserve(wp.Uploader.queue);
|
95 |
|
96 |
-
this.frame.off('content:render:browse', this.
|
97 |
|
98 |
media.controller.Library.prototype.deactivate.apply(this, arguments);
|
99 |
},
|
@@ -103,7 +113,7 @@
|
|
103 |
*
|
104 |
* @param browser
|
105 |
*/
|
106 |
-
|
107 |
if (!this.get('displaySettings')) {
|
108 |
return;
|
109 |
}
|
@@ -114,12 +124,12 @@
|
|
114 |
return;
|
115 |
}
|
116 |
|
117 |
-
library.
|
118 |
|
119 |
browser.sidebar.set({
|
120 |
-
|
121 |
controller: this,
|
122 |
-
model: library.
|
123 |
priority: 40
|
124 |
})
|
125 |
});
|
@@ -136,7 +146,7 @@
|
|
136 |
});
|
137 |
|
138 |
/**
|
139 |
-
* A state for selecting more images to add to a
|
140 |
*
|
141 |
* @class
|
142 |
* @augments wp.media.controller.Library
|
@@ -144,34 +154,34 @@
|
|
144 |
* @augments Backbone.Model
|
145 |
*
|
146 |
* @param {object} [attributes] The attributes hash passed to the state.
|
147 |
-
* @param {string} [attributes.id=
|
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=
|
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=
|
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.
|
168 |
defaults: _.defaults({
|
169 |
-
id: '
|
170 |
-
title: l10n.
|
171 |
multiple: 'add',
|
172 |
filterable: 'uploaded',
|
173 |
-
menu: '
|
174 |
-
toolbar: '
|
175 |
priority: 100,
|
176 |
syncSelection: false
|
177 |
}, media.controller.Library.prototype.defaults),
|
@@ -192,13 +202,13 @@
|
|
192 |
*/
|
193 |
activate: function () {
|
194 |
var library = this.get('library'),
|
195 |
-
edit = this.frame.state('
|
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
|
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 |
};
|
@@ -215,7 +225,7 @@
|
|
215 |
});
|
216 |
|
217 |
/**
|
218 |
-
* wp.media.view.Settings.
|
219 |
*
|
220 |
* @class
|
221 |
* @augments wp.media.view.Settings
|
@@ -223,12 +233,53 @@
|
|
223 |
* @augments wp.Backbone.View
|
224 |
* @augments Backbone.View
|
225 |
*/
|
226 |
-
media.view.Settings.
|
227 |
-
|
228 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
{
|
@@ -236,10 +287,10 @@
|
|
236 |
wpMediaFramePost.prototype.initialize.apply(this, arguments);
|
237 |
this.states.add([
|
238 |
new media.controller.Library({
|
239 |
-
id: '
|
240 |
-
title: l10n.
|
241 |
priority: 50,
|
242 |
-
toolbar: 'main-
|
243 |
filterable: 'all',
|
244 |
multiple: 'add',
|
245 |
editable: false,
|
@@ -248,32 +299,35 @@
|
|
248 |
}),
|
249 |
|
250 |
// Document Gallery states.
|
251 |
-
new media.controller.
|
252 |
library: this.options.selection,
|
253 |
editing: this.options.editing,
|
254 |
-
menu: '
|
255 |
}),
|
256 |
|
257 |
-
new media.controller.
|
258 |
]);
|
259 |
|
260 |
-
this.on('menu:create:
|
261 |
-
this.on('toolbar:create:main-
|
262 |
|
263 |
-
this.on('menu:render:
|
264 |
-
this.on('toolbar:render:main-
|
265 |
-
this.on('toolbar:render:
|
266 |
-
this.on('toolbar:render:
|
267 |
},
|
268 |
|
269 |
-
|
|
|
|
|
|
|
270 |
var lastState = this.lastState(),
|
271 |
previous = lastState && lastState.id,
|
272 |
frame = this;
|
273 |
|
274 |
view.set({
|
275 |
cancel: {
|
276 |
-
text: l10n.
|
277 |
priority: 20,
|
278 |
click: function () {
|
279 |
if (previous) {
|
@@ -283,7 +337,7 @@
|
|
283 |
}
|
284 |
|
285 |
// Keep focus inside media modal
|
286 |
-
// after canceling a
|
287 |
this.controller.modal.focusManager.focus();
|
288 |
}
|
289 |
},
|
@@ -297,41 +351,44 @@
|
|
297 |
/**
|
298 |
* @param {wp.Backbone.View} view
|
299 |
*/
|
300 |
-
|
301 |
var controller = this;
|
302 |
|
303 |
this.selectionStatusToolbar(view);
|
304 |
|
305 |
-
view.set('
|
306 |
style: 'primary',
|
307 |
-
text: l10n.
|
308 |
priority: 60,
|
309 |
requires: {selection: true},
|
310 |
|
311 |
click: function () {
|
312 |
var selection = controller.state().get('selection'),
|
313 |
-
edit = controller.state('
|
314 |
models = selection.models;
|
315 |
|
316 |
-
edit.set('library',
|
|
|
|
|
|
|
317 |
|
318 |
-
this.controller.setState('
|
319 |
|
320 |
// Keep focus inside media modal
|
321 |
-
// after jumping to
|
322 |
this.controller.modal.focusManager.focus();
|
323 |
}
|
324 |
});
|
325 |
},
|
326 |
|
327 |
-
|
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.
|
335 |
priority: 80,
|
336 |
requires: {library: true},
|
337 |
|
@@ -343,25 +400,28 @@
|
|
343 |
state = controller.state();
|
344 |
|
345 |
controller.close();
|
346 |
-
//state.trigger( 'update', state.get('library') );
|
347 |
-
wp.media.editor.insert(wp.media.
|
348 |
|
349 |
// Restore and reset the default state.
|
350 |
controller.setState(controller.options.state);
|
351 |
controller.reset();
|
|
|
|
|
|
|
352 |
}
|
353 |
}
|
354 |
}
|
355 |
}));
|
356 |
},
|
357 |
|
358 |
-
|
359 |
this.toolbar.set(new media.view.Toolbar({
|
360 |
controller: this,
|
361 |
items: {
|
362 |
insert: {
|
363 |
style: 'primary',
|
364 |
-
text: l10n.
|
365 |
priority: 80,
|
366 |
requires: {selection: true},
|
367 |
|
@@ -371,15 +431,126 @@
|
|
371 |
click: function () {
|
372 |
var controller = this.controller,
|
373 |
state = controller.state(),
|
374 |
-
edit = controller.state('
|
375 |
|
376 |
edit.get('library').add(state.get('selection').models);
|
377 |
state.trigger('reset');
|
378 |
-
controller.setState('
|
379 |
}
|
380 |
}
|
381 |
}
|
382 |
}));
|
383 |
}
|
384 |
});
|
385 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* Cause gallery shortcode is hardcoded into WP core and has a lot of relations with Media Manager and other parts
|
3 |
+
* had to copy related code and adjust to the DG needs.
|
4 |
+
* Since WP core make use of shortcode tag to get (build) needed function name while handling shortcode (especially in visual editor),
|
5 |
+
* named all DG related variables and functions using prefix or suffix (depending on context) same as shortcode tag - dg
|
6 |
+
* As long as WP core has strange conditional statements for order and orderby attributes had to rename them by adding dg prefix.
|
7 |
+
*
|
8 |
+
*/
|
9 |
( function ($, _) {
|
10 |
+
var l10n,
|
11 |
+
media = wp.media;
|
12 |
|
13 |
// Link any localized strings.
|
14 |
l10n = media.view.l10n = typeof _wpMediaViewsL10n === 'undefined' ? {} : _wpMediaViewsL10n;
|
15 |
jQuery.extend(l10n, DGl10n);
|
16 |
|
17 |
+
// Based on code from /wp-includes/js/media-views.js WP 4.1
|
18 |
/**
|
19 |
+
* wp.media.controller.dgEdit
|
20 |
*
|
21 |
+
* A state for editing a dg's images and settings.
|
22 |
*
|
23 |
* @class
|
24 |
* @augments wp.media.controller.Library
|
26 |
* @augments Backbone.Model
|
27 |
*
|
28 |
* @param {object} [attributes] The attributes hash passed to the state.
|
29 |
+
* @param {string} [attributes.id=dg-edit] Unique identifier.
|
30 |
+
* @param {string} [attributes.title=Edit Document Gallery] Title for the state. Displays in the frame's title region.
|
31 |
+
* @param {wp.media.model.Attachments} [attributes.library] The collection of attachments in the dg.
|
32 |
* If one is not supplied, an empty media.model.Selection collection is created.
|
33 |
* @param {boolean} [attributes.multiple=false] Whether multi-select is enabled.
|
34 |
* @param {boolean} [attributes.searchable=false] Whether the library is searchable.
|
35 |
* @param {boolean} [attributes.sortable=true] Whether the Attachments should be sortable. Depends on the orderby property being set to menuOrder on the attachments collection.
|
36 |
* @param {string|false} [attributes.content=browse] Initial mode for the content region.
|
37 |
* @param {string|false} [attributes.toolbar=image-details] Initial mode for the toolbar region.
|
38 |
+
* @param {boolean} [attributes.describe=true] Whether to offer UI to describe attachments - e.g. captioning images in a dg.
|
39 |
* @param {boolean} [attributes.displaySettings=true] Whether to show the attachment display settings interface.
|
40 |
* @param {boolean} [attributes.dragInfo=true] Whether to show instructional text about the attachments being sortable.
|
41 |
* @param {int} [attributes.idealColumnWidth=170] The ideal column width in pixels for attachments.
|
42 |
+
* @param {boolean} [attributes.editing=false] Whether the dg is being created, or editing an existing instance.
|
43 |
* @param {int} [attributes.priority=60] The priority for the state link in the media menu.
|
44 |
* @param {boolean} [attributes.syncSelection=false] Whether the Attachments selection should be persisted from the last state.
|
45 |
* Defaults to false for this state, because the library passed in *is* the selection.
|
46 |
* @param {view} [attributes.AttachmentView] The single `Attachment` view to be used in the `Attachments`.
|
47 |
* If none supplied, defaults to wp.media.view.Attachment.EditLibrary.
|
48 |
*/
|
49 |
+
media.controller.dgEdit = media.controller.Library.extend({
|
50 |
defaults: {
|
51 |
+
id: 'dg-edit',
|
52 |
+
title: l10n.editdgTitle,
|
53 |
multiple: false,
|
54 |
searchable: false,
|
55 |
sortable: true,
|
56 |
display: false,
|
57 |
content: 'browse',
|
58 |
+
toolbar: 'dg-edit',
|
59 |
describe: true,
|
60 |
displaySettings: true,
|
61 |
dragInfo: true,
|
86 |
var library = this.get('library');
|
87 |
|
88 |
// Limit the library to images only.
|
89 |
+
//library.props.set( 'type', 'image' );
|
90 |
|
91 |
// Watch for uploaded attachments.
|
92 |
this.get('library').observe(wp.Uploader.queue);
|
93 |
|
94 |
+
this.frame.on('content:render:browse', this.dgSettings, this);
|
95 |
|
96 |
media.controller.Library.prototype.activate.apply(this, arguments);
|
97 |
},
|
103 |
// Stop watching for uploaded attachments.
|
104 |
this.get('library').unobserve(wp.Uploader.queue);
|
105 |
|
106 |
+
this.frame.off('content:render:browse', this.dgSettings, this);
|
107 |
|
108 |
media.controller.Library.prototype.deactivate.apply(this, arguments);
|
109 |
},
|
113 |
*
|
114 |
* @param browser
|
115 |
*/
|
116 |
+
dgSettings: function (browser) {
|
117 |
if (!this.get('displaySettings')) {
|
118 |
return;
|
119 |
}
|
124 |
return;
|
125 |
}
|
126 |
|
127 |
+
library.dg = library.dg || new Backbone.Model();
|
128 |
|
129 |
browser.sidebar.set({
|
130 |
+
dg: new media.view.Settings.dg({
|
131 |
controller: this,
|
132 |
+
model: library.dg,
|
133 |
priority: 40
|
134 |
})
|
135 |
});
|
146 |
});
|
147 |
|
148 |
/**
|
149 |
+
* A state for selecting more images to add to a dg.
|
150 |
*
|
151 |
* @class
|
152 |
* @augments wp.media.controller.Library
|
154 |
* @augments Backbone.Model
|
155 |
*
|
156 |
* @param {object} [attributes] The attributes hash passed to the state.
|
157 |
+
* @param {string} [attributes.id=dg-library] Unique identifier.
|
158 |
+
* @param {string} [attributes.title=Add to Document Gallery] Title for the state. Displays in the frame's title region.
|
159 |
* @param {boolean} [attributes.multiple=add] Whether multi-select is enabled. @todo 'add' doesn't seem do anything special, and gets used as a boolean.
|
160 |
* @param {wp.media.model.Attachments} [attributes.library] The attachments collection to browse.
|
161 |
* If one is not supplied, a collection of all images will be created.
|
162 |
* @param {boolean|string} [attributes.filterable=uploaded] Whether the library is filterable, and if so what filters should be shown.
|
163 |
* Accepts 'all', 'uploaded', or 'unattached'.
|
164 |
+
* @param {string} [attributes.menu=dg] Initial mode for the menu region.
|
165 |
* @param {string} [attributes.content=upload] Initial mode for the content region.
|
166 |
* Overridden by persistent user setting if 'contentUserSetting' is true.
|
167 |
* @param {string} [attributes.router=browse] Initial mode for the router region.
|
168 |
+
* @param {string} [attributes.toolbar=dg-add] Initial mode for the toolbar region.
|
169 |
* @param {boolean} [attributes.searchable=true] Whether the library is searchable.
|
170 |
* @param {boolean} [attributes.sortable=true] Whether the Attachments should be sortable. Depends on the orderby property being set to menuOrder on the attachments collection.
|
171 |
* @param {boolean} [attributes.autoSelect=true] Whether an uploaded attachment should be automatically added to the selection.
|
172 |
* @param {boolean} [attributes.contentUserSetting=true] Whether the content region's mode should be set and persisted per user.
|
173 |
* @param {int} [attributes.priority=100] The priority for the state link in the media menu.
|
174 |
* @param {boolean} [attributes.syncSelection=false] Whether the Attachments selection should be persisted from the last state.
|
175 |
+
* Defaults to false because for this state, because the library of the Edit Document Gallery state is the selection.
|
176 |
*/
|
177 |
+
media.controller.dgAdd = media.controller.Library.extend({
|
178 |
defaults: _.defaults({
|
179 |
+
id: 'dg-library',
|
180 |
+
title: l10n.addTodgTitle,
|
181 |
multiple: 'add',
|
182 |
filterable: 'uploaded',
|
183 |
+
menu: 'dg',
|
184 |
+
toolbar: 'dg-add',
|
185 |
priority: 100,
|
186 |
syncSelection: false
|
187 |
}, media.controller.Library.prototype.defaults),
|
202 |
*/
|
203 |
activate: function () {
|
204 |
var library = this.get('library'),
|
205 |
+
edit = this.frame.state('dg-edit').get('library');
|
206 |
|
207 |
if (this.editLibrary && this.editLibrary !== edit)
|
208 |
library.unobserve(this.editLibrary);
|
209 |
|
210 |
// Accepts attachments that exist in the original library and
|
211 |
+
// that do not exist in dg's library.
|
212 |
library.validator = function (attachment) {
|
213 |
return !!this.mirroring.get(attachment.cid) && !edit.get(attachment.cid) && media.model.Selection.prototype.validator.apply(this, arguments);
|
214 |
};
|
225 |
});
|
226 |
|
227 |
/**
|
228 |
+
* wp.media.view.Settings.dg
|
229 |
*
|
230 |
* @class
|
231 |
* @augments wp.media.view.Settings
|
233 |
* @augments wp.Backbone.View
|
234 |
* @augments Backbone.View
|
235 |
*/
|
236 |
+
media.view.Settings.dg = media.view.Settings.extend({
|
237 |
+
update: function( key ) {
|
238 |
+
var value = this.model.get( key ),
|
239 |
+
$setting = this.$('[data-setting="' + key + '"]'),
|
240 |
+
$buttons, $value;
|
241 |
+
|
242 |
+
// Bail if we didn't find a matching setting.
|
243 |
+
if ( ! $setting.length ) {
|
244 |
+
return;
|
245 |
+
}
|
246 |
+
|
247 |
+
// Attempt to determine how the setting is rendered and update
|
248 |
+
// the selected value.
|
249 |
+
|
250 |
+
// Handle dropdowns.
|
251 |
+
if ( $setting.is('select') ) {
|
252 |
+
$value = $setting.find('[value="' + value + '"]');
|
253 |
+
|
254 |
+
if ( $value.length ) {
|
255 |
+
$setting.find('option').prop( 'selected', false );
|
256 |
+
$value.prop( 'selected', true );
|
257 |
+
} else {
|
258 |
+
// If we can't find the desired value, record what *is* selected.
|
259 |
+
this.model.set( key, $setting.find(':selected').val() );
|
260 |
+
}
|
261 |
+
|
262 |
+
// Handle button groups.
|
263 |
+
} else if ( $setting.hasClass('button-group') ) {
|
264 |
+
$buttons = $setting.find('button').removeClass('active');
|
265 |
+
$buttons.filter( '[value="' + value + '"]' ).addClass('active');
|
266 |
+
|
267 |
+
// Handle text inputs and textareas.
|
268 |
+
} else if ( $setting.is('input[type="text"], input[type="number"], textarea') ) {
|
269 |
+
if ( ! $setting.is(':focus') ) {
|
270 |
+
$setting.val( value );
|
271 |
+
}
|
272 |
+
// Handle checkboxes.
|
273 |
+
} else if ( $setting.is('input[type="checkbox"]') ) {
|
274 |
+
$setting.prop( 'checked', !! value && 'false' !== value );
|
275 |
+
}
|
276 |
+
},
|
277 |
+
className: 'collection-settings dg-settings',
|
278 |
+
template: media.template('dg-settings')
|
279 |
});
|
280 |
|
281 |
// supersede the default MediaFrame.Post view
|
282 |
+
// hint from https://gist.github.com/Fab1en/4586865
|
283 |
var wpMediaFramePost = wp.media.view.MediaFrame.Post;
|
284 |
wp.media.view.MediaFrame.Post = wpMediaFramePost.extend(
|
285 |
{
|
287 |
wpMediaFramePost.prototype.initialize.apply(this, arguments);
|
288 |
this.states.add([
|
289 |
new media.controller.Library({
|
290 |
+
id: 'dg',
|
291 |
+
title: l10n.dgMenuTitle,
|
292 |
priority: 50,
|
293 |
+
toolbar: 'main-dg',
|
294 |
filterable: 'all',
|
295 |
multiple: 'add',
|
296 |
editable: false,
|
299 |
}),
|
300 |
|
301 |
// Document Gallery states.
|
302 |
+
new media.controller.dgEdit({
|
303 |
library: this.options.selection,
|
304 |
editing: this.options.editing,
|
305 |
+
menu: 'dg'
|
306 |
}),
|
307 |
|
308 |
+
new media.controller.dgAdd()
|
309 |
]);
|
310 |
|
311 |
+
this.on('menu:create:dg', this.createMenu, this);
|
312 |
+
this.on('toolbar:create:main-dg', this.createToolbar, this);
|
313 |
|
314 |
+
this.on('menu:render:dg', this.dgMenu, this);
|
315 |
+
this.on('toolbar:render:main-dg', this.maindgToolbar, this);
|
316 |
+
this.on('toolbar:render:dg-edit', this.dgEditToolbar, this);
|
317 |
+
this.on('toolbar:render:dg-add', this.dgAddToolbar, this);
|
318 |
},
|
319 |
|
320 |
+
/**
|
321 |
+
* @param {wp.Backbone.View} view
|
322 |
+
*/
|
323 |
+
dgMenu: function (view) {
|
324 |
var lastState = this.lastState(),
|
325 |
previous = lastState && lastState.id,
|
326 |
frame = this;
|
327 |
|
328 |
view.set({
|
329 |
cancel: {
|
330 |
+
text: l10n.canceldgTitle,
|
331 |
priority: 20,
|
332 |
click: function () {
|
333 |
if (previous) {
|
337 |
}
|
338 |
|
339 |
// Keep focus inside media modal
|
340 |
+
// after canceling a dg
|
341 |
this.controller.modal.focusManager.focus();
|
342 |
}
|
343 |
},
|
351 |
/**
|
352 |
* @param {wp.Backbone.View} view
|
353 |
*/
|
354 |
+
maindgToolbar: function (view) {
|
355 |
var controller = this;
|
356 |
|
357 |
this.selectionStatusToolbar(view);
|
358 |
|
359 |
+
view.set('dg', {
|
360 |
style: 'primary',
|
361 |
+
text: l10n.dgButton,
|
362 |
priority: 60,
|
363 |
requires: {selection: true},
|
364 |
|
365 |
click: function () {
|
366 |
var selection = controller.state().get('selection'),
|
367 |
+
edit = controller.state('dg-edit'),
|
368 |
models = selection.models;
|
369 |
|
370 |
+
edit.set('library', new media.model.Selection(models, {
|
371 |
+
props: selection.props.toJSON(),
|
372 |
+
multiple: true
|
373 |
+
}));
|
374 |
|
375 |
+
this.controller.setState('dg-edit');
|
376 |
|
377 |
// Keep focus inside media modal
|
378 |
+
// after jumping to dg view
|
379 |
this.controller.modal.focusManager.focus();
|
380 |
}
|
381 |
});
|
382 |
},
|
383 |
|
384 |
+
dgEditToolbar: function () {
|
385 |
var editing = this.state().get('editing');
|
386 |
this.toolbar.set(new media.view.Toolbar({
|
387 |
controller: this,
|
388 |
items: {
|
389 |
insert: {
|
390 |
style: 'primary',
|
391 |
+
text: editing ? l10n.updatedg : l10n.insertdg,
|
392 |
priority: 80,
|
393 |
requires: {library: true},
|
394 |
|
400 |
state = controller.state();
|
401 |
|
402 |
controller.close();
|
403 |
+
//state.trigger( 'update', state.get('library') ); // calling for workflow.state update, so just execute its contents
|
404 |
+
wp.media.editor.insert(wp.media.dg.shortcode(state.get('library')).string().replace(/\sdgorder=/ig, ' order=').replace(/\sdgorderby=/ig, ' orderby='));
|
405 |
|
406 |
// Restore and reset the default state.
|
407 |
controller.setState(controller.options.state);
|
408 |
controller.reset();
|
409 |
+
if (typeof tinyMCE != 'undefined') {
|
410 |
+
tinyMCE.activeEditor.fire('dgUpdate');
|
411 |
+
}
|
412 |
}
|
413 |
}
|
414 |
}
|
415 |
}));
|
416 |
},
|
417 |
|
418 |
+
dgAddToolbar: function () {
|
419 |
this.toolbar.set(new media.view.Toolbar({
|
420 |
controller: this,
|
421 |
items: {
|
422 |
insert: {
|
423 |
style: 'primary',
|
424 |
+
text: l10n.addTodg,
|
425 |
priority: 80,
|
426 |
requires: {selection: true},
|
427 |
|
431 |
click: function () {
|
432 |
var controller = this.controller,
|
433 |
state = controller.state(),
|
434 |
+
edit = controller.state('dg-edit');
|
435 |
|
436 |
edit.get('library').add(state.get('selection').models);
|
437 |
state.trigger('reset');
|
438 |
+
controller.setState('dg-edit');
|
439 |
}
|
440 |
}
|
441 |
}
|
442 |
}));
|
443 |
}
|
444 |
});
|
445 |
+
|
446 |
+
// Based on code from /wp-includes/js/media-editor.js WP 4.1
|
447 |
+
|
448 |
+
wp.media._dgDefaults = {
|
449 |
+
id: wp.media.view.settings.post && wp.media.view.settings.post.id,
|
450 |
+
columns: dgDefaults.columns,
|
451 |
+
fancy: dgDefaults.fancy,
|
452 |
+
relation: dgDefaults.relation,
|
453 |
+
limit: dgDefaults.limit,
|
454 |
+
mime_types: dgDefaults.mime_types,
|
455 |
+
post_status: dgDefaults.post_status,
|
456 |
+
post_type: dgDefaults.post_type,
|
457 |
+
attachment_pg: dgDefaults.attachment_pg,
|
458 |
+
descriptions: dgDefaults.descriptions,
|
459 |
+
new_window: dgDefaults.new_window,
|
460 |
+
paginate: dgDefaults.paginate,
|
461 |
+
dgorder: dgDefaults.order,
|
462 |
+
dgorderby: dgDefaults.orderby
|
463 |
+
};
|
464 |
+
|
465 |
+
if (wp.media.view.settings.dgDefaults) {
|
466 |
+
wp.media.dgDefaults = _.extend({}, wp.media._dgDefaults, wp.media.view.settings.dgDefaults);
|
467 |
+
} else {
|
468 |
+
wp.media.dgDefaults = wp.media._dgDefaults;
|
469 |
+
}
|
470 |
+
|
471 |
+
wp.media.dg = new wp.media.collection({
|
472 |
+
tag: 'dg',
|
473 |
+
//type : 'image',
|
474 |
+
editTitle: wp.media.view.l10n.editdgTitle,
|
475 |
+
defaults: wp.media.dgDefaults,
|
476 |
+
|
477 |
+
setDefaults: function (attrs) {
|
478 |
+
var self = this, changed = !_.isEqual(wp.media.dgDefaults, wp.media._dgDefaults);
|
479 |
+
_.each(this.defaults, function (value, key) {
|
480 |
+
attrs[key] = self.coerce(attrs, key);
|
481 |
+
if (value === attrs[key] && ( !changed || value === wp.media._dgDefaults[key] )) {
|
482 |
+
delete attrs[key];
|
483 |
+
}
|
484 |
+
});
|
485 |
+
return attrs;
|
486 |
+
}
|
487 |
+
});
|
488 |
+
}(jQuery, _));
|
489 |
+
|
490 |
+
// Based on code from /wp-includes/js/mce-view.js WP 4.2
|
491 |
+
/*
|
492 |
+
* The WordPress core TinyMCE views.
|
493 |
+
* View for the dg shortcode.
|
494 |
+
*/
|
495 |
+
(function (window, views, media, $) {
|
496 |
+
var dg;
|
497 |
+
|
498 |
+
base = {
|
499 |
+
state: [],
|
500 |
+
|
501 |
+
edit: function (text, update) {
|
502 |
+
// currently the shortcode *must* include ids attribute and may include any of the listed attributes to be editable
|
503 |
+
if ( text.search( /\sids\s*=/gi ) == -1 || text.search( /\s(?!(?:ids|attachment_pg|columns|new_window|descriptions|fancy|orderby|order|paginate|limit)\s*=)[\w\-]+\s*=/gi ) > -1 ) {
|
504 |
+
tinyMCE.activeEditor.windowManager.alert( DGl10n.unfitSCalert );
|
505 |
+
} else {
|
506 |
+
var type = this.type,
|
507 |
+
frame = media[type].edit(text.replace(/\sorder\s*=/ig, ' dgorder=').replace(/\sorderby\s*=/ig, ' dgorderby='));
|
508 |
+
|
509 |
+
this.pausePlayers && this.pausePlayers();
|
510 |
+
|
511 |
+
_.each(this.state, function (state) {
|
512 |
+
frame.state(state).on('update', function (selection) {
|
513 |
+
update(media[type].shortcode(selection).string(), type === 'dg');
|
514 |
+
});
|
515 |
+
});
|
516 |
+
|
517 |
+
frame.on('close', function () {
|
518 |
+
frame.detach();
|
519 |
+
});
|
520 |
+
|
521 |
+
frame.open();
|
522 |
+
}
|
523 |
+
}
|
524 |
+
};
|
525 |
+
|
526 |
+
dg = _.extend({}, base, {
|
527 |
+
state: ['dg-edit'],
|
528 |
+
template: media.template('editor-dg'),
|
529 |
+
|
530 |
+
initialize: function () {
|
531 |
+
var attachments = media.dg.attachments(this.shortcode, media.view.settings.post.id),
|
532 |
+
attrs = this.shortcode.attrs.named,
|
533 |
+
sc = this.text,
|
534 |
+
atts = {},
|
535 |
+
self = this;
|
536 |
+
|
537 |
+
for (prop in attrs) {
|
538 |
+
if (sc.indexOf(' ' + prop + '=') > -1) {
|
539 |
+
atts[prop] = attrs[prop];
|
540 |
+
}
|
541 |
+
}
|
542 |
+
if (sc.indexOf(' dgorderby=') > -1) {
|
543 |
+
atts['orderby'] = attrs['dgorderby'];
|
544 |
+
}
|
545 |
+
if (sc.indexOf(' dgorder=') > -1) {
|
546 |
+
atts['order'] = attrs['dgorder'];
|
547 |
+
}
|
548 |
+
self.render('<div data-shortcode="' +
|
549 |
+
encodeURIComponent(JSON.stringify(atts)) +
|
550 |
+
'"><div class="loading-placeholder"><div class="dashicons dashicons-admin-media"></div><div class="wpview-loading"><ins></ins></div></div></div>');
|
551 |
+
}
|
552 |
+
});
|
553 |
+
|
554 |
+
views.register('dg', _.extend({}, dg));
|
555 |
+
|
556 |
+
})(window, window.wp.mce.views, window.wp.media, window.jQuery);
|
assets/js/media_manager.min.js
CHANGED
@@ -1,10 +1,15 @@
|
|
1 |
-
(function(g
|
2 |
-
this.set("
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
this.createMenu,this);this.on("toolbar:create:main-
|
8 |
-
priority:20,click:function(){e
|
9 |
-
this.controller.modal.focusManager.focus()}})},
|
10 |
-
|
|
|
|
|
|
|
|
|
|
1 |
+
(function(h,g){var d,a=wp.media;d=a.view.l10n="undefined"===typeof _wpMediaViewsL10n?{}:_wpMediaViewsL10n;jQuery.extend(d,DGl10n);a.controller.dgEdit=a.controller.Library.extend({defaults:{id:"dg-edit",title:d.editdgTitle,multiple:!1,searchable:!1,sortable:!0,display:!1,content:"browse",toolbar:"dg-edit",describe:!0,displaySettings:!0,dragInfo:!0,idealColumnWidth:170,editing:!1,priority:60,syncSelection:!1},initialize:function(){this.get("library")||this.set("library",new a.model.Selection);this.get("AttachmentView")||
|
2 |
+
this.set("AttachmentView",a.view.Attachment.EditLibrary);a.controller.Library.prototype.initialize.apply(this,arguments)},activate:function(){this.get("library");this.get("library").observe(wp.Uploader.queue);this.frame.on("content:render:browse",this.dgSettings,this);a.controller.Library.prototype.activate.apply(this,arguments)},deactivate:function(){this.get("library").unobserve(wp.Uploader.queue);this.frame.off("content:render:browse",this.dgSettings,this);a.controller.Library.prototype.deactivate.apply(this,
|
3 |
+
arguments)},dgSettings:function(b){if(this.get("displaySettings")){var c=this.get("library");c&&b&&(c.dg=c.dg||new Backbone.Model,b.sidebar.set({dg:new a.view.Settings.dg({controller:this,model:c.dg,priority:40})}),b.toolbar.set("reverse",{text:d.reverseOrder,priority:80,click:function(){c.reset(c.toArray().reverse())}}))}}});a.controller.dgAdd=a.controller.Library.extend({defaults:g.defaults({id:"dg-library",title:d.addTodgTitle,multiple:"add",filterable:"uploaded",menu:"dg",toolbar:"dg-add",priority:100,
|
4 |
+
syncSelection:!1},a.controller.Library.prototype.defaults),initialize:function(){this.get("library")||this.set("library",a.query());a.controller.Library.prototype.initialize.apply(this,arguments)},activate:function(){var b=this.get("library"),c=this.frame.state("dg-edit").get("library");this.editLibrary&&this.editLibrary!==c&&b.unobserve(this.editLibrary);b.validator=function(b){return!!this.mirroring.get(b.cid)&&!c.get(b.cid)&&a.model.Selection.prototype.validator.apply(this,arguments)};b.reset(b.mirroring.models,
|
5 |
+
{silent:!0});b.observe(c);this.editLibrary=c;a.controller.Library.prototype.activate.apply(this,arguments)}});a.view.Settings.dg=a.view.Settings.extend({update:function(b){var c=this.model.get(b),a=this.$('[data-setting="'+b+'"]');a.length&&(a.is("select")?(c=a.find('[value="'+c+'"]'),c.length?(a.find("option").prop("selected",!1),c.prop("selected",!0)):this.model.set(b,a.find(":selected").val())):a.hasClass("button-group")?(b=a.find("button").removeClass("active"),b.filter('[value="'+c+'"]').addClass("active")):
|
6 |
+
a.is('input[type="text"], input[type="number"], textarea')?a.is(":focus")||a.val(c):a.is('input[type="checkbox"]')&&a.prop("checked",!!c&&"false"!==c))},className:"collection-settings dg-settings",template:a.template("dg-settings")});var e=wp.media.view.MediaFrame.Post;wp.media.view.MediaFrame.Post=e.extend({initialize:function(){e.prototype.initialize.apply(this,arguments);this.states.add([new a.controller.Library({id:"dg",title:d.dgMenuTitle,priority:50,toolbar:"main-dg",filterable:"all",multiple:"add",
|
7 |
+
editable:!1,library:a.query(this.options.library)}),new a.controller.dgEdit({library:this.options.selection,editing:this.options.editing,menu:"dg"}),new a.controller.dgAdd]);this.on("menu:create:dg",this.createMenu,this);this.on("toolbar:create:main-dg",this.createToolbar,this);this.on("menu:render:dg",this.dgMenu,this);this.on("toolbar:render:main-dg",this.maindgToolbar,this);this.on("toolbar:render:dg-edit",this.dgEditToolbar,this);this.on("toolbar:render:dg-add",this.dgAddToolbar,this)},dgMenu:function(b){var c=
|
8 |
+
this.lastState(),f=c&&c.id,e=this;b.set({cancel:{text:d.canceldgTitle,priority:20,click:function(){f?e.setState(f):e.close();this.controller.modal.focusManager.focus()}},separateCancel:new a.View({className:"separator",priority:40})})},maindgToolbar:function(b){var c=this;this.selectionStatusToolbar(b);b.set("dg",{style:"primary",text:d.dgButton,priority:60,requires:{selection:!0},click:function(){var b=c.state().get("selection");c.state("dg-edit").set("library",new a.model.Selection(b.models,{props:b.props.toJSON(),
|
9 |
+
multiple:!0}));this.controller.setState("dg-edit");this.controller.modal.focusManager.focus()}})},dgEditToolbar:function(){var b=this.state().get("editing");this.toolbar.set(new a.view.Toolbar({controller:this,items:{insert:{style:"primary",text:b?d.updatedg:d.insertdg,priority:80,requires:{library:!0},click:function(){var c=this.controller,b=c.state();c.close();wp.media.editor.insert(wp.media.dg.shortcode(b.get("library")).string().replace(/\sdgorder=/ig," order=").replace(/\sdgorderby=/ig," orderby="));
|
10 |
+
c.setState(c.options.state);c.reset();"undefined"!=typeof tinyMCE&&tinyMCE.activeEditor.fire("dgUpdate")}}}}))},dgAddToolbar:function(){this.toolbar.set(new a.view.Toolbar({controller:this,items:{insert:{style:"primary",text:d.addTodg,priority:80,requires:{selection:!0},click:function(){var b=this.controller,c=b.state();b.state("dg-edit").get("library").add(c.get("selection").models);c.trigger("reset");b.setState("dg-edit")}}}}))}});wp.media._dgDefaults={id:wp.media.view.settings.post&&wp.media.view.settings.post.id,
|
11 |
+
columns:dgDefaults.columns,fancy:dgDefaults.fancy,relation:dgDefaults.relation,limit:dgDefaults.limit,mime_types:dgDefaults.mime_types,post_status:dgDefaults.post_status,post_type:dgDefaults.post_type,attachment_pg:dgDefaults.attachment_pg,descriptions:dgDefaults.descriptions,new_window:dgDefaults.new_window,paginate:dgDefaults.paginate,dgorder:dgDefaults.order,dgorderby:dgDefaults.orderby};wp.media.dgDefaults=wp.media.view.settings.dgDefaults?g.extend({},wp.media._dgDefaults,wp.media.view.settings.dgDefaults):
|
12 |
+
wp.media._dgDefaults;wp.media.dg=new wp.media.collection({tag:"dg",editTitle:wp.media.view.l10n.editdgTitle,defaults:wp.media.dgDefaults,setDefaults:function(b){var c=this,a=!g.isEqual(wp.media.dgDefaults,wp.media._dgDefaults);g.each(this.defaults,function(d,e){b[e]=c.coerce(b,e);d!==b[e]||a&&d!==wp.media._dgDefaults[e]||delete b[e]});return b}})})(jQuery,_);
|
13 |
+
(function(h,g,d,a){base={state:[],edit:function(a,b){if(-1==a.search(/\sids\s*=/gi)||-1<a.search(/\s(?!(?:ids|attachment_pg|columns|new_window|descriptions|fancy|orderby|order|paginate|limit)\s*=)[\w\-]+\s*=/gi))tinyMCE.activeEditor.windowManager.alert(DGl10n.unfitSCalert);else{var c=this.type,f=d[c].edit(a.replace(/\sorder\s*=/ig," dgorder=").replace(/\sorderby\s*=/ig," dgorderby="));this.pausePlayers&&this.pausePlayers();_.each(this.state,function(a){f.state(a).on("update",function(a){b(d[c].shortcode(a).string(),
|
14 |
+
"dg"===c)})});f.on("close",function(){f.detach()});f.open()}}};h=_.extend({},base,{state:["dg-edit"],template:d.template("editor-dg"),initialize:function(){d.dg.attachments(this.shortcode,d.view.settings.post.id);var a=this.shortcode.attrs.named,b=this.text,c={};for(prop in a)-1<b.indexOf(" "+prop+"=")&&(c[prop]=a[prop]);-1<b.indexOf(" dgorderby=")&&(c.orderby=a.dgorderby);-1<b.indexOf(" dgorder=")&&(c.order=a.dgorder);this.render('<div data-shortcode="'+encodeURIComponent(JSON.stringify(c))+'"><div class="loading-placeholder"><div class="dashicons dashicons-admin-media"></div><div class="wpview-loading"><ins></ins></div></div></div>')}});
|
15 |
+
g.register("dg",_.extend({},h))})(window,window.wp.mce.views,window.wp.media,window.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:
|
9 |
Author: Dan Rossiter
|
10 |
Author URI: http://danrossiter.org/
|
11 |
License: GPLv2
|
12 |
Text Domain: document-gallery
|
13 |
*/
|
14 |
|
15 |
-
define( 'DG_VERSION', '
|
16 |
|
17 |
// define helper paths & URLs
|
18 |
define( 'DG_BASENAME', plugin_basename( __FILE__ ) );
|
@@ -28,8 +28,7 @@ $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
|
@@ -51,12 +50,15 @@ add_action( 'plugins_loaded', array( 'DocumentGallery', 'loadTextDomain' ) );
|
|
51 |
|
52 |
// cleanup cached data when thumbed attachment deleted
|
53 |
include_once DG_PATH . 'inc/class-thumber.php';
|
54 |
-
add_action( 'delete_attachment', array( '
|
55 |
|
56 |
if ( is_admin() ) {
|
57 |
// admin house keeping
|
58 |
include_once DG_PATH . 'admin/class-admin.php';
|
59 |
|
|
|
|
|
|
|
60 |
// add links to plugin index
|
61 |
add_filter( 'plugin_action_links_' . DG_BASENAME, array( 'DG_Admin', 'addSettingsLink' ) );
|
62 |
add_filter( 'plugin_row_meta', array( 'DG_Admin', 'addDonateLink' ), 10, 2 );
|
@@ -77,9 +79,6 @@ if ( is_admin() ) {
|
|
77 |
if ( DG_Admin::doRegisterSettings() ) {
|
78 |
add_action( 'admin_init', array( 'DG_Admin', 'registerSettings' ) );
|
79 |
}
|
80 |
-
|
81 |
-
add_action( 'wp_ajax_dg_generate_icons', array( 'DocumentGallery', 'ajaxGenerateIcons' ) );
|
82 |
-
add_action( 'wp_ajax_nopriv_dg_generate_icons', array( 'DocumentGallery', 'ajaxGenerateIcons' ) );
|
83 |
} else {
|
84 |
// styling for gallery
|
85 |
if ( apply_filters( 'dg_use_default_gallery_style', true ) ) {
|
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: 4.0
|
9 |
Author: Dan Rossiter
|
10 |
Author URI: http://danrossiter.org/
|
11 |
License: GPLv2
|
12 |
Text Domain: document-gallery
|
13 |
*/
|
14 |
|
15 |
+
define( 'DG_VERSION', '4.0' );
|
16 |
|
17 |
// define helper paths & URLs
|
18 |
define( 'DG_BASENAME', plugin_basename( __FILE__ ) );
|
28 |
|
29 |
// core functionality
|
30 |
include_once DG_PATH . 'inc/class-document-gallery.php';
|
31 |
+
include_once DG_PATH . 'inc/class-thumb.php';
|
|
|
32 |
include_once DG_PATH . 'inc/class-util.php';
|
33 |
|
34 |
// logging functionality
|
50 |
|
51 |
// cleanup cached data when thumbed attachment deleted
|
52 |
include_once DG_PATH . 'inc/class-thumber.php';
|
53 |
+
add_action( 'delete_attachment', array( 'DG_Thumb', 'cleanupAttachmentMeta' ) );
|
54 |
|
55 |
if ( is_admin() ) {
|
56 |
// admin house keeping
|
57 |
include_once DG_PATH . 'admin/class-admin.php';
|
58 |
|
59 |
+
// AJAX handling
|
60 |
+
include_once DG_PATH . 'admin/class-ajax-handler.php';
|
61 |
+
|
62 |
// add links to plugin index
|
63 |
add_filter( 'plugin_action_links_' . DG_BASENAME, array( 'DG_Admin', 'addSettingsLink' ) );
|
64 |
add_filter( 'plugin_row_meta', array( 'DG_Admin', 'addDonateLink' ), 10, 2 );
|
79 |
if ( DG_Admin::doRegisterSettings() ) {
|
80 |
add_action( 'admin_init', array( 'DG_Admin', 'registerSettings' ) );
|
81 |
}
|
|
|
|
|
|
|
82 |
} else {
|
83 |
// styling for gallery
|
84 |
if ( apply_filters( 'dg_use_default_gallery_style', true ) ) {
|
inc/class-document-gallery.php
CHANGED
@@ -56,7 +56,7 @@ class DocumentGallery {
|
|
56 |
// need AJAX URL variable in frontend
|
57 |
?>
|
58 |
<script type="text/javascript">
|
59 |
-
|
60 |
</script>
|
61 |
<?php
|
62 |
}
|
@@ -76,27 +76,6 @@ class DocumentGallery {
|
|
76 |
* HELPER FUNCTIONS
|
77 |
*=========================================================================*/
|
78 |
|
79 |
-
/**
|
80 |
-
* Accepts AJAX request containing list of IDs to be generated and returned.
|
81 |
-
* Returns associative array mapping ID to thumbnail URL for all icons that were generated,
|
82 |
-
* skipping any that could not be processed.
|
83 |
-
*/
|
84 |
-
public static function ajaxGenerateIcons() {
|
85 |
-
$ret = array();
|
86 |
-
|
87 |
-
if ( array_key_exists( 'ids', $_REQUEST ) ) {
|
88 |
-
foreach ( $_REQUEST['ids'] as $id ) {
|
89 |
-
// only return URL if different from default -- default image is already displayed on the client side
|
90 |
-
$url = DG_Thumber::getThumbnail( $id );
|
91 |
-
if ( $url !== DG_Thumber::getDefaultThumbnail( $id ) ) {
|
92 |
-
$ret[$id] = $url;
|
93 |
-
}
|
94 |
-
}
|
95 |
-
}
|
96 |
-
|
97 |
-
wp_send_json($ret);
|
98 |
-
}
|
99 |
-
|
100 |
/**
|
101 |
* @param int $blog ID of the blog to be retrieved in multisite env.
|
102 |
*
|
@@ -207,16 +186,17 @@ class DocumentGallery {
|
|
207 |
* @return string The local time in the WP date/time format.
|
208 |
*/
|
209 |
public static function localDateTimeFromTimestamp( $timestamp ) {
|
210 |
-
static $
|
211 |
static $wp_date_format = null;
|
212 |
static $wp_time_format = null;
|
213 |
-
if ( is_null( $
|
214 |
-
$
|
215 |
$wp_date_format = get_option( 'date_format' );
|
216 |
$wp_time_format = get_option( 'time_format' );
|
217 |
}
|
218 |
|
219 |
-
return '<span class="nowrap">' . date_i18n( $wp_date_format, $timestamp + $
|
|
|
220 |
}
|
221 |
|
222 |
/**
|
56 |
// need AJAX URL variable in frontend
|
57 |
?>
|
58 |
<script type="text/javascript">
|
59 |
+
ajaxurl = typeof(ajaxurl) !== 'string' ? '<?php echo admin_url( 'admin-ajax.php' ); ?>' : ajaxurl;
|
60 |
</script>
|
61 |
<?php
|
62 |
}
|
76 |
* HELPER FUNCTIONS
|
77 |
*=========================================================================*/
|
78 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
/**
|
80 |
* @param int $blog ID of the blog to be retrieved in multisite env.
|
81 |
*
|
186 |
* @return string The local time in the WP date/time format.
|
187 |
*/
|
188 |
public static function localDateTimeFromTimestamp( $timestamp ) {
|
189 |
+
static $gmt_offset = null;
|
190 |
static $wp_date_format = null;
|
191 |
static $wp_time_format = null;
|
192 |
+
if ( is_null( $gmt_offset ) ) {
|
193 |
+
$gmt_offset = get_option( 'gmt_offset' );
|
194 |
$wp_date_format = get_option( 'date_format' );
|
195 |
$wp_time_format = get_option( 'time_format' );
|
196 |
}
|
197 |
|
198 |
+
return '<span class="nowrap">' . date_i18n( $wp_date_format, $timestamp + $gmt_offset * 3600 ) . '</span> ' .
|
199 |
+
'<span class="nowrap">' . date_i18n( $wp_time_format, $timestamp + $gmt_offset * 3600 ) . '</span>';
|
200 |
}
|
201 |
|
202 |
/**
|
inc/class-document.php
CHANGED
@@ -9,15 +9,15 @@ defined( 'WPINC' ) OR exit;
|
|
9 |
class DG_Document {
|
10 |
|
11 |
/*==========================================================================
|
12 |
-
|
13 |
-
|
14 |
|
15 |
// general document data
|
16 |
private $description, $gallery, $ID, $link, $title, $title_attribute, $path, $extension, $size;
|
17 |
|
18 |
/*==========================================================================
|
19 |
-
|
20 |
-
|
21 |
|
22 |
/**
|
23 |
* Constructs instance of Document.
|
@@ -39,12 +39,20 @@ class DG_Document {
|
|
39 |
$this->path = get_attached_file( $attachment->ID );
|
40 |
$wp_filetype = wp_check_filetype_and_ext( $this->path, basename( $this->path ) );
|
41 |
$this->extension = $wp_filetype['ext'];
|
42 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
}
|
44 |
|
45 |
/*==========================================================================
|
46 |
-
|
47 |
-
|
48 |
|
49 |
/**
|
50 |
* Returns HTML representing this Document.
|
@@ -54,29 +62,30 @@ class DG_Document {
|
|
54 |
*/
|
55 |
public function __toString() {
|
56 |
include_once DG_PATH . 'inc/class-thumber.php';
|
57 |
-
$options = DG_Thumber::getOptions();
|
58 |
|
59 |
-
$thumb = null;
|
60 |
$data = '';
|
61 |
$description = '';
|
62 |
$target = $this->gallery->openLinkInNewWindow() ? '_blank' : '_self';
|
63 |
|
64 |
if ( $this->gallery->useFancyThumbs() ) {
|
65 |
-
|
66 |
-
|
67 |
-
|
|
|
|
|
|
|
68 |
} else {
|
69 |
// include a data-* attribute for client side to asynchronously request icon after gallery load
|
70 |
-
$data = '
|
71 |
}
|
72 |
}
|
73 |
|
74 |
-
if (
|
75 |
$thumb = DG_Thumber::getDefaultThumbnail( $this->ID );
|
76 |
}
|
77 |
|
78 |
-
$repl = array( $this->link, $thumb, $this->title_attribute, $this->title, $target, $this->extension, $this->size, $this->path );
|
79 |
-
$find = array( '%link%', '%img%', '%title_attribute%', '%title%', '%target%', '%extension%', '%size%', '%path%' );
|
80 |
|
81 |
// if descriptions then add filterable tag and value to replaced tag
|
82 |
if ( $this->gallery->useDescriptions() ) {
|
@@ -86,17 +95,16 @@ class DG_Document {
|
|
86 |
}
|
87 |
|
88 |
$doc_icon =
|
89 |
-
' <div class="document-icon"
|
90 |
-
' <a href="%link%" target="%target%"
|
|
|
|
|
|
|
91 |
' </div>' . PHP_EOL .
|
92 |
$description;
|
93 |
|
94 |
// allow developers to filter icon output
|
95 |
-
$doc_icon = apply_filters(
|
96 |
-
'dg_icon_template',
|
97 |
-
$doc_icon,
|
98 |
-
$this->gallery->useDescriptions(),
|
99 |
-
$this->ID );
|
100 |
|
101 |
return str_replace( $find, $repl, $doc_icon );
|
102 |
}
|
9 |
class DG_Document {
|
10 |
|
11 |
/*==========================================================================
|
12 |
+
* PRIVATE FIELDS
|
13 |
+
*=========================================================================*/
|
14 |
|
15 |
// general document data
|
16 |
private $description, $gallery, $ID, $link, $title, $title_attribute, $path, $extension, $size;
|
17 |
|
18 |
/*==========================================================================
|
19 |
+
* INIT GALLERY
|
20 |
+
*=========================================================================*/
|
21 |
|
22 |
/**
|
23 |
* Constructs instance of Document.
|
39 |
$this->path = get_attached_file( $attachment->ID );
|
40 |
$wp_filetype = wp_check_filetype_and_ext( $this->path, basename( $this->path ) );
|
41 |
$this->extension = $wp_filetype['ext'];
|
42 |
+
$size = @filesize( $this->path );
|
43 |
+
$this->size = ($size !== false) ? size_format( $size ) : 0;
|
44 |
+
}
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @return int The attachment ID.
|
48 |
+
*/
|
49 |
+
public function getId() {
|
50 |
+
return $this->ID;
|
51 |
}
|
52 |
|
53 |
/*==========================================================================
|
54 |
+
* OUTPUT HTML STRING
|
55 |
+
*=========================================================================*/
|
56 |
|
57 |
/**
|
58 |
* Returns HTML representing this Document.
|
62 |
*/
|
63 |
public function __toString() {
|
64 |
include_once DG_PATH . 'inc/class-thumber.php';
|
|
|
65 |
|
|
|
66 |
$data = '';
|
67 |
$description = '';
|
68 |
$target = $this->gallery->openLinkInNewWindow() ? '_blank' : '_self';
|
69 |
|
70 |
if ( $this->gallery->useFancyThumbs() ) {
|
71 |
+
$thumb_obj = DG_Thumb::getThumb( $this->ID );
|
72 |
+
if ( ! is_null( $thumb_obj ) ) {
|
73 |
+
if ( $thumb_obj->isSuccess() ) {
|
74 |
+
// icon has already been generated so include it in generated gallery
|
75 |
+
$thumb = $thumb_obj->getUrl();
|
76 |
+
}
|
77 |
} else {
|
78 |
// include a data-* attribute for client side to asynchronously request icon after gallery load
|
79 |
+
$data = 'data-id="' . $this->ID . '"';
|
80 |
}
|
81 |
}
|
82 |
|
83 |
+
if ( ! isset( $thumb ) ) {
|
84 |
$thumb = DG_Thumber::getDefaultThumbnail( $this->ID );
|
85 |
}
|
86 |
|
87 |
+
$repl = array( $this->link, $thumb, $this->title_attribute, $this->title, $target, $this->extension, $this->size, $this->path, $data );
|
88 |
+
$find = array( '%link%', '%img%', '%title_attribute%', '%title%', '%target%', '%extension%', '%size%', '%path%', '%data%' );
|
89 |
|
90 |
// if descriptions then add filterable tag and value to replaced tag
|
91 |
if ( $this->gallery->useDescriptions() ) {
|
95 |
}
|
96 |
|
97 |
$doc_icon =
|
98 |
+
' <div class="document-icon">' . PHP_EOL .
|
99 |
+
' <a href="%link%" target="%target%">' . PHP_EOL .
|
100 |
+
' <img src="%img%" title="%title_attribute%" alt="%title_attribute%" %data%/>' . PHP_EOL .
|
101 |
+
' <span class="title">%title%</span>' . PHP_EOL .
|
102 |
+
' </a>' . PHP_EOL .
|
103 |
' </div>' . PHP_EOL .
|
104 |
$description;
|
105 |
|
106 |
// allow developers to filter icon output
|
107 |
+
$doc_icon = apply_filters( 'dg_icon_template', $doc_icon, $this->gallery->useDescriptions(), $this->ID );
|
|
|
|
|
|
|
|
|
108 |
|
109 |
return str_replace( $find, $repl, $doc_icon );
|
110 |
}
|
inc/class-gallery-sanitization.php
ADDED
@@ -0,0 +1,496 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
defined( 'WPINC' ) OR exit;
|
3 |
+
|
4 |
+
DG_GallerySanitization::init();
|
5 |
+
|
6 |
+
/**
|
7 |
+
* Holds data specific to a given document gallery.
|
8 |
+
*
|
9 |
+
* @author drossiter
|
10 |
+
*/
|
11 |
+
class DG_GallerySanitization {
|
12 |
+
|
13 |
+
/*==========================================================================
|
14 |
+
* PRIVATE FIELDS
|
15 |
+
*=========================================================================*/
|
16 |
+
|
17 |
+
private static $unary_err, $binary_err;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @return string The unary error format string.
|
21 |
+
*/
|
22 |
+
public static function getUnaryErr() {
|
23 |
+
return self::$unary_err;
|
24 |
+
}
|
25 |
+
|
26 |
+
/**
|
27 |
+
* @return string The binary error format string.
|
28 |
+
*/
|
29 |
+
public static function getBinaryErr() {
|
30 |
+
return self::$binary_err;
|
31 |
+
}
|
32 |
+
|
33 |
+
/*==========================================================================
|
34 |
+
* INIT SANITIZATION
|
35 |
+
*=========================================================================*/
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Initializes static values for this class.
|
39 |
+
*/
|
40 |
+
public static function init() {
|
41 |
+
if ( ! isset( self::$unary_err ) ) {
|
42 |
+
self::$unary_err = __( 'The %s value entered, "%s", is not valid.', 'document-gallery' );
|
43 |
+
self::$binary_err = __( 'The %s parameter may only be "%s" or "%s." You entered "%s."', 'document-gallery' );
|
44 |
+
}
|
45 |
+
}
|
46 |
+
|
47 |
+
/*==========================================================================
|
48 |
+
* SANITIZATION
|
49 |
+
*=========================================================================*/
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Sanitize the given key/value pair, passing any error to $errs if given.
|
53 |
+
*
|
54 |
+
* @param string $key The key to reference the current value in the defaults array.
|
55 |
+
* @param mixed $value The value to be sanitized.
|
56 |
+
* @param array $errs The array of errors, which will be appended with any errors found.
|
57 |
+
*
|
58 |
+
* @return mixed The sanitized value, falling back to the current default value when invalid value given.
|
59 |
+
*/
|
60 |
+
public static function sanitizeParameter( $key, $value, &$errs = null ) {
|
61 |
+
// all sanitize methods must be in the following form: sanitize<UpperCamelCaseKey>
|
62 |
+
$funct = $key;
|
63 |
+
$funct[0] = strtoupper( $funct[0] );
|
64 |
+
$funct = 'sanitize' . preg_replace_callback( '/_([a-z])/', array( __CLASS__, 'secondCharToUpper' ), $funct );
|
65 |
+
|
66 |
+
$callable = array( __CLASS__, $funct );
|
67 |
+
|
68 |
+
// avoid looking for method beforehand unless we're running in debug mode -- expensive call
|
69 |
+
if ( DG_Logger::logEnabled() && ! method_exists( __CLASS__, $funct ) ) {
|
70 |
+
DG_Logger::writeLog(
|
71 |
+
DG_LogLevel::Error,
|
72 |
+
__( 'Attempted to call invalid function: ', 'document-gallery' ) . implode( '::', $callable ),
|
73 |
+
true );
|
74 |
+
}
|
75 |
+
|
76 |
+
// call param-specific sanitization
|
77 |
+
$ret = call_user_func_array( $callable, array( $value, &$err ) );
|
78 |
+
|
79 |
+
// check for error and return default
|
80 |
+
if ( isset( $err ) ) {
|
81 |
+
$defaults = DG_Gallery::getOptions();
|
82 |
+
$ret = $defaults[ $key ];
|
83 |
+
|
84 |
+
if ( ! is_null($errs) ) {
|
85 |
+
$errs[ $key ] = $err;
|
86 |
+
}
|
87 |
+
}
|
88 |
+
|
89 |
+
return $ret;
|
90 |
+
}
|
91 |
+
|
92 |
+
/**
|
93 |
+
* Takes the provided value and returns a sanitized value.
|
94 |
+
*
|
95 |
+
* @param string $value The attachment_pg value to be sanitized.
|
96 |
+
* @param string &$err String to be initialized with error, if any.
|
97 |
+
*
|
98 |
+
* @return bool The sanitized attachment_pg value.
|
99 |
+
*/
|
100 |
+
private static function sanitizeAttachmentPg( $value, &$err ) {
|
101 |
+
$ret = DG_Util::toBool( $value );
|
102 |
+
|
103 |
+
if ( is_null( $ret ) ) {
|
104 |
+
$err = sprintf( self::$binary_err, 'attachment_pg', 'true', 'false', $value );
|
105 |
+
}
|
106 |
+
|
107 |
+
return $ret;
|
108 |
+
}
|
109 |
+
|
110 |
+
/**
|
111 |
+
* Takes the provided value and returns a sanitized value.
|
112 |
+
*
|
113 |
+
* @param string $value The columns value to be sanitized.
|
114 |
+
* @param string &$err String to be initialized with error, if any.
|
115 |
+
*
|
116 |
+
* @return int The sanitized columns value.
|
117 |
+
*/
|
118 |
+
public static function sanitizeColumns( $value, &$err ) {
|
119 |
+
return $value != -1 ? absint( $value ) : null;
|
120 |
+
}
|
121 |
+
|
122 |
+
/**
|
123 |
+
* Takes the provided value and returns a sanitized value.
|
124 |
+
*
|
125 |
+
* @param string $value The descriptions value to be sanitized.
|
126 |
+
* @param string &$err String to be initialized with error, if any.
|
127 |
+
*
|
128 |
+
* @return bool The sanitized descriptions value.
|
129 |
+
*/
|
130 |
+
private static function sanitizeDescriptions( $value, &$err ) {
|
131 |
+
$ret = DG_Util::toBool( $value );
|
132 |
+
|
133 |
+
if ( is_null( $ret ) ) {
|
134 |
+
$err = sprintf( self::$binary_err, 'descriptions', 'true', 'false', $value );
|
135 |
+
}
|
136 |
+
|
137 |
+
return $ret;
|
138 |
+
}
|
139 |
+
|
140 |
+
/**
|
141 |
+
* Takes the provided value and returns a sanitized value.
|
142 |
+
*
|
143 |
+
* @param string $value The exclude value to be sanitized.
|
144 |
+
* @param string &$err String to be initialized with error, if any.
|
145 |
+
*
|
146 |
+
* @return bool The sanitized exclude value.
|
147 |
+
*/
|
148 |
+
private static function sanitizeExclude( $value, &$err ) {
|
149 |
+
return self::sanitizeIdList( 'Exclude', $value, $err );
|
150 |
+
}
|
151 |
+
|
152 |
+
/**
|
153 |
+
* Takes the provided value and returns a sanitized value.
|
154 |
+
*
|
155 |
+
* @param string $value The fancy value to be sanitized.
|
156 |
+
* @param string &$err String to be initialized with error, if any.
|
157 |
+
*
|
158 |
+
* @return bool The sanitized fancy value.
|
159 |
+
*/
|
160 |
+
private static function sanitizeFancy( $value, &$err ) {
|
161 |
+
$ret = DG_Util::toBool( $value );
|
162 |
+
|
163 |
+
if ( is_null( $ret ) ) {
|
164 |
+
$err = sprintf( self::$binary_err, 'fancy', 'true', 'false', $value );
|
165 |
+
}
|
166 |
+
|
167 |
+
return $ret;
|
168 |
+
}
|
169 |
+
|
170 |
+
/**
|
171 |
+
* Takes the provided value and returns a sanitized value.
|
172 |
+
*
|
173 |
+
* @param string $value The id value to be sanitized.
|
174 |
+
* @param string &$err String to be initialized with error, if any.
|
175 |
+
*
|
176 |
+
* @return int The sanitized id value.
|
177 |
+
*/
|
178 |
+
private static function sanitizeId( $value, &$err ) {
|
179 |
+
return $value != -1 ? absint( $value ) : null;
|
180 |
+
}
|
181 |
+
|
182 |
+
/**
|
183 |
+
* Takes the provided comma-delimited list of IDs and returns null if it is invalid.
|
184 |
+
*
|
185 |
+
* @param string $name Name of the value being sanitized. Used in error string when needed.
|
186 |
+
* @param string $value The ids value to be sanitized.
|
187 |
+
* @param string &$err String to be initialized with error, if any.
|
188 |
+
*
|
189 |
+
* @return bool|multitype:int The sanitized comma-delimited list of IDs value.
|
190 |
+
*/
|
191 |
+
private static function sanitizeIdList( $name, $value, &$err ) {
|
192 |
+
static $regex = '/(?:|\d+(?:,\d+)*)/';
|
193 |
+
|
194 |
+
$ret = $value;
|
195 |
+
|
196 |
+
if ( ! preg_match( $regex, $value ) ) {
|
197 |
+
$err = sprintf( __( '%s may only be a comma-delimited list of integers.', 'document-gallery' ), $name );
|
198 |
+
$ret = null;
|
199 |
+
}
|
200 |
+
|
201 |
+
return $ret;
|
202 |
+
}
|
203 |
+
|
204 |
+
/**
|
205 |
+
* Takes the provided value and returns a sanitized value.
|
206 |
+
*
|
207 |
+
* @param string $value The ids value to be sanitized.
|
208 |
+
* @param string &$err String to be initialized with error, if any.
|
209 |
+
*
|
210 |
+
* @return bool|multitype:int The sanitized ids value.
|
211 |
+
*/
|
212 |
+
private static function sanitizeInclude( $value, &$err ) {
|
213 |
+
return self::sanitizeIdList( 'Include', $value, $err );
|
214 |
+
}
|
215 |
+
|
216 |
+
/**
|
217 |
+
* Takes the provided value and returns a sanitized value.
|
218 |
+
*
|
219 |
+
* @param string $value The limit value to be sanitized.
|
220 |
+
* @param string &$err String to be initialized with error, if any.
|
221 |
+
*
|
222 |
+
* @return int The sanitized limit value.
|
223 |
+
*/
|
224 |
+
private static function sanitizeLimit( $value, &$err ) {
|
225 |
+
$ret = intval( $value );
|
226 |
+
|
227 |
+
if ( is_null( $ret ) || $ret < -1 ) {
|
228 |
+
$err = sprintf( self::$unary_err, 'limit', '>= -1' );
|
229 |
+
$ret = null;
|
230 |
+
}
|
231 |
+
|
232 |
+
return $ret;
|
233 |
+
}
|
234 |
+
|
235 |
+
/**
|
236 |
+
* Takes the provided value and returns a sanitized value.
|
237 |
+
*
|
238 |
+
* @param string $value The mime_types value to be sanitized.
|
239 |
+
* @param string &$err String to be initialized with error, if any.
|
240 |
+
*
|
241 |
+
* @return string The sanitized mime_types value.
|
242 |
+
*/
|
243 |
+
private static function sanitizeMimeTypes( $value, &$err ) {
|
244 |
+
// TODO: do some actual sanitization...
|
245 |
+
return $value;
|
246 |
+
}
|
247 |
+
|
248 |
+
/**
|
249 |
+
* Takes the provided value and returns a sanitized value.
|
250 |
+
*
|
251 |
+
* @param string $value The new_window value to be sanitized.
|
252 |
+
* @param string &$err String to be initialized with error, if any.
|
253 |
+
*
|
254 |
+
* @return bool The sanitized new_window value.
|
255 |
+
*/
|
256 |
+
private static function sanitizeNewWindow( $value, &$err ) {
|
257 |
+
$ret = DG_Util::toBool( $value );
|
258 |
+
|
259 |
+
if ( is_null( $ret ) ) {
|
260 |
+
$err = sprintf( self::$binary_err, 'new_window', 'true', 'false', $value );
|
261 |
+
}
|
262 |
+
|
263 |
+
return $ret;
|
264 |
+
}
|
265 |
+
|
266 |
+
/**
|
267 |
+
* Takes the provided value and returns a sanitized value.
|
268 |
+
*
|
269 |
+
* @param string $value The order value to be sanitized.
|
270 |
+
* @param string &$err String to be initialized with error, if any.
|
271 |
+
*
|
272 |
+
* @return string The sanitized order value.
|
273 |
+
*/
|
274 |
+
private static function sanitizeOrder( $value, &$err ) {
|
275 |
+
$ret = strtoupper( $value );
|
276 |
+
|
277 |
+
if ( ! in_array( $ret, self::getOrderOptions() ) ) {
|
278 |
+
$err = sprintf( self::$binary_err, 'order', 'ASC', 'DESC', $value );
|
279 |
+
$ret = null;
|
280 |
+
}
|
281 |
+
|
282 |
+
return $ret;
|
283 |
+
}
|
284 |
+
|
285 |
+
/**
|
286 |
+
* @return array The valid options for order parameter.
|
287 |
+
*/
|
288 |
+
public static function getOrderOptions() {
|
289 |
+
return array( 'ASC', 'DESC' );
|
290 |
+
}
|
291 |
+
|
292 |
+
/**
|
293 |
+
* Takes the provided value and returns a sanitized value.
|
294 |
+
*
|
295 |
+
* @param string $value The orderby value to be sanitized.
|
296 |
+
* @param string &$err String to be initialized with error, if any.
|
297 |
+
*
|
298 |
+
* @return string The sanitized orderby value.
|
299 |
+
*/
|
300 |
+
private static function sanitizeOrderby( $value, &$err ) {
|
301 |
+
$ret = ( 'ID' === strtoupper( $value ) ) ? 'ID' : strtolower( $value );
|
302 |
+
|
303 |
+
if ( ! in_array( $ret, self::getOrderbyOptions() ) ) {
|
304 |
+
$err = sprintf( self::$unary_err, 'orderby', $value );
|
305 |
+
$ret = null;
|
306 |
+
}
|
307 |
+
|
308 |
+
return $ret;
|
309 |
+
}
|
310 |
+
|
311 |
+
/**
|
312 |
+
* @return array The valid options for orderby parameter.
|
313 |
+
*/
|
314 |
+
public static function getOrderbyOptions() {
|
315 |
+
return array(
|
316 |
+
'author',
|
317 |
+
'comment_count',
|
318 |
+
'date',
|
319 |
+
'ID',
|
320 |
+
'menu_order',
|
321 |
+
'modified',
|
322 |
+
'name',
|
323 |
+
'none',
|
324 |
+
'parent',
|
325 |
+
'post__in',
|
326 |
+
'rand',
|
327 |
+
'title'
|
328 |
+
);
|
329 |
+
}
|
330 |
+
|
331 |
+
/**
|
332 |
+
* Takes the provided value and returns a sanitized value.
|
333 |
+
*
|
334 |
+
* @param string $value The paginate value to be sanitized.
|
335 |
+
* @param string &$err String to be initialized with error, if any.
|
336 |
+
*
|
337 |
+
* @return string The sanitized paginate value.
|
338 |
+
*/
|
339 |
+
private static function sanitizePaginate( $value, &$err ) {
|
340 |
+
$ret = DG_Util::toBool( $value );
|
341 |
+
|
342 |
+
if ( is_null( $ret ) ) {
|
343 |
+
$err = sprintf( self::$binary_err, 'paginate', 'true', 'false', $value );
|
344 |
+
}
|
345 |
+
|
346 |
+
return $ret;
|
347 |
+
}
|
348 |
+
|
349 |
+
/**
|
350 |
+
* Takes the provided value and returns a sanitized value.
|
351 |
+
*
|
352 |
+
* @param string $value The post_status value to be sanitized.
|
353 |
+
* @param string &$err String to be initialized with error, if any.
|
354 |
+
*
|
355 |
+
* @return string The sanitized post_status value.
|
356 |
+
*/
|
357 |
+
private static function sanitizePostStatus( $value, &$err ) {
|
358 |
+
$ret = preg_grep( '/^' . preg_quote( $value ) . '$/i', self::getPostStatuses() );
|
359 |
+
$ret = reset( $ret );
|
360 |
+
|
361 |
+
if ( $ret === false ) {
|
362 |
+
$err = sprintf( self::$unary_err, 'post_status', $value );
|
363 |
+
}
|
364 |
+
|
365 |
+
return $ret;
|
366 |
+
}
|
367 |
+
|
368 |
+
/**
|
369 |
+
* @return array All registered post statuses.
|
370 |
+
*/
|
371 |
+
public static function getPostStatuses() {
|
372 |
+
static $statuses;
|
373 |
+
if ( ! isset( $statuses ) ) {
|
374 |
+
$statuses = get_post_stati();
|
375 |
+
$statuses[] = 'any';
|
376 |
+
asort( $statuses );
|
377 |
+
}
|
378 |
+
|
379 |
+
return $statuses;
|
380 |
+
}
|
381 |
+
|
382 |
+
/**
|
383 |
+
* Takes the provided value and returns a sanitized value.
|
384 |
+
*
|
385 |
+
* @param string $value The post_type value to be sanitized.
|
386 |
+
* @param string &$err String to be initialized with error, if any.
|
387 |
+
*
|
388 |
+
* @return string The sanitized post_type value.
|
389 |
+
*/
|
390 |
+
private static function sanitizePostType( $value, &$err ) {
|
391 |
+
$ret = preg_grep( '/^' . preg_quote( $value ) . '$/i', self::getPostTypes() );
|
392 |
+
$ret = reset( $ret );
|
393 |
+
|
394 |
+
if ( $ret === false ) {
|
395 |
+
$err = sprintf( self::$unary_err, 'post_type', $value );
|
396 |
+
}
|
397 |
+
|
398 |
+
return $ret;
|
399 |
+
}
|
400 |
+
|
401 |
+
/**
|
402 |
+
* @return array All registered post types.
|
403 |
+
*/
|
404 |
+
public static function getPostTypes() {
|
405 |
+
static $types;
|
406 |
+
if ( ! isset( $types ) ) {
|
407 |
+
$types = get_post_types();
|
408 |
+
$types[] = 'any';
|
409 |
+
asort( $types );
|
410 |
+
}
|
411 |
+
|
412 |
+
return $types;
|
413 |
+
}
|
414 |
+
|
415 |
+
/**
|
416 |
+
* Takes the provided value and returns a sanitized value.
|
417 |
+
*
|
418 |
+
* @param string $value The relation value to be sanitized.
|
419 |
+
* @param string &$err String to be initialized with error, if any.
|
420 |
+
*
|
421 |
+
* @return string The sanitized relation value.
|
422 |
+
*/
|
423 |
+
private static function sanitizeRelation( $value, &$err ) {
|
424 |
+
$ret = strtoupper( $value );
|
425 |
+
|
426 |
+
if ( ! in_array( $ret, self::getRelationOptions() ) ) {
|
427 |
+
$err = sprintf( self::$binary_err, 'relation', 'AND', 'OR', $value );
|
428 |
+
$ret = null;
|
429 |
+
}
|
430 |
+
|
431 |
+
return $ret;
|
432 |
+
}
|
433 |
+
|
434 |
+
/**
|
435 |
+
* @return array The valid options for relation parameter.
|
436 |
+
*/
|
437 |
+
public static function getRelationOptions() {
|
438 |
+
return array( 'AND', 'OR' );
|
439 |
+
}
|
440 |
+
|
441 |
+
/**
|
442 |
+
* Takes the provided value and returns a sanitized value.
|
443 |
+
*
|
444 |
+
* @param string $value The skip value to be sanitized.
|
445 |
+
* @param string &$err String to be initialized with error, if any.
|
446 |
+
*
|
447 |
+
* @return string The sanitized skip value.
|
448 |
+
*/
|
449 |
+
private static function sanitizeSkip( $value, &$err ) {
|
450 |
+
$ret = intval( $value );
|
451 |
+
|
452 |
+
if ( is_null( $ret ) || $ret < 0 ) {
|
453 |
+
$err = sprintf( self::$unary_err, 'skip', '>= 0' );
|
454 |
+
$ret = null;
|
455 |
+
}
|
456 |
+
|
457 |
+
return $ret;
|
458 |
+
}
|
459 |
+
|
460 |
+
/**
|
461 |
+
* Takes the provided value and returns a sanitized value.
|
462 |
+
*
|
463 |
+
* @param string $operator The operator value to be sanitized.
|
464 |
+
* @param string &$err String to be initialized with error, if any.
|
465 |
+
*
|
466 |
+
* @return string The sanitized operator value.
|
467 |
+
*/
|
468 |
+
private static function sanitizeOperator( $operator, &$err ) {
|
469 |
+
$ret = strtoupper( $operator );
|
470 |
+
|
471 |
+
if ( ! in_array( $ret, self::getOperatorOptions() ) ) {
|
472 |
+
$err = sprintf( self::$binary_err, 'IN", "NOT IN", "OR', 'AND', $operator );
|
473 |
+
$ret = null;
|
474 |
+
} else if ( $ret === 'OR' ) {
|
475 |
+
$ret = 'IN';
|
476 |
+
}
|
477 |
+
|
478 |
+
return $ret;
|
479 |
+
}
|
480 |
+
|
481 |
+
/**
|
482 |
+
* @return array The valid options for *_relation/*_operator parameter.
|
483 |
+
*/
|
484 |
+
public static function getOperatorOptions() {
|
485 |
+
return array( 'IN', 'NOT IN', 'AND', 'OR' );
|
486 |
+
}
|
487 |
+
|
488 |
+
/**
|
489 |
+
* @param string $string To take second char from.
|
490 |
+
*
|
491 |
+
* @return string Capitalized second char of given string.
|
492 |
+
*/
|
493 |
+
private static function secondCharToUpper( $string ) {
|
494 |
+
return strtoupper( $string[1] );
|
495 |
+
}
|
496 |
+
}
|
inc/class-gallery.php
CHANGED
@@ -1,6 +1,8 @@
|
|
1 |
<?php
|
2 |
defined( 'WPINC' ) OR exit;
|
3 |
|
|
|
|
|
4 |
DG_Gallery::init();
|
5 |
|
6 |
/**
|
@@ -11,19 +13,22 @@ DG_Gallery::init();
|
|
11 |
class DG_Gallery {
|
12 |
|
13 |
/*==========================================================================
|
14 |
-
|
15 |
-
|
16 |
|
17 |
private $atts, $taxa;
|
18 |
private $docs = array();
|
19 |
private $errs = array();
|
20 |
|
|
|
|
|
|
|
21 |
// templates for HTML output
|
22 |
-
private static $no_docs, $comment, $
|
23 |
|
24 |
/*==========================================================================
|
25 |
-
|
26 |
-
|
27 |
|
28 |
/**
|
29 |
* @return bool Whether to link to attachment pg.
|
@@ -54,8 +59,8 @@ class DG_Gallery {
|
|
54 |
}
|
55 |
|
56 |
/*==========================================================================
|
57 |
-
|
58 |
-
|
59 |
|
60 |
/**
|
61 |
* @param int $blog The blog we're retrieving options for (null => current blog).
|
@@ -79,20 +84,19 @@ class DG_Gallery {
|
|
79 |
}
|
80 |
|
81 |
/*==========================================================================
|
82 |
-
|
83 |
-
|
84 |
|
85 |
/**
|
86 |
* Initializes static values for this class.
|
87 |
*/
|
88 |
public static function init() {
|
89 |
if ( ! isset( self::$comment ) ) {
|
90 |
-
self::$comment
|
91 |
PHP_EOL . '<!-- ' . __( 'Generated using Document Gallery. Get yours here: ', 'document-gallery' ) .
|
92 |
'http://wordpress.org/extend/plugins/document-gallery -->' . PHP_EOL;
|
93 |
-
self::$no_docs
|
94 |
-
self::$
|
95 |
-
self::$binary_err = __( 'The %s parameter may only be "%s" or "%s." You entered "%s."', 'document-gallery' );
|
96 |
}
|
97 |
}
|
98 |
|
@@ -104,11 +108,13 @@ class DG_Gallery {
|
|
104 |
public function __construct( $atts ) {
|
105 |
include_once DG_PATH . 'inc/class-document.php';
|
106 |
|
107 |
-
$post = get_post();
|
108 |
-
|
109 |
// empty string is passed when no arguments are given, but constructor expects an array
|
110 |
$atts = empty( $atts ) ? array() : $atts;
|
111 |
|
|
|
|
|
|
|
|
|
112 |
if ( ! empty( $atts['ids'] ) ) {
|
113 |
// 'ids' is explicitly ordered, unless you specify otherwise.
|
114 |
if ( empty( $atts['orderby'] ) ) {
|
@@ -141,14 +147,11 @@ class DG_Gallery {
|
|
141 |
* @deprecated localpost will be removed at some point.
|
142 |
*/
|
143 |
if ( ! empty( $atts['localpost'] ) ) {
|
144 |
-
$atts['id'] = -
|
145 |
unset( $atts['localpost'] );
|
146 |
}
|
147 |
|
148 |
-
|
149 |
-
$defaults = array_merge(
|
150 |
-
array( 'id' => $post->ID, 'include' => '', 'exclude' => '' ),
|
151 |
-
self::getOptions() );
|
152 |
|
153 |
// values used to construct tax query (may be empty)
|
154 |
$this->taxa = array_diff_key( $atts, $defaults );
|
@@ -200,409 +203,13 @@ class DG_Gallery {
|
|
200 |
}
|
201 |
} else if ( $sanitized[ $k ] !== $v ) { //Sometimes we get boolean in the string form for checkboxes
|
202 |
// sanitize value if different from old value
|
203 |
-
$sanitized[ $k ] =
|
204 |
}
|
205 |
}
|
206 |
|
207 |
return $sanitized;
|
208 |
}
|
209 |
|
210 |
-
/**
|
211 |
-
*
|
212 |
-
* @param string $key The key to reference the current value in the defaults array.
|
213 |
-
* @param mixed $value The value to be sanitized.
|
214 |
-
* @param array $errs The array of errors, which will be appended with any errors found.
|
215 |
-
*
|
216 |
-
* @return mixed The sanitized value, falling back to the current default value when invalid value given.
|
217 |
-
*/
|
218 |
-
private static function sanitizeParameter( $key, $value, &$errs ) {
|
219 |
-
// all sanitize methods must be in the following form: sanitize<UpperCammelCaseKey>
|
220 |
-
$funct = $key;
|
221 |
-
$funct[0] = strtoupper( $funct[0] );
|
222 |
-
$funct = 'sanitize' . preg_replace_callback( '/_([a-z])/', array( __CLASS__, 'secondCharToUpper' ), $funct );
|
223 |
-
|
224 |
-
$callable = array( __CLASS__, $funct );
|
225 |
-
|
226 |
-
// avoid looking for method beforehand unless we're running in debug mode -- expensive call
|
227 |
-
if ( DG_Logger::logEnabled() && ! method_exists( __CLASS__, $funct ) ) {
|
228 |
-
DG_Logger::writeLog(
|
229 |
-
DG_LogLevel::Error,
|
230 |
-
__( 'Attempted to call invalid function: ', 'document-gallery' ) . implode( '::', $callable ),
|
231 |
-
true );
|
232 |
-
}
|
233 |
-
|
234 |
-
// call param-specific sanitization
|
235 |
-
$ret = call_user_func_array( $callable, array( $value, &$err ) );
|
236 |
-
|
237 |
-
// check for error and return default
|
238 |
-
if ( isset( $err ) ) {
|
239 |
-
$defaults = self::getOptions();
|
240 |
-
$ret = $defaults[ $key ];
|
241 |
-
|
242 |
-
$errs[ $key ] = $err;
|
243 |
-
}
|
244 |
-
|
245 |
-
return $ret;
|
246 |
-
}
|
247 |
-
|
248 |
-
/**
|
249 |
-
* Takes the provided value and returns a sanitized value.
|
250 |
-
*
|
251 |
-
* @param string $value The attachment_pg value to be sanitized.
|
252 |
-
* @param string &$err String to be initialized with error, if any.
|
253 |
-
*
|
254 |
-
* @return bool The sanitized attachment_pg value.
|
255 |
-
*/
|
256 |
-
private static function sanitizeAttachmentPg( $value, &$err ) {
|
257 |
-
$ret = DG_Util::toBool( $value );
|
258 |
-
|
259 |
-
if ( is_null( $ret ) ) {
|
260 |
-
$err = sprintf( self::$binary_err, 'attachment_pg', 'true', 'false', $value );
|
261 |
-
}
|
262 |
-
|
263 |
-
return $ret;
|
264 |
-
}
|
265 |
-
|
266 |
-
/**
|
267 |
-
* Takes the provided value and returns a sanitized value.
|
268 |
-
*
|
269 |
-
* @param string $value The columns value to be sanitized.
|
270 |
-
* @param string &$err String to be initialized with error, if any.
|
271 |
-
*
|
272 |
-
* @return int The sanitized columns value.
|
273 |
-
*/
|
274 |
-
public static function sanitizeColumns( $value, &$err ) {
|
275 |
-
return $value != - 1 ? absint( $value ) : null;
|
276 |
-
}
|
277 |
-
|
278 |
-
/**
|
279 |
-
* Takes the provided value and returns a sanitized value.
|
280 |
-
*
|
281 |
-
* @param string $value The descriptions value to be sanitized.
|
282 |
-
* @param string &$err String to be initialized with error, if any.
|
283 |
-
*
|
284 |
-
* @return bool The sanitized descriptions value.
|
285 |
-
*/
|
286 |
-
private static function sanitizeDescriptions( $value, &$err ) {
|
287 |
-
$ret = DG_Util::toBool( $value );
|
288 |
-
|
289 |
-
if ( is_null( $ret ) ) {
|
290 |
-
$err = sprintf( self::$binary_err, 'descriptions', 'true', 'false', $value );
|
291 |
-
}
|
292 |
-
|
293 |
-
return $ret;
|
294 |
-
}
|
295 |
-
|
296 |
-
/**
|
297 |
-
* Takes the provided value and returns a sanitized value.
|
298 |
-
*
|
299 |
-
* @param string $value The exclude value to be sanitized.
|
300 |
-
* @param string &$err String to be initialized with error, if any.
|
301 |
-
*
|
302 |
-
* @return bool The sanitized exclude value.
|
303 |
-
*/
|
304 |
-
private static function sanitizeExclude( $value, &$err ) {
|
305 |
-
return self::sanitizeIdList( 'Exclude', $value, $err );
|
306 |
-
}
|
307 |
-
|
308 |
-
/**
|
309 |
-
* Takes the provided value and returns a sanitized value.
|
310 |
-
*
|
311 |
-
* @param string $value The fancy value to be sanitized.
|
312 |
-
* @param string &$err String to be initialized with error, if any.
|
313 |
-
*
|
314 |
-
* @return bool The sanitized fancy value.
|
315 |
-
*/
|
316 |
-
private static function sanitizeFancy( $value, &$err ) {
|
317 |
-
$ret = DG_Util::toBool( $value );
|
318 |
-
|
319 |
-
if ( is_null( $ret ) ) {
|
320 |
-
$err = sprintf( self::$binary_err, 'fancy', 'true', 'false', $value );
|
321 |
-
}
|
322 |
-
|
323 |
-
return $ret;
|
324 |
-
}
|
325 |
-
|
326 |
-
/**
|
327 |
-
* Takes the provided value and returns a sanitized value.
|
328 |
-
*
|
329 |
-
* @param string $value The id value to be sanitized.
|
330 |
-
* @param string &$err String to be initialized with error, if any.
|
331 |
-
*
|
332 |
-
* @return int The sanitized id value.
|
333 |
-
*/
|
334 |
-
private static function sanitizeId( $value, &$err ) {
|
335 |
-
return $value != - 1 ? absint( $value ) : null;
|
336 |
-
}
|
337 |
-
|
338 |
-
/**
|
339 |
-
* Takes the provided comma-delimited list of IDs and returns null if it is invalid.
|
340 |
-
*
|
341 |
-
* @param string $name Name of the value being sanitized. Used in error string when needed.
|
342 |
-
* @param string $value The ids value to be sanitized.
|
343 |
-
* @param string &$err String to be initialized with error, if any.
|
344 |
-
*
|
345 |
-
* @return bool|multitype:int The sanitized comma-delimited list of IDs value.
|
346 |
-
*/
|
347 |
-
private static function sanitizeIdList( $name, $value, &$err ) {
|
348 |
-
static $regex = '/(?:|\d+(?:,\d+)*)/';
|
349 |
-
|
350 |
-
$ret = $value;
|
351 |
-
|
352 |
-
if ( ! preg_match( $regex, $value ) ) {
|
353 |
-
$err = sprintf( __( '%s may only be a comma-delimited list of integers.', 'document-gallery' ), $name );
|
354 |
-
$ret = null;
|
355 |
-
}
|
356 |
-
|
357 |
-
return $ret;
|
358 |
-
}
|
359 |
-
|
360 |
-
/**
|
361 |
-
* Takes the provided value and returns a sanitized value.
|
362 |
-
*
|
363 |
-
* @param string $value The ids value to be sanitized.
|
364 |
-
* @param string &$err String to be initialized with error, if any.
|
365 |
-
*
|
366 |
-
* @return bool|multitype:int The sanitized ids value.
|
367 |
-
*/
|
368 |
-
private static function sanitizeInclude( $value, &$err ) {
|
369 |
-
return self::sanitizeIdList( 'Include', $value, $err );
|
370 |
-
}
|
371 |
-
|
372 |
-
/**
|
373 |
-
* Takes the provided value and returns a sanitized value.
|
374 |
-
*
|
375 |
-
* @param string $value The limit value to be sanitized.
|
376 |
-
* @param string &$err String to be initialized with error, if any.
|
377 |
-
*
|
378 |
-
* @return int The sanitized limit value.
|
379 |
-
*/
|
380 |
-
private static function sanitizeLimit( $value, &$err ) {
|
381 |
-
$ret = intval( $value );
|
382 |
-
|
383 |
-
if ( is_null( $ret ) || $ret < - 1 ) {
|
384 |
-
$err = sprintf( self::$unary_err, 'limit', '>= -1' );
|
385 |
-
$ret = null;
|
386 |
-
}
|
387 |
-
|
388 |
-
return $ret;
|
389 |
-
}
|
390 |
-
|
391 |
-
/**
|
392 |
-
* Takes the provided value and returns a sanitized value.
|
393 |
-
*
|
394 |
-
* @param string $value The mime_types value to be sanitized.
|
395 |
-
* @param string &$err String to be initialized with error, if any.
|
396 |
-
*
|
397 |
-
* @return string The sanitized mime_types value.
|
398 |
-
*/
|
399 |
-
private static function sanitizeMimeTypes( $value, &$err ) {
|
400 |
-
// TODO: do some actual sanitization...
|
401 |
-
return $value;
|
402 |
-
}
|
403 |
-
|
404 |
-
/**
|
405 |
-
* Takes the provided value and returns a sanitized value.
|
406 |
-
*
|
407 |
-
* @param string $value The new_window value to be sanitized.
|
408 |
-
* @param string &$err String to be initialized with error, if any.
|
409 |
-
*
|
410 |
-
* @return bool The sanitized new_window value.
|
411 |
-
*/
|
412 |
-
private static function sanitizeNewWindow( $value, &$err ) {
|
413 |
-
$ret = DG_Util::toBool( $value );
|
414 |
-
|
415 |
-
if ( is_null( $ret ) ) {
|
416 |
-
$err = sprintf( self::$binary_err, 'new_window', 'true', 'false', $value );
|
417 |
-
}
|
418 |
-
|
419 |
-
return $ret;
|
420 |
-
}
|
421 |
-
|
422 |
-
/**
|
423 |
-
* Takes the provided value and returns a sanitized value.
|
424 |
-
*
|
425 |
-
* @param string $value The order value to be sanitized.
|
426 |
-
* @param string &$err String to be initialized with error, if any.
|
427 |
-
*
|
428 |
-
* @return string The sanitized order value.
|
429 |
-
*/
|
430 |
-
private static function sanitizeOrder( $value, &$err ) {
|
431 |
-
$ret = strtoupper( $value );
|
432 |
-
|
433 |
-
if ( ! in_array( $ret, self::getOrderOptions() ) ) {
|
434 |
-
$err = sprintf( self::$binary_err, 'order', 'ASC', 'DESC', $value );
|
435 |
-
$ret = null;
|
436 |
-
}
|
437 |
-
|
438 |
-
return $ret;
|
439 |
-
}
|
440 |
-
|
441 |
-
/**
|
442 |
-
* @return array The valid options for order parameter.
|
443 |
-
*/
|
444 |
-
public static function getOrderOptions() {
|
445 |
-
return array( 'ASC', 'DESC' );
|
446 |
-
}
|
447 |
-
|
448 |
-
/**
|
449 |
-
* Takes the provided value and returns a sanitized value.
|
450 |
-
*
|
451 |
-
* @param string $value The orderby value to be sanitized.
|
452 |
-
* @param string &$err String to be initialized with error, if any.
|
453 |
-
*
|
454 |
-
* @return string The sanitized orderby value.
|
455 |
-
*/
|
456 |
-
private static function sanitizeOrderby( $value, &$err ) {
|
457 |
-
$ret = ( 'ID' === strtoupper( $value ) ) ? 'ID' : strtolower( $value );
|
458 |
-
|
459 |
-
if ( ! in_array( $ret, self::getOrderbyOptions() ) ) {
|
460 |
-
$err = sprintf( self::$unary_err, 'orderby', $value );
|
461 |
-
$ret = null;
|
462 |
-
}
|
463 |
-
|
464 |
-
return $ret;
|
465 |
-
}
|
466 |
-
|
467 |
-
/**
|
468 |
-
* @return array The valid options for orderby parameter.
|
469 |
-
*/
|
470 |
-
public static function getOrderbyOptions() {
|
471 |
-
return array(
|
472 |
-
'author',
|
473 |
-
'comment_count',
|
474 |
-
'date',
|
475 |
-
'ID',
|
476 |
-
'menu_order',
|
477 |
-
'modified',
|
478 |
-
'name',
|
479 |
-
'none',
|
480 |
-
'parent',
|
481 |
-
'post__in',
|
482 |
-
'rand',
|
483 |
-
'title'
|
484 |
-
);
|
485 |
-
}
|
486 |
-
|
487 |
-
/**
|
488 |
-
* Takes the provided value and returns a sanitized value.
|
489 |
-
*
|
490 |
-
* @param string $value The post_status value to be sanitized.
|
491 |
-
* @param string &$err String to be initialized with error, if any.
|
492 |
-
*
|
493 |
-
* @return string The sanitized post_status value.
|
494 |
-
*/
|
495 |
-
private static function sanitizePostStatus( $value, &$err ) {
|
496 |
-
$ret = preg_grep( '/^' . preg_quote( $value ) . '$/i', self::getPostStatuses() );
|
497 |
-
$ret = reset( $ret );
|
498 |
-
|
499 |
-
if ( $ret === false ) {
|
500 |
-
$err = sprintf( self::$unary_err, 'post_status', $value );
|
501 |
-
}
|
502 |
-
|
503 |
-
return $ret;
|
504 |
-
}
|
505 |
-
|
506 |
-
/**
|
507 |
-
* @return array All registered post statuses.
|
508 |
-
*/
|
509 |
-
public static function getPostStatuses() {
|
510 |
-
static $statuses;
|
511 |
-
if ( ! isset( $statuses ) ) {
|
512 |
-
$statuses = get_post_stati();
|
513 |
-
$statuses[] = 'any';
|
514 |
-
asort( $statuses );
|
515 |
-
}
|
516 |
-
|
517 |
-
return $statuses;
|
518 |
-
}
|
519 |
-
|
520 |
-
/**
|
521 |
-
* Takes the provided value and returns a sanitized value.
|
522 |
-
*
|
523 |
-
* @param string $value The post_type value to be sanitized.
|
524 |
-
* @param string &$err String to be initialized with error, if any.
|
525 |
-
*
|
526 |
-
* @return string The sanitized post_type value.
|
527 |
-
*/
|
528 |
-
private static function sanitizePostType( $value, &$err ) {
|
529 |
-
$ret = preg_grep( '/^' . preg_quote( $value ) . '$/i', self::getPostTypes() );
|
530 |
-
$ret = reset( $ret );
|
531 |
-
|
532 |
-
if ( $ret === false ) {
|
533 |
-
$err = sprintf( self::$unary_err, 'post_type', $value );
|
534 |
-
}
|
535 |
-
|
536 |
-
return $ret;
|
537 |
-
}
|
538 |
-
|
539 |
-
/**
|
540 |
-
* @return array All registered post types.
|
541 |
-
*/
|
542 |
-
public static function getPostTypes() {
|
543 |
-
static $types;
|
544 |
-
if ( ! isset( $types ) ) {
|
545 |
-
$types = get_post_types();
|
546 |
-
$types[] = 'any';
|
547 |
-
asort( $types );
|
548 |
-
}
|
549 |
-
|
550 |
-
return $types;
|
551 |
-
}
|
552 |
-
|
553 |
-
/**
|
554 |
-
* Takes the provided value and returns a sanitized value.
|
555 |
-
*
|
556 |
-
* @param string $value The relation value to be sanitized.
|
557 |
-
* @param string &$err String to be initialized with error, if any.
|
558 |
-
*
|
559 |
-
* @return string The sanitized relation value.
|
560 |
-
*/
|
561 |
-
private static function sanitizeRelation( $value, &$err ) {
|
562 |
-
$ret = strtoupper( $value );
|
563 |
-
|
564 |
-
if ( ! in_array( $ret, self::getRelationOptions() ) ) {
|
565 |
-
$err = sprintf( self::$binary_err, 'relation', 'AND', 'OR', $value );
|
566 |
-
$ret = null;
|
567 |
-
}
|
568 |
-
|
569 |
-
return $ret;
|
570 |
-
}
|
571 |
-
|
572 |
-
/**
|
573 |
-
* @return array The valid options for relation parameter.
|
574 |
-
*/
|
575 |
-
public static function getRelationOptions() {
|
576 |
-
return array( 'AND', 'OR' );
|
577 |
-
}
|
578 |
-
|
579 |
-
/**
|
580 |
-
* Takes the provided value and returns a sanitized value.
|
581 |
-
*
|
582 |
-
* @param string $operator The operator value to be sanitized.
|
583 |
-
*
|
584 |
-
* @return string The sanitized operator value.
|
585 |
-
*/
|
586 |
-
private function sanitizeOperator( $operator ) {
|
587 |
-
$ret = strtoupper( $operator );
|
588 |
-
|
589 |
-
if ( ! in_array( $ret, self::getOperatorOptions() ) ) {
|
590 |
-
$this->errs[] = sprintf( self::$binary_err, 'IN", "NOT IN", "OR', 'AND', $operator );
|
591 |
-
$ret = null;
|
592 |
-
} else if ( $ret === 'OR' ) {
|
593 |
-
$ret = 'IN';
|
594 |
-
}
|
595 |
-
|
596 |
-
return $ret;
|
597 |
-
}
|
598 |
-
|
599 |
-
/**
|
600 |
-
* @return array The valid options for *_relation/*_operator parameter.
|
601 |
-
*/
|
602 |
-
public static function getOperatorOptions() {
|
603 |
-
return array( 'IN', 'NOT IN', 'AND', 'OR' );
|
604 |
-
}
|
605 |
-
|
606 |
/**
|
607 |
* Gets all valid Documents based on the attributes passed by the user.
|
608 |
* NOTE: Keys in returned array are arbitrary and will vary. They should be ignored.
|
@@ -611,12 +218,14 @@ class DG_Gallery {
|
|
611 |
*/
|
612 |
private function getDocuments() {
|
613 |
$query = array(
|
614 |
-
'
|
615 |
-
'
|
616 |
-
'
|
617 |
-
'
|
618 |
-
'
|
619 |
-
'
|
|
|
|
|
620 |
);
|
621 |
|
622 |
$this->setTaxa( $query );
|
@@ -625,21 +234,22 @@ class DG_Gallery {
|
|
625 |
throw new InvalidArgumentException();
|
626 |
}
|
627 |
|
628 |
-
// NOTE: Derived from gallery shortcode
|
629 |
if ( ! empty( $this->atts['include'] ) ) {
|
630 |
-
$query['
|
631 |
-
$attachments = get_posts( $query );
|
632 |
} else {
|
633 |
// id == 0 => all attachments w/o a parent
|
634 |
// id == null => all matched attachments
|
635 |
$query['post_parent'] = $this->atts['id'];
|
636 |
-
if ( ! empty( $exclude ) ) {
|
637 |
-
$query['
|
638 |
}
|
639 |
-
|
640 |
-
$attachments = get_children( $query );
|
641 |
}
|
642 |
|
|
|
|
|
|
|
|
|
|
|
643 |
return $attachments;
|
644 |
}
|
645 |
|
@@ -652,25 +262,26 @@ class DG_Gallery {
|
|
652 |
*/
|
653 |
private function setTaxa( &$query ) {
|
654 |
if ( ! empty( $this->taxa ) ) {
|
|
|
655 |
$taxa = array( 'relation' => $this->atts['relation'] );
|
656 |
$operator = array();
|
657 |
-
$suffix = array( 'relation', 'operator' );
|
658 |
-
$pattern = '/(.+)_(?:' . implode( '|', $suffix ) . ')$/i';
|
659 |
|
660 |
// find any relations for taxa
|
661 |
-
$
|
662 |
-
foreach ( $
|
663 |
if ( preg_match( $pattern, $key, $matches ) ) {
|
664 |
$base = $matches[1];
|
665 |
-
if (
|
666 |
-
$operator[
|
667 |
-
|
668 |
}
|
669 |
}
|
670 |
}
|
671 |
|
672 |
// build tax query
|
673 |
foreach ( $this->taxa as $taxon => $terms ) {
|
|
|
|
|
674 |
$terms = $this->getTermIdsByNames( $taxon, explode( ',', $terms ) );
|
675 |
|
676 |
$taxa[] = array(
|
@@ -725,11 +336,11 @@ class DG_Gallery {
|
|
725 |
*
|
726 |
* @param string $x Field to retrieve from matched term.
|
727 |
* @param string $taxon The taxon these terms are a member of.
|
728 |
-
* @param array $
|
729 |
*
|
730 |
* @return array All matched terms.
|
731 |
*/
|
732 |
-
private function getTermXByNames( $x, $taxon, $
|
733 |
$ret = array();
|
734 |
$valid = true;
|
735 |
|
@@ -740,19 +351,24 @@ class DG_Gallery {
|
|
740 |
if ( $count > 0 && taxonomy_exists( $tmp ) ) {
|
741 |
$taxon = $tmp;
|
742 |
} else {
|
743 |
-
$this->errs[] = sprintf(
|
744 |
$valid = false;
|
745 |
}
|
746 |
}
|
747 |
|
748 |
// only check terms if we first have a valid taxon
|
749 |
if ( $valid ) {
|
750 |
-
foreach ( $
|
751 |
-
|
|
|
|
|
|
|
|
|
|
|
752 |
$ret[] = $term->{$x};
|
753 |
} else {
|
754 |
-
$this->errs[] = sprintf( __( '%s is not a valid term name in %s.',
|
755 |
-
'document-gallery' ), $
|
756 |
}
|
757 |
}
|
758 |
}
|
@@ -760,15 +376,6 @@ class DG_Gallery {
|
|
760 |
return $ret;
|
761 |
}
|
762 |
|
763 |
-
/**
|
764 |
-
* @param string $string To take second char from.
|
765 |
-
*
|
766 |
-
* @return string Capitalized second char of given string.
|
767 |
-
*/
|
768 |
-
private static function secondCharToUpper( $string ) {
|
769 |
-
return strtoupper( $string[1] );
|
770 |
-
}
|
771 |
-
|
772 |
/**
|
773 |
* Function returns false for positive ints, true otherwise.
|
774 |
*
|
@@ -783,8 +390,22 @@ class DG_Gallery {
|
|
783 |
}
|
784 |
|
785 |
/*==========================================================================
|
786 |
-
|
787 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
788 |
|
789 |
/**
|
790 |
* @filter dg_gallery_template Allows the user to filter anything content surrounding the generated gallery.
|
@@ -794,12 +415,6 @@ class DG_Gallery {
|
|
794 |
*/
|
795 |
public function __toString() {
|
796 |
static $instance = 0;
|
797 |
-
$instance++;
|
798 |
-
|
799 |
-
static $find = null;
|
800 |
-
if ( is_null( $find ) ) {
|
801 |
-
$find = array( '%class%', '%icons%' );
|
802 |
-
}
|
803 |
|
804 |
if ( ! empty( $this->errs ) ) {
|
805 |
return '<p>' . implode( '</p><p>', $this->errs ) . '</p>';
|
@@ -809,56 +424,88 @@ class DG_Gallery {
|
|
809 |
return self::$no_docs;
|
810 |
}
|
811 |
|
812 |
-
$
|
813 |
-
$selector = "document-gallery-$instance";
|
814 |
-
$template =
|
815 |
-
"<div class='%class%'>" . PHP_EOL .
|
816 |
-
'%icons%' . PHP_EOL .
|
817 |
-
'</div>' . PHP_EOL;
|
818 |
|
819 |
-
$
|
820 |
-
|
821 |
-
|
822 |
-
|
|
|
|
|
823 |
|
824 |
-
$core = '';
|
825 |
-
$classes = array( 'document-icon-wrapper' );
|
826 |
if ( $this->useDescriptions() ) {
|
827 |
-
$
|
828 |
}
|
829 |
|
830 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
831 |
if ( $this->useDescriptions() ) {
|
832 |
foreach ( $this->docs as $doc ) {
|
833 |
-
$
|
834 |
-
$
|
835 |
}
|
836 |
} else {
|
837 |
$count = count( $this->docs );
|
838 |
-
$cols = !
|
839 |
|
840 |
-
// TODO: Invalid HTML. WP Core does it this way for [gallery], but consider setting width for each
|
841 |
-
// .document-icon as style attribute in element.
|
842 |
if ( apply_filters( 'dg_use_default_gallery_style', true ) ) {
|
843 |
$itemwidth = $cols > 0 ? ( floor( 100 / $cols ) - 1 ) : 100;
|
844 |
-
$
|
845 |
}
|
846 |
|
847 |
for ( $i = 0; $i < $count; $i += $cols ) {
|
848 |
-
$
|
849 |
|
850 |
$min = min( $i + $cols, $count );
|
851 |
for ( $x = $i; $x < $min; $x ++ ) {
|
852 |
-
$
|
853 |
}
|
854 |
|
855 |
-
$
|
856 |
}
|
857 |
}
|
858 |
|
859 |
// allow user to filter gallery wrapper
|
860 |
-
$gallery = apply_filters( 'dg_gallery_template', '<div id="%id%"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
861 |
|
862 |
-
return
|
863 |
}
|
864 |
}
|
1 |
<?php
|
2 |
defined( 'WPINC' ) OR exit;
|
3 |
|
4 |
+
include_once DG_PATH . 'inc/class-gallery-sanitization.php';
|
5 |
+
|
6 |
DG_Gallery::init();
|
7 |
|
8 |
/**
|
13 |
class DG_Gallery {
|
14 |
|
15 |
/*==========================================================================
|
16 |
+
* PRIVATE FIELDS
|
17 |
+
*=========================================================================*/
|
18 |
|
19 |
private $atts, $taxa;
|
20 |
private $docs = array();
|
21 |
private $errs = array();
|
22 |
|
23 |
+
private $has_prev = false;
|
24 |
+
private $has_next = false;
|
25 |
+
|
26 |
// templates for HTML output
|
27 |
+
private static $no_docs, $comment, $defaults;
|
28 |
|
29 |
/*==========================================================================
|
30 |
+
* PUBLIC FUNCTIONS
|
31 |
+
*=========================================================================*/
|
32 |
|
33 |
/**
|
34 |
* @return bool Whether to link to attachment pg.
|
59 |
}
|
60 |
|
61 |
/*==========================================================================
|
62 |
+
* GET AND SET OPTIONS
|
63 |
+
*=========================================================================*/
|
64 |
|
65 |
/**
|
66 |
* @param int $blog The blog we're retrieving options for (null => current blog).
|
84 |
}
|
85 |
|
86 |
/*==========================================================================
|
87 |
+
* INIT GALLERY
|
88 |
+
*=========================================================================*/
|
89 |
|
90 |
/**
|
91 |
* Initializes static values for this class.
|
92 |
*/
|
93 |
public static function init() {
|
94 |
if ( ! isset( self::$comment ) ) {
|
95 |
+
self::$comment =
|
96 |
PHP_EOL . '<!-- ' . __( 'Generated using Document Gallery. Get yours here: ', 'document-gallery' ) .
|
97 |
'http://wordpress.org/extend/plugins/document-gallery -->' . PHP_EOL;
|
98 |
+
self::$no_docs = '<!-- ' . __( 'No attachments to display. How boring! :(', 'document-gallery' ) . ' -->';
|
99 |
+
self::$defaults = array_merge( array( 'include' => '', 'exclude' => '' ), self::getOptions() );
|
|
|
100 |
}
|
101 |
}
|
102 |
|
108 |
public function __construct( $atts ) {
|
109 |
include_once DG_PATH . 'inc/class-document.php';
|
110 |
|
|
|
|
|
111 |
// empty string is passed when no arguments are given, but constructor expects an array
|
112 |
$atts = empty( $atts ) ? array() : $atts;
|
113 |
|
114 |
+
// get_post will return null during AJAX requests
|
115 |
+
$post = get_post();
|
116 |
+
$post_id = !is_null( $post ) ? $post->ID : -1;
|
117 |
+
|
118 |
if ( ! empty( $atts['ids'] ) ) {
|
119 |
// 'ids' is explicitly ordered, unless you specify otherwise.
|
120 |
if ( empty( $atts['orderby'] ) ) {
|
147 |
* @deprecated localpost will be removed at some point.
|
148 |
*/
|
149 |
if ( ! empty( $atts['localpost'] ) ) {
|
150 |
+
$atts['id'] = -1;
|
151 |
unset( $atts['localpost'] );
|
152 |
}
|
153 |
|
154 |
+
$defaults = array_merge( array( 'id' => $post_id ), self::$defaults );
|
|
|
|
|
|
|
155 |
|
156 |
// values used to construct tax query (may be empty)
|
157 |
$this->taxa = array_diff_key( $atts, $defaults );
|
203 |
}
|
204 |
} else if ( $sanitized[ $k ] !== $v ) { //Sometimes we get boolean in the string form for checkboxes
|
205 |
// sanitize value if different from old value
|
206 |
+
$sanitized[ $k ] = DG_GallerySanitization::sanitizeParameter( $k, $sanitized[ $k ], $errs );
|
207 |
}
|
208 |
}
|
209 |
|
210 |
return $sanitized;
|
211 |
}
|
212 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
213 |
/**
|
214 |
* Gets all valid Documents based on the attributes passed by the user.
|
215 |
* NOTE: Keys in returned array are arbitrary and will vary. They should be ignored.
|
218 |
*/
|
219 |
private function getDocuments() {
|
220 |
$query = array(
|
221 |
+
'posts_per_page' => $this->atts['limit'],
|
222 |
+
'offset' => $this->atts['skip'],
|
223 |
+
'orderby' => $this->atts['orderby'],
|
224 |
+
'order' => $this->atts['order'],
|
225 |
+
'post_status' => $this->atts['post_status'],
|
226 |
+
'post_type' => $this->atts['post_type'],
|
227 |
+
'post_mime_type' => $this->atts['mime_types'],
|
228 |
+
'suppress_filters' => true
|
229 |
);
|
230 |
|
231 |
$this->setTaxa( $query );
|
234 |
throw new InvalidArgumentException();
|
235 |
}
|
236 |
|
|
|
237 |
if ( ! empty( $this->atts['include'] ) ) {
|
238 |
+
$query['post__in'] = wp_parse_id_list( $this->atts['include'] );
|
|
|
239 |
} else {
|
240 |
// id == 0 => all attachments w/o a parent
|
241 |
// id == null => all matched attachments
|
242 |
$query['post_parent'] = $this->atts['id'];
|
243 |
+
if ( ! empty( $this->atts['exclude'] ) ) {
|
244 |
+
$query['post__not_in'] = wp_parse_id_list( $this->atts['exclude'] );
|
245 |
}
|
|
|
|
|
246 |
}
|
247 |
|
248 |
+
$wpq = new WP_Query();
|
249 |
+
$attachments = $wpq->query( $query );
|
250 |
+
$this->has_next = $wpq->found_posts > ( $this->atts['skip'] + $this->atts['limit'] );
|
251 |
+
$this->has_prev = $this->atts['skip'] > 0;
|
252 |
+
|
253 |
return $attachments;
|
254 |
}
|
255 |
|
262 |
*/
|
263 |
private function setTaxa( &$query ) {
|
264 |
if ( ! empty( $this->taxa ) ) {
|
265 |
+
static $pattern = '/(.+)_(?:relation|operator)$/i';
|
266 |
$taxa = array( 'relation' => $this->atts['relation'] );
|
267 |
$operator = array();
|
|
|
|
|
268 |
|
269 |
// find any relations for taxa
|
270 |
+
$operator_keys = array();
|
271 |
+
foreach ( $this->taxa as $key => $value ) {
|
272 |
if ( preg_match( $pattern, $key, $matches ) ) {
|
273 |
$base = $matches[1];
|
274 |
+
if ( isset( $this->taxa[$base] ) ) {
|
275 |
+
$operator[$base] = DG_GallerySanitization::sanitizeParameter( 'operator', $value, $this->errs );
|
276 |
+
$operator_keys[] = $key;
|
277 |
}
|
278 |
}
|
279 |
}
|
280 |
|
281 |
// build tax query
|
282 |
foreach ( $this->taxa as $taxon => $terms ) {
|
283 |
+
if ( in_array( $taxon, $operator_keys ) ) continue;
|
284 |
+
|
285 |
$terms = $this->getTermIdsByNames( $taxon, explode( ',', $terms ) );
|
286 |
|
287 |
$taxa[] = array(
|
336 |
*
|
337 |
* @param string $x Field to retrieve from matched term.
|
338 |
* @param string $taxon The taxon these terms are a member of.
|
339 |
+
* @param array $term_idents Terms to retrieve, identified by either slug or name.
|
340 |
*
|
341 |
* @return array All matched terms.
|
342 |
*/
|
343 |
+
private function getTermXByNames( $x, $taxon, $term_idents ) {
|
344 |
$ret = array();
|
345 |
$valid = true;
|
346 |
|
351 |
if ( $count > 0 && taxonomy_exists( $tmp ) ) {
|
352 |
$taxon = $tmp;
|
353 |
} else {
|
354 |
+
$this->errs[] = sprintf( DG_GallerySanitization::getUnaryErr(), 'taxon', $taxon );
|
355 |
$valid = false;
|
356 |
}
|
357 |
}
|
358 |
|
359 |
// only check terms if we first have a valid taxon
|
360 |
if ( $valid ) {
|
361 |
+
foreach ( $term_idents as $ident ) {
|
362 |
+
$term = get_term_by( 'slug', $ident, $taxon );
|
363 |
+
if ( ! $term ) {
|
364 |
+
$term = get_term_by( 'name', $ident, $taxon );
|
365 |
+
}
|
366 |
+
|
367 |
+
if ( $term ) {
|
368 |
$ret[] = $term->{$x};
|
369 |
} else {
|
370 |
+
$this->errs[] = sprintf( __( '%s is not a valid term slug/name in %s.',
|
371 |
+
'document-gallery' ), $ident, $taxon );
|
372 |
}
|
373 |
}
|
374 |
}
|
376 |
return $ret;
|
377 |
}
|
378 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
379 |
/**
|
380 |
* Function returns false for positive ints, true otherwise.
|
381 |
*
|
390 |
}
|
391 |
|
392 |
/*==========================================================================
|
393 |
+
* OUTPUT HTML STRING
|
394 |
+
*=========================================================================*/
|
395 |
+
|
396 |
+
/**
|
397 |
+
* @return array The data to be used in the data-shortcode attribute.
|
398 |
+
*/
|
399 |
+
private function getShortcodeData() {
|
400 |
+
$ret = array_merge( $this->atts, $this->taxa );
|
401 |
+
|
402 |
+
// need to undo nulling of -1 ID for version sent out to JSON
|
403 |
+
if ( is_null( $ret['id'] ) ) {
|
404 |
+
$ret['id'] = -1;
|
405 |
+
}
|
406 |
+
|
407 |
+
return $ret;
|
408 |
+
}
|
409 |
|
410 |
/**
|
411 |
* @filter dg_gallery_template Allows the user to filter anything content surrounding the generated gallery.
|
415 |
*/
|
416 |
public function __toString() {
|
417 |
static $instance = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
418 |
|
419 |
if ( ! empty( $this->errs ) ) {
|
420 |
return '<p>' . implode( '</p><p>', $this->errs ) . '</p>';
|
424 |
return self::$no_docs;
|
425 |
}
|
426 |
|
427 |
+
$instance++;
|
|
|
|
|
|
|
|
|
|
|
428 |
|
429 |
+
$icon_find = array( '%class%', '%icons%' );
|
430 |
+
$icon_repl = array();
|
431 |
+
$icon_classes = array( 'document-icon-row' );
|
432 |
+
$gallery_find = array( '%id%', '%data%', '%rows%', '%class%' );
|
433 |
+
$gallery_repl = array( "document-gallery-$instance", ( "data-shortcode='" . wp_json_encode( self::getShortcodeData() ) . "'" ), '' );
|
434 |
+
$gallery_classes = array( 'document-gallery' );
|
435 |
|
|
|
|
|
436 |
if ( $this->useDescriptions() ) {
|
437 |
+
$icon_classes[] = 'descriptions';
|
438 |
}
|
439 |
|
440 |
+
$icon_repl[] = implode( ' ', $icon_classes );
|
441 |
+
|
442 |
+
$icon_wrapper = apply_filters(
|
443 |
+
'dg_row_template',
|
444 |
+
"<div class='%class%'>" . PHP_EOL . '%icons%' . PHP_EOL . '</div>' . PHP_EOL,
|
445 |
+
$this->useDescriptions() );
|
446 |
+
|
447 |
if ( $this->useDescriptions() ) {
|
448 |
foreach ( $this->docs as $doc ) {
|
449 |
+
$icon_repl[1] = $doc;
|
450 |
+
$gallery_repl[2] .= str_replace( $icon_find, $icon_repl, $icon_wrapper );
|
451 |
}
|
452 |
} else {
|
453 |
$count = count( $this->docs );
|
454 |
+
$cols = !is_null( $this->atts['columns'] ) ? $this->atts['columns'] : $count;
|
455 |
|
|
|
|
|
456 |
if ( apply_filters( 'dg_use_default_gallery_style', true ) ) {
|
457 |
$itemwidth = $cols > 0 ? ( floor( 100 / $cols ) - 1 ) : 100;
|
458 |
+
$gallery_repl[1] .= " data-icon-width='$itemwidth'";
|
459 |
}
|
460 |
|
461 |
for ( $i = 0; $i < $count; $i += $cols ) {
|
462 |
+
$icon_repl[1] = '';
|
463 |
|
464 |
$min = min( $i + $cols, $count );
|
465 |
for ( $x = $i; $x < $min; $x ++ ) {
|
466 |
+
$icon_repl[1] .= $this->docs[ $x ];
|
467 |
}
|
468 |
|
469 |
+
$gallery_repl[2] .= str_replace( $icon_find, $icon_repl, $icon_wrapper );
|
470 |
}
|
471 |
}
|
472 |
|
473 |
// allow user to filter gallery wrapper
|
474 |
+
$gallery = apply_filters( 'dg_gallery_template', '<div id="%id%" class="%class%" %data%>' . PHP_EOL . '%rows%</div>', $this->useDescriptions() );
|
475 |
+
|
476 |
+
// build pagination section
|
477 |
+
// TODO: We should be using WP core get_the_posts_pagination()
|
478 |
+
if ( $this->atts['paginate'] && $this->atts['limit'] > 0 ) {
|
479 |
+
$left_href = $right_href = ' href="#"';
|
480 |
+
$left_tag = $right_tag = 'a';
|
481 |
+
|
482 |
+
if ( !$this->has_prev ) {
|
483 |
+
$left_href = '';
|
484 |
+
$left_tag = 'span';
|
485 |
+
}
|
486 |
+
if ( !$this->has_next ) {
|
487 |
+
$right_href = '';
|
488 |
+
$right_tag = 'span';
|
489 |
+
}
|
490 |
+
|
491 |
+
$prev = __( 'Prev', 'document-gallery' );
|
492 |
+
$next = __( 'Next', 'document-gallery' );
|
493 |
+
$gallery_repl[2] .= "<span class='pagination'><$left_tag$left_href class='paginate left'>$prev</$left_tag> | <$right_tag$right_href class='paginate right'>$next</$right_tag></span>";
|
494 |
+
$gallery_classes[] = 'dg-paginate-wrapper';
|
495 |
+
}
|
496 |
+
|
497 |
+
$gallery_repl[] = implode( ' ', $gallery_classes );
|
498 |
+
|
499 |
+
$comment = self::$comment;
|
500 |
+
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
|
501 |
+
$ids = array();
|
502 |
+
foreach ( $this->docs as $doc ) {
|
503 |
+
$ids[] = $doc->getId();
|
504 |
+
}
|
505 |
+
|
506 |
+
$comment .= '<!-- Attachment IDs: ' . implode( $ids, ', ' ) . ' -->' . PHP_EOL;
|
507 |
+
}
|
508 |
|
509 |
+
return $comment . str_replace( $gallery_find, $gallery_repl, $gallery );
|
510 |
}
|
511 |
}
|
inc/class-image-editor-imagick.php
CHANGED
@@ -32,9 +32,8 @@ class DG_Image_Editor_Imagick extends WP_Image_Editor_Imagick {
|
|
32 |
$ret = parent::load();
|
33 |
|
34 |
// set correct page number
|
35 |
-
if ( !
|
36 |
-
&& is_callable( array( $this->image, 'setIteratorIndex' ) )
|
37 |
-
) {
|
38 |
$err = __( 'Failed to set Imagick page number', 'document-gallery' );
|
39 |
|
40 |
// setIteratorIndex() should return false on failure, but I've found
|
32 |
$ret = parent::load();
|
33 |
|
34 |
// set correct page number
|
35 |
+
if ( ! is_null( $this->pg ) && ! is_wp_error( $ret )
|
36 |
+
&& is_callable( array( $this->image, 'setIteratorIndex' ) ) ) {
|
|
|
37 |
$err = __( 'Failed to set Imagick page number', 'document-gallery' );
|
38 |
|
39 |
// setIteratorIndex() should return false on failure, but I've found
|
inc/class-setup.php
CHANGED
@@ -26,8 +26,6 @@ class DG_Setup {
|
|
26 |
|
27 |
return array(
|
28 |
'thumber' => array(
|
29 |
-
// cached thumbnails, keyed by post ID
|
30 |
-
'thumbs' => array(),
|
31 |
// Ghostscript path
|
32 |
'gs' => $gs,
|
33 |
// which thumbnail generation methods are available
|
@@ -40,28 +38,32 @@ class DG_Setup {
|
|
40 |
'gallery' => array(
|
41 |
// default: link directly to file (true to link to attachment pg)
|
42 |
'attachment_pg' => false,
|
|
|
|
|
43 |
// include the attachment description in output
|
44 |
'descriptions' => false,
|
45 |
// include thumbnail of actual document in gallery display
|
46 |
'fancy' => true,
|
|
|
|
|
47 |
// comma-delimited list of all mime types to be included
|
48 |
'mime_types' => implode( ',', self::getDefaultMimeTypes() ),
|
|
|
|
|
49 |
// ascending/descending order for included documents
|
50 |
'order' => 'ASC',
|
51 |
// which property to order by
|
52 |
'orderby' => 'menu_order',
|
53 |
-
//
|
54 |
-
'
|
55 |
// the status the post must be in when returned by DG
|
56 |
'post_status' => 'any',
|
57 |
// the type of post to be returned
|
58 |
'post_type' => 'attachment',
|
59 |
-
//
|
60 |
-
'
|
61 |
-
//
|
62 |
-
'
|
63 |
-
// whether to open documents in new window
|
64 |
-
'new_window' => false
|
65 |
),
|
66 |
'css' => array(
|
67 |
// plain text of CSS to be edited by user
|
@@ -70,6 +72,8 @@ class DG_Setup {
|
|
70 |
'meta' => array(
|
71 |
// current DG version
|
72 |
'version' => DG_VERSION,
|
|
|
|
|
73 |
// URL to donate to plugin development
|
74 |
'donate_link' => $donate_link
|
75 |
),
|
@@ -100,7 +104,7 @@ class DG_Setup {
|
|
100 |
}
|
101 |
|
102 |
// version has historically been in two locations -- must check both to continue supporting upgrading from those old versions
|
103 |
-
$old_version =
|
104 |
if ( ! is_null( $dg_options ) && DG_VERSION !== $old_version ) {
|
105 |
DG_Logger::writeLog( DG_LogLevel::Detail, "Upgrading Document Gallery from version $old_version to " . DG_VERSION );
|
106 |
|
@@ -137,18 +141,14 @@ class DG_Setup {
|
|
137 |
self::threePointThree( $options );
|
138 |
self::threePointFour( $options );
|
139 |
self::threePointFive( $options );
|
|
|
140 |
|
141 |
// update plugin meta data
|
142 |
$options['meta']['version'] = DG_VERSION;
|
143 |
$options['meta']['donate_link'] = self::getDonateLink();
|
144 |
|
145 |
// remove previously-failed thumbs
|
146 |
-
|
147 |
-
foreach ( $thumbs as $k => $v ) {
|
148 |
-
if ( empty( $v['thumber'] ) ) {
|
149 |
-
unset( $options['thumber']['thumbs'][ $k ] );
|
150 |
-
}
|
151 |
-
}
|
152 |
|
153 |
DocumentGallery::setOptions( $options, $blog );
|
154 |
}
|
@@ -318,7 +318,6 @@ class DG_Setup {
|
|
318 |
|
319 |
/**
|
320 |
* Removes the validation option. Validation is now non-optional.
|
321 |
-
* Adds the meta items_per_page default value.
|
322 |
*
|
323 |
* @param array $options The options to be modified.
|
324 |
*/
|
@@ -329,7 +328,7 @@ class DG_Setup {
|
|
329 |
if ( ! DocumentGallery::isValidOptionsStructure( $options ) ) {
|
330 |
DG_Logger::writeLog(
|
331 |
DG_LogLevel::Error,
|
332 |
-
|
333 |
false,
|
334 |
true );
|
335 |
$options = self::getDefaultOptions();
|
@@ -349,6 +348,39 @@ class DG_Setup {
|
|
349 |
}
|
350 |
}
|
351 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
352 |
/**
|
353 |
* Sets up Document Gallery on all blog(s) activated.
|
354 |
*
|
@@ -425,17 +457,7 @@ class DG_Setup {
|
|
425 |
* Runs when DG is uninstalled for an individual blog.
|
426 |
*/
|
427 |
private static function _uninstall( $blog ) {
|
428 |
-
|
429 |
-
if ( is_null( $options ) ) {
|
430 |
-
return;
|
431 |
-
}
|
432 |
-
|
433 |
-
foreach ( $options['thumbs'] as $val ) {
|
434 |
-
if ( isset( $val['thumber'] ) ) {
|
435 |
-
@unlink( $val['thumb_path'] );
|
436 |
-
}
|
437 |
-
}
|
438 |
-
|
439 |
DocumentGallery::deleteOptions( $blog );
|
440 |
}
|
441 |
|
26 |
|
27 |
return array(
|
28 |
'thumber' => array(
|
|
|
|
|
29 |
// Ghostscript path
|
30 |
'gs' => $gs,
|
31 |
// which thumbnail generation methods are available
|
38 |
'gallery' => array(
|
39 |
// default: link directly to file (true to link to attachment pg)
|
40 |
'attachment_pg' => false,
|
41 |
+
// # of columns to be used in gallery
|
42 |
+
'columns' => 4,
|
43 |
// include the attachment description in output
|
44 |
'descriptions' => false,
|
45 |
// include thumbnail of actual document in gallery display
|
46 |
'fancy' => true,
|
47 |
+
// the max number of thumbnails to return
|
48 |
+
'limit' => -1,
|
49 |
// comma-delimited list of all mime types to be included
|
50 |
'mime_types' => implode( ',', self::getDefaultMimeTypes() ),
|
51 |
+
// whether to open documents in new window
|
52 |
+
'new_window' => false,
|
53 |
// ascending/descending order for included documents
|
54 |
'order' => 'ASC',
|
55 |
// which property to order by
|
56 |
'orderby' => 'menu_order',
|
57 |
+
// whether to paginate galleries with a "limit"
|
58 |
+
'paginate' => true,
|
59 |
// the status the post must be in when returned by DG
|
60 |
'post_status' => 'any',
|
61 |
// the type of post to be returned
|
62 |
'post_type' => 'attachment',
|
63 |
+
// AND or OR
|
64 |
+
'relation' => 'AND',
|
65 |
+
// how many documents to skip
|
66 |
+
'skip' => 0
|
|
|
|
|
67 |
),
|
68 |
'css' => array(
|
69 |
// plain text of CSS to be edited by user
|
72 |
'meta' => array(
|
73 |
// current DG version
|
74 |
'version' => DG_VERSION,
|
75 |
+
// items per page at Thumbnail Management tab
|
76 |
+
'items_per_page' => 10,
|
77 |
// URL to donate to plugin development
|
78 |
'donate_link' => $donate_link
|
79 |
),
|
104 |
}
|
105 |
|
106 |
// version has historically been in two locations -- must check both to continue supporting upgrading from those old versions
|
107 |
+
$old_version = isset( $dg_options['version'] ) ? $dg_options['version'] : $dg_options['meta']['version'];
|
108 |
if ( ! is_null( $dg_options ) && DG_VERSION !== $old_version ) {
|
109 |
DG_Logger::writeLog( DG_LogLevel::Detail, "Upgrading Document Gallery from version $old_version to " . DG_VERSION );
|
110 |
|
141 |
self::threePointThree( $options );
|
142 |
self::threePointFour( $options );
|
143 |
self::threePointFive( $options );
|
144 |
+
self::fourPointZero( $options );
|
145 |
|
146 |
// update plugin meta data
|
147 |
$options['meta']['version'] = DG_VERSION;
|
148 |
$options['meta']['donate_link'] = self::getDonateLink();
|
149 |
|
150 |
// remove previously-failed thumbs
|
151 |
+
DG_Thumb::purgeFailedThumbs();
|
|
|
|
|
|
|
|
|
|
|
152 |
|
153 |
DocumentGallery::setOptions( $options, $blog );
|
154 |
}
|
318 |
|
319 |
/**
|
320 |
* Removes the validation option. Validation is now non-optional.
|
|
|
321 |
*
|
322 |
* @param array $options The options to be modified.
|
323 |
*/
|
328 |
if ( ! DocumentGallery::isValidOptionsStructure( $options ) ) {
|
329 |
DG_Logger::writeLog(
|
330 |
DG_LogLevel::Error,
|
331 |
+
'Found invalid options structure. Reverting to default options.',
|
332 |
false,
|
333 |
true );
|
334 |
$options = self::getDefaultOptions();
|
348 |
}
|
349 |
}
|
350 |
|
351 |
+
/**
|
352 |
+
* Adds the meta items_per_page default value.
|
353 |
+
* Paginate & skip options were added.
|
354 |
+
* Moving cached thumbs into postmeta table.
|
355 |
+
*
|
356 |
+
* @param array $options The options to be modified.
|
357 |
+
*/
|
358 |
+
private static function fourPointZero( &$options ) {
|
359 |
+
if ( version_compare( $options['meta']['version'], '4.0', '<' ) ) {
|
360 |
+
$options['gallery']['paginate'] = true;
|
361 |
+
$options['gallery']['skip'] = 0;
|
362 |
+
$options['meta']['items_per_page'] = 10;
|
363 |
+
|
364 |
+
$upload_dir = wp_upload_dir();
|
365 |
+
$upload_len = strlen( $upload_dir['basedir'] );
|
366 |
+
$dimensions = $options['thumber']['width'] . 'x' . $options['thumber']['height'];
|
367 |
+
foreach ( $options['thumber']['thumbs'] as $id => $thumb ) {
|
368 |
+
$thumb_obj = new DG_Thumb();
|
369 |
+
$thumb_obj->setPostId( $id );
|
370 |
+
$thumb_obj->setTimestamp( $thumb['timestamp'] );
|
371 |
+
$thumb_obj->setDimensions( $dimensions );
|
372 |
+
if ( isset( $thumb['thumb_path'] ) ) {
|
373 |
+
$thumb_obj->setRelativePath( substr( $thumb['thumb_path'], $upload_len + 1 ) );
|
374 |
+
$thumb_obj->setGenerator( DG_Util::callableToString( $thumb['thumber'] ) );
|
375 |
+
}
|
376 |
+
|
377 |
+
$thumb_obj->save();
|
378 |
+
}
|
379 |
+
|
380 |
+
unset( $options['thumber']['thumbs'] );
|
381 |
+
}
|
382 |
+
}
|
383 |
+
|
384 |
/**
|
385 |
* Sets up Document Gallery on all blog(s) activated.
|
386 |
*
|
457 |
* Runs when DG is uninstalled for an individual blog.
|
458 |
*/
|
459 |
private static function _uninstall( $blog ) {
|
460 |
+
DG_Thumb::purgeThumbs( null, $blog );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
461 |
DocumentGallery::deleteOptions( $blog );
|
462 |
}
|
463 |
|
inc/class-thumb.php
ADDED
@@ -0,0 +1,412 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Holds data specific to a specific thumbnail
|
5 |
+
*
|
6 |
+
* @author drossiter
|
7 |
+
*/
|
8 |
+
class DG_Thumb {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* TODO: Replace w/ https://codex.wordpress.org/Class_Reference/WP_Object_Cache
|
12 |
+
* @var array The cached copy of thumbs.
|
13 |
+
*/
|
14 |
+
private static $thumbs = null;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @var string The meta key identifying DG thumbs.
|
18 |
+
*/
|
19 |
+
private static $meta_key = '_dg_thumbnail';
|
20 |
+
|
21 |
+
/**
|
22 |
+
* @var int The DB row ID.
|
23 |
+
*/
|
24 |
+
private $meta_id;
|
25 |
+
|
26 |
+
/**
|
27 |
+
* @var int The post (attachment) ID.
|
28 |
+
*/
|
29 |
+
private $post_id;
|
30 |
+
|
31 |
+
/**
|
32 |
+
* @return int The post ID.
|
33 |
+
*/
|
34 |
+
public function getPostId() {
|
35 |
+
return $this->post_id;
|
36 |
+
}
|
37 |
+
|
38 |
+
/**
|
39 |
+
* @param $post_id int The post ID.
|
40 |
+
*/
|
41 |
+
public function setPostId($post_id) {
|
42 |
+
$this->post_id = $post_id;
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* @var string The thumb dimensions (format: WIDTHxHEIGHT).
|
47 |
+
*/
|
48 |
+
private $dimensions = '';
|
49 |
+
|
50 |
+
/**
|
51 |
+
* @return string The dimensions (WIDTHxHEIGHT).
|
52 |
+
*/
|
53 |
+
public function getDimensions() {
|
54 |
+
return $this->dimensions;
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* @param $dimensions string The dimensions (WIDTHxHEIGHT).
|
59 |
+
*/
|
60 |
+
public function setDimensions($dimensions) {
|
61 |
+
$this->dimensions = $dimensions;
|
62 |
+
}
|
63 |
+
|
64 |
+
/**
|
65 |
+
* @var string The path relative to the WP uploads directory.
|
66 |
+
*/
|
67 |
+
private $relative_path = '';
|
68 |
+
|
69 |
+
/**
|
70 |
+
* @return string The path relative to the WP uploads directory.
|
71 |
+
*/
|
72 |
+
public function getRelativePath() {
|
73 |
+
return $this->relative_path;
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* @param $relative_path string The path relative to the WP uploads directory.
|
78 |
+
*/
|
79 |
+
public function setRelativePath($relative_path) {
|
80 |
+
$this->relative_path = $relative_path;
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* @var int The time when thumbnail was generated.
|
85 |
+
*/
|
86 |
+
private $timestamp;
|
87 |
+
|
88 |
+
/**
|
89 |
+
* @return int The time when thumbnail was generated.
|
90 |
+
*/
|
91 |
+
public function getTimestamp() {
|
92 |
+
return $this->timestamp;
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* @param $timestamp int The time when thumbnail was generated.
|
97 |
+
*/
|
98 |
+
public function setTimestamp($timestamp) {
|
99 |
+
$this->timestamp = $timestamp;
|
100 |
+
}
|
101 |
+
|
102 |
+
/**
|
103 |
+
* @var string The function used in generating this thumb.
|
104 |
+
*/
|
105 |
+
private $generator = '';
|
106 |
+
|
107 |
+
/**
|
108 |
+
* @return string The function used in generating this thumb.
|
109 |
+
*/
|
110 |
+
public function getGenerator() {
|
111 |
+
return $this->generator;
|
112 |
+
}
|
113 |
+
|
114 |
+
/**
|
115 |
+
* @param $generator string The function used in generating this thumb.
|
116 |
+
*/
|
117 |
+
public function setGenerator($generator) {
|
118 |
+
$this->generator = $generator;
|
119 |
+
}
|
120 |
+
|
121 |
+
/**
|
122 |
+
* DG_Thumb constructor.
|
123 |
+
* @param $db_row object The result of querying WP postmeta.
|
124 |
+
*/
|
125 |
+
public function __construct($db_row = null) {
|
126 |
+
if ( is_null ($db_row) ) return;
|
127 |
+
|
128 |
+
$this->meta_id = $db_row->meta_id;
|
129 |
+
$this->post_id = $db_row->post_id;
|
130 |
+
$this->setMetaValue( $db_row->meta_value );
|
131 |
+
}
|
132 |
+
|
133 |
+
/**
|
134 |
+
* Meta value is in the following format: [width]x[height]:[timestamp]:[path]:[generator].
|
135 |
+
* Note that generator may contain colons, so parsing of this field must be done carefully.
|
136 |
+
*
|
137 |
+
* @param $meta_value string Populates the dimensions and path from meta_value.
|
138 |
+
*/
|
139 |
+
private function setMetaValue($meta_value) {
|
140 |
+
$split = explode( ':', $meta_value, 4 );
|
141 |
+
$this->dimensions = $split[0];
|
142 |
+
$this->timestamp = absint( $split[1] );
|
143 |
+
$this->relative_path = $split[2];
|
144 |
+
$this->generator = $split[3];
|
145 |
+
}
|
146 |
+
|
147 |
+
/**
|
148 |
+
* Meta value is in the following format: [width]x[height]:[timestamp]:[path]:[generator].
|
149 |
+
*
|
150 |
+
* @return string The meta_value generated from the dimensions & path fields.
|
151 |
+
*/
|
152 |
+
private function getMetaValue() {
|
153 |
+
return $this->dimensions . ':' . $this->timestamp . ':' . $this->relative_path . ':' . $this->generator;
|
154 |
+
}
|
155 |
+
|
156 |
+
/**
|
157 |
+
* @return int Parses dimensions string pulling out the width.
|
158 |
+
*/
|
159 |
+
public function getWidth() {
|
160 |
+
$split = explode( 'x', $this->dimensions, 2 );
|
161 |
+
return absint( $split[0] );
|
162 |
+
}
|
163 |
+
|
164 |
+
/**
|
165 |
+
* @return int Parses dimensions string pulling out the height.
|
166 |
+
*/
|
167 |
+
public function getHeight() {
|
168 |
+
$split = explode( 'x', $this->dimensions, 2 );
|
169 |
+
return absint( $split[1] );
|
170 |
+
}
|
171 |
+
|
172 |
+
/**
|
173 |
+
* @return string Get fully-qualified URL pointing to this thumb.
|
174 |
+
*/
|
175 |
+
public function getUrl() {
|
176 |
+
$upload_dir = wp_upload_dir();
|
177 |
+
return $upload_dir['baseurl'] . '/' . $this->relative_path;
|
178 |
+
}
|
179 |
+
|
180 |
+
/**
|
181 |
+
* @return string Get fully-qualified system path pointing to this thumb.
|
182 |
+
*/
|
183 |
+
public function getPath() {
|
184 |
+
$upload_dir = wp_upload_dir();
|
185 |
+
return $upload_dir['basedir'] . DIRECTORY_SEPARATOR . $this->relative_path;
|
186 |
+
}
|
187 |
+
|
188 |
+
/**
|
189 |
+
* @return bool Whether this instance represents a successful thumb generation.
|
190 |
+
*/
|
191 |
+
public function isSuccess() {
|
192 |
+
return ! empty( $this->relative_path );
|
193 |
+
}
|
194 |
+
|
195 |
+
/**
|
196 |
+
* Saves thumb to DB. Either an UPDATE or an INSERT is performed depending on whether meta_id isset and
|
197 |
+
* updates the instance meta_id if INSERT is performed.
|
198 |
+
*/
|
199 |
+
public function save() {
|
200 |
+
global $wpdb;
|
201 |
+
|
202 |
+
// thumbs are immutable -- once created they can only be read or deleted
|
203 |
+
if ( isset( $this->meta_id ) ) return;
|
204 |
+
|
205 |
+
// post_id + dimensions must be unique so purge the old entry if one exists
|
206 |
+
$old_thumb = self::getThumb( $this->post_id, $this->getWidth(), $this->getHeight() );
|
207 |
+
if ( ! is_null( $old_thumb ) ) {
|
208 |
+
$old_thumb->delete();
|
209 |
+
}
|
210 |
+
|
211 |
+
DG_Logger::writeLog( DG_LogLevel::Detail, 'Saving thumb with post_id = ' . $this->post_id );
|
212 |
+
|
213 |
+
// perform save to DB
|
214 |
+
$values = array( 'post_id' => $this->post_id, 'meta_key' => self::$meta_key, 'meta_value' => $this->getMetaValue() );
|
215 |
+
$value_formats = array( '%d', '%s', '%s' );
|
216 |
+
$wpdb->insert( $wpdb->postmeta, $values, $value_formats );
|
217 |
+
$this->meta_id = $wpdb->insert_id;
|
218 |
+
|
219 |
+
self::initThumbs();
|
220 |
+
if ( ! isset( self::$thumbs[$this->post_id] ) ) {
|
221 |
+
self::$thumbs[$this->post_id] = array();
|
222 |
+
}
|
223 |
+
|
224 |
+
self::$thumbs[$this->post_id][$this->dimensions] = $this;
|
225 |
+
}
|
226 |
+
|
227 |
+
/**
|
228 |
+
* Deletes the current instances from the DB and filesystem.
|
229 |
+
*/
|
230 |
+
public function delete() {
|
231 |
+
if ( ! isset( $this->meta_id ) ) return;
|
232 |
+
|
233 |
+
DG_Logger::writeLog( DG_LogLevel::Detail, 'Deleting thumb with post_id = ' . $this->post_id );
|
234 |
+
|
235 |
+
global $wpdb;
|
236 |
+
$wpdb->delete( $wpdb->postmeta, array( 'meta_id' => $this->meta_id ), array( '%d' ) );
|
237 |
+
self::cleanupThumbFiles( $this );
|
238 |
+
unset( $this->meta_id );
|
239 |
+
if ( 1 === sizeof( self::$thumbs[$this->post_id] ) ) {
|
240 |
+
unset( self::$thumbs[$this->post_id] );
|
241 |
+
} else {
|
242 |
+
unset( self::$thumbs[$this->post_id][$this->dimensions] );
|
243 |
+
}
|
244 |
+
}
|
245 |
+
|
246 |
+
/**
|
247 |
+
* Whether the given attachment has a thumb graphic.
|
248 |
+
*
|
249 |
+
* @param $ID int The id of the attachment to be checked.
|
250 |
+
* @param $dimensions string Optional. The dimensions for the thumbnail we're seeking.
|
251 |
+
* @param $success_matters bool Optional. Whether return value should be false when DG_Thumb exists, but is not successful.
|
252 |
+
* @return bool Whether the given attachment has a thumbnail image.
|
253 |
+
*/
|
254 |
+
public static function thumbExists($ID, $dimensions = null, $success_matters = true) {
|
255 |
+
$thumb = self::getThumb( $ID, $dimensions );
|
256 |
+
return ! is_null( $thumb ) && ( ! $success_matters || $thumb->isSuccess() );
|
257 |
+
}
|
258 |
+
|
259 |
+
/**
|
260 |
+
* Whether the given attachment has a thumb graphic.
|
261 |
+
*
|
262 |
+
* @param $ID int The id of the attachment to be checked.
|
263 |
+
* @param $dimensions string The dimensions for the thumbnail we're seeking.
|
264 |
+
* @return DG_Thumb|null The thumbnail at the requested dimensions.
|
265 |
+
*/
|
266 |
+
public static function getThumb($ID, $dimensions = null) {
|
267 |
+
$thumbs = self::getThumbs();
|
268 |
+
$ret = null;
|
269 |
+
if ( isset( $thumbs[$ID] ) && ( is_null( $dimensions ) || isset( $thumbs[$ID][$dimensions] ) ) ) {
|
270 |
+
$ret = ! is_null( $dimensions ) ? $thumbs[$ID][$dimensions] : reset( $thumbs[$ID] );
|
271 |
+
}
|
272 |
+
|
273 |
+
return $ret;
|
274 |
+
}
|
275 |
+
|
276 |
+
/**
|
277 |
+
* Initializes the thumbs variable if not already initialized.
|
278 |
+
*/
|
279 |
+
private static function initThumbs() {
|
280 |
+
if ( !isset( self::$thumbs ) ) {
|
281 |
+
DG_Logger::writeLog( DG_LogLevel::Detail, 'Populating thumbnail cache.' );
|
282 |
+
global $wpdb;
|
283 |
+
self::$thumbs = array();
|
284 |
+
|
285 |
+
$meta_key = self::$meta_key;
|
286 |
+
$sql = "SELECT post_id, meta_id, meta_value FROM $wpdb->postmeta WHERE meta_key = '$meta_key'";
|
287 |
+
foreach ( $wpdb->get_results( $sql ) as $row ) {
|
288 |
+
$key = $row->post_id;
|
289 |
+
$new = new DG_Thumb( $row );
|
290 |
+
if ( ! isset( self::$thumbs[$key] ) ) {
|
291 |
+
self::$thumbs[$key] = array();
|
292 |
+
} elseif ( isset( self::$thumbs[$key][$new->dimensions] ) ) {
|
293 |
+
// it is possible to end up with duplicate thumbnails -- cleanup here
|
294 |
+
$old = self::$thumbs[$key][$new->dimensions];
|
295 |
+
if ( $old->timestamp < $new->timestamp ) {
|
296 |
+
$old->delete();
|
297 |
+
} else {
|
298 |
+
$new->delete();
|
299 |
+
continue;
|
300 |
+
}
|
301 |
+
}
|
302 |
+
|
303 |
+
self::$thumbs[$key][$new->dimensions] = $new;
|
304 |
+
}
|
305 |
+
}
|
306 |
+
}
|
307 |
+
|
308 |
+
/**
|
309 |
+
* Gets either a nested associative array mapping ID to dimension to thumb or an associative array mapping ID to thumb.
|
310 |
+
*
|
311 |
+
* @param $dimensions string WIDTHxHEIGHT
|
312 |
+
* @return array The matched thumbs.
|
313 |
+
*/
|
314 |
+
public static function getThumbs($dimensions = null) {
|
315 |
+
self::initThumbs();
|
316 |
+
if ( is_null( $dimensions ) ) {
|
317 |
+
$ret = self::$thumbs;
|
318 |
+
} else {
|
319 |
+
$ret = array();
|
320 |
+
foreach ( self::$thumbs as $thumbs ) {
|
321 |
+
if ( isset( $thumbs[$dimensions] ) ) {
|
322 |
+
$thumb = $thumbs[$dimensions];
|
323 |
+
$ret[$thumb->post_id] = $thumb;
|
324 |
+
}
|
325 |
+
}
|
326 |
+
}
|
327 |
+
|
328 |
+
return $ret;
|
329 |
+
}
|
330 |
+
|
331 |
+
/**
|
332 |
+
* Removes thumbs from the DB.
|
333 |
+
* @param $ids array|int|null Optional. The post IDs to be purged. If not given then all are purged.
|
334 |
+
* @param $blog_id null|int Optional. The blog to purge from. Defaults to active blog.
|
335 |
+
*/
|
336 |
+
public static function purgeThumbs($ids = null, $blog_id = null) {
|
337 |
+
global $wpdb;
|
338 |
+
|
339 |
+
if ( ! is_null( $ids ) ) {
|
340 |
+
$ids = (array)$ids;
|
341 |
+
}
|
342 |
+
|
343 |
+
$postmeta = $wpdb->get_blog_prefix( $blog_id ) . 'postmeta';
|
344 |
+
$meta_key = self::$meta_key;
|
345 |
+
|
346 |
+
self::initThumbs();
|
347 |
+
|
348 |
+
if ( ! is_array( $ids ) ) {
|
349 |
+
$sql = "DELETE FROM $postmeta WHERE meta_key = '$meta_key'";
|
350 |
+
$result = $wpdb->query( $sql );
|
351 |
+
|
352 |
+
if ( $result ) {
|
353 |
+
// cleanup filesystem
|
354 |
+
foreach ( self::$thumbs as $thumbs ) {
|
355 |
+
self::cleanupThumbFiles( $thumbs );
|
356 |
+
}
|
357 |
+
|
358 |
+
self::$thumbs = null;
|
359 |
+
}
|
360 |
+
} else {
|
361 |
+
$sql = "DELETE FROM $postmeta WHERE meta_key = '$meta_key' AND post_id IN(" . rtrim( str_repeat( '%d,', sizeof( $ids ) ), ',' ) . ")";
|
362 |
+
$result = $wpdb->query( $wpdb->prepare( $sql, $ids ) );
|
363 |
+
|
364 |
+
if ( $result ) {
|
365 |
+
foreach ( $ids as $id ) {
|
366 |
+
if ( isset( self::$thumbs[$id] ) ) {
|
367 |
+
self::cleanupThumbFiles( self::$thumbs[$id] );
|
368 |
+
unset( self::$thumbs[$id] );
|
369 |
+
}
|
370 |
+
}
|
371 |
+
}
|
372 |
+
}
|
373 |
+
}
|
374 |
+
|
375 |
+
/**
|
376 |
+
* Delete all thumb entries that do not have an actual image associated with them due to failed generation.
|
377 |
+
*/
|
378 |
+
public static function purgeFailedThumbs() {
|
379 |
+
global $wpdb;
|
380 |
+
$wpdb->query( "DELETE FROM $wpdb->postmeta WHERE meta_key = '" . self::$meta_key . "' AND meta_value LIKE '%:%::'" );
|
381 |
+
|
382 |
+
// force re-query next time
|
383 |
+
self::$thumbs = null;
|
384 |
+
}
|
385 |
+
|
386 |
+
/**
|
387 |
+
* Removes meta data associated w/ attachment.
|
388 |
+
*
|
389 |
+
* @param $id int The post ID.
|
390 |
+
*/
|
391 |
+
public static function cleanupAttachmentMeta($id) {
|
392 |
+
$thumb = self::getThumb( $id );
|
393 |
+
if ( ! is_null( $thumb ) ) {
|
394 |
+
self::cleanupThumbFiles($thumb);
|
395 |
+
}
|
396 |
+
}
|
397 |
+
|
398 |
+
/**
|
399 |
+
* @param $thumbs array|DG_Thumb Removes files associated with given thumb(s).
|
400 |
+
*/
|
401 |
+
private static function cleanupThumbFiles($thumbs) {
|
402 |
+
if ( is_a( $thumbs, __CLASS__ ) ) {
|
403 |
+
$thumbs = array( $thumbs );
|
404 |
+
}
|
405 |
+
|
406 |
+
foreach ( $thumbs as $thumb ) {
|
407 |
+
if ( isset( $thumb->relative_path ) ) {
|
408 |
+
@unlink( $thumb->getPath() );
|
409 |
+
}
|
410 |
+
}
|
411 |
+
}
|
412 |
+
}
|
inc/class-thumber.php
CHANGED
@@ -38,7 +38,7 @@ class DG_Thumber {
|
|
38 |
* @param string $path System path to thumbnail.
|
39 |
* @param string $generator Descriptor for generation method -- usually method name.
|
40 |
*
|
41 |
-
* @return bool
|
42 |
*/
|
43 |
public static function setThumbnail( $ID, $path, $generator = 'unknown' ) {
|
44 |
return self::thumbnailGenerationHarness( $generator, $ID, $path );
|
@@ -50,9 +50,12 @@ class DG_Thumber {
|
|
50 |
* @param int $ID Document ID.
|
51 |
*/
|
52 |
public static function setThumbnailFailed( $ID ) {
|
53 |
-
$options
|
54 |
-
$
|
55 |
-
|
|
|
|
|
|
|
56 |
}
|
57 |
|
58 |
/**
|
@@ -61,14 +64,16 @@ class DG_Thumber {
|
|
61 |
* @param int $ID Document ID
|
62 |
* @param int $pg Page number to get thumb from.
|
63 |
* @param bool $generate_if_missing Whether to attempt generating the thumbnail if missing.
|
|
|
64 |
*
|
65 |
-
* @return string
|
66 |
*/
|
67 |
-
public static function getThumbnail( $ID, $pg = 1, $generate_if_missing = true ) {
|
68 |
$options = self::getOptions();
|
|
|
69 |
|
70 |
// if we haven't saved a thumb, generate one
|
71 |
-
if (
|
72 |
// short-circuit generation if not required
|
73 |
if ( ! $generate_if_missing ) {
|
74 |
return null;
|
@@ -83,38 +88,37 @@ class DG_Thumber {
|
|
83 |
if ( preg_match( $ext_preg, $file ) ) {
|
84 |
if ( DG_Logger::logEnabled() ) {
|
85 |
$toLog = sprintf( __( 'Attempting to generate thumbnail for attachment #%d with (%s)',
|
86 |
-
'document-gallery' ), $ID,
|
87 |
DG_Logger::writeLog( DG_LogLevel::Detail, $toLog );
|
88 |
}
|
89 |
|
90 |
if ( self::thumbnailGenerationHarness( $thumber, $ID, $pg ) ) {
|
91 |
-
// harness updates options so we need a new copy
|
92 |
-
$options = self::getOptions();
|
93 |
break;
|
94 |
}
|
95 |
}
|
96 |
}
|
97 |
}
|
98 |
|
99 |
-
$
|
100 |
-
if ( $
|
101 |
-
if ( $
|
102 |
self::setThumbnailFailed( $ID );
|
103 |
}
|
104 |
|
105 |
// fallback to default thumb for attachment type
|
106 |
$url = self::getDefaultThumbnail( $ID, $pg );
|
|
|
107 |
} else {
|
108 |
-
|
109 |
-
$
|
110 |
}
|
111 |
|
112 |
return $url;
|
113 |
}
|
114 |
|
115 |
/*==========================================================================
|
116 |
-
|
117 |
-
|
118 |
|
119 |
/**
|
120 |
* Uses wp_read_video_metadata() and wp_read_audio_metadata() to retrieve
|
@@ -180,8 +184,8 @@ class DG_Thumber {
|
|
180 |
}
|
181 |
|
182 |
/*==========================================================================
|
183 |
-
|
184 |
-
|
185 |
|
186 |
/**
|
187 |
* Uses WP_Image_Editor_Imagick to generate thumbnails.
|
@@ -367,8 +371,8 @@ class DG_Thumber {
|
|
367 |
}
|
368 |
|
369 |
/*==========================================================================
|
370 |
-
|
371 |
-
|
372 |
|
373 |
/**
|
374 |
* Get thumbnail for document with given ID from default images.
|
@@ -467,22 +471,24 @@ class DG_Thumber {
|
|
467 |
}
|
468 |
|
469 |
/*==========================================================================
|
470 |
-
|
471 |
-
|
472 |
|
473 |
/**
|
474 |
* @return array WP_Post objects for each attachment that has been processed.
|
475 |
*/
|
476 |
public static function getThumbed() {
|
477 |
-
$
|
478 |
-
$
|
|
|
|
|
479 |
'post_type' => 'attachment',
|
480 |
'post_status' => 'inherit',
|
481 |
'post_per_page' => - 1,
|
482 |
-
'post__in' => array_keys( $
|
483 |
);
|
484 |
|
485 |
-
return
|
486 |
}
|
487 |
|
488 |
/**
|
@@ -594,7 +600,7 @@ class DG_Thumber {
|
|
594 |
* @param int $ID ID for the attachment that we need a thumbnail for.
|
595 |
* @param int|string $pg Page number of the attachment to get a thumbnail for or the system path to the image to be used.
|
596 |
*
|
597 |
-
* @return bool
|
598 |
*/
|
599 |
private static function thumbnailGenerationHarness( $generator, $ID, $pg = 1 ) {
|
600 |
// handle system page in $pg variable
|
@@ -607,7 +613,6 @@ class DG_Thumber {
|
|
607 |
|
608 |
// get some useful stuff
|
609 |
$doc_path = get_attached_file( $ID );
|
610 |
-
$doc_url = wp_get_attachment_url( $ID );
|
611 |
$dirname = dirname( $doc_path );
|
612 |
$basename = basename( $doc_path );
|
613 |
if ( false === ( $len = strrpos( $basename, '.' ) ) ) {
|
@@ -617,7 +622,7 @@ class DG_Thumber {
|
|
617 |
$ext = self::getExt( $temp_path );
|
618 |
|
619 |
$thumb_name = self::getUniqueThumbName( $dirname, $extless, $ext );
|
620 |
-
$thumb_path = $dirname
|
621 |
|
622 |
// scale generated image down
|
623 |
$img = wp_get_image_editor( $temp_path );
|
@@ -645,18 +650,19 @@ class DG_Thumber {
|
|
645 |
|
646 |
// do some cleanup
|
647 |
@unlink( $temp_path );
|
648 |
-
self::deleteThumbMeta( $ID );
|
649 |
-
|
650 |
-
// store new thumbnail in DG options
|
651 |
-
$options['thumbs'][ $ID ] = array(
|
652 |
-
'timestamp' => time(),
|
653 |
-
'thumb_url' => preg_replace( '#' . preg_quote( $basename ) . '$#', $thumb_name, $doc_url ),
|
654 |
-
'thumb_path' => $thumb_path,
|
655 |
-
'thumber' => $generator
|
656 |
-
);
|
657 |
-
self::setOptions( $options );
|
658 |
|
659 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
660 |
}
|
661 |
|
662 |
/**
|
@@ -692,36 +698,6 @@ class DG_Thumber {
|
|
692 |
return wp_unique_filename( $dirname, str_replace( '.', '-', $extless ) . '-thumb.' . $ext );
|
693 |
}
|
694 |
|
695 |
-
/**
|
696 |
-
* Removes the existing thumbnail/document meta for the attachment(s)
|
697 |
-
* with the ID(s), if such a thumbnails exists.
|
698 |
-
*
|
699 |
-
* @param int|array $ids
|
700 |
-
*
|
701 |
-
* @return array All IDs that were deleted -- some subset of IDs requested to be deleted.
|
702 |
-
*/
|
703 |
-
public static function deleteThumbMeta( $ids ) {
|
704 |
-
$options = self::getOptions();
|
705 |
-
|
706 |
-
$deleted = array();
|
707 |
-
foreach ( (array) $ids as $id ) {
|
708 |
-
if ( isset( $options['thumbs'][ $id ] ) ) {
|
709 |
-
if ( isset( $options['thumbs'][ $id ]['thumber'] ) ) {
|
710 |
-
@unlink( $options['thumbs'][ $id ]['thumb_path'] );
|
711 |
-
}
|
712 |
-
|
713 |
-
unset( $options['thumbs'][ $id ] );
|
714 |
-
$deleted[] = $id;
|
715 |
-
}
|
716 |
-
}
|
717 |
-
|
718 |
-
if ( count( $deleted ) > 0 ) {
|
719 |
-
self::setOptions( $options );
|
720 |
-
}
|
721 |
-
|
722 |
-
return $deleted;
|
723 |
-
}
|
724 |
-
|
725 |
/**
|
726 |
* Checks whether exec() may be used.
|
727 |
* Source: http://stackoverflow.com/a/12980534/866618
|
38 |
* @param string $path System path to thumbnail.
|
39 |
* @param string $generator Descriptor for generation method -- usually method name.
|
40 |
*
|
41 |
+
* @return DG_Thumb|bool Thumb on success, false on failure.
|
42 |
*/
|
43 |
public static function setThumbnail( $ID, $path, $generator = 'unknown' ) {
|
44 |
return self::thumbnailGenerationHarness( $generator, $ID, $path );
|
50 |
* @param int $ID Document ID.
|
51 |
*/
|
52 |
public static function setThumbnailFailed( $ID ) {
|
53 |
+
$options = self::getOptions();
|
54 |
+
$thumb = new DG_Thumb();
|
55 |
+
$thumb->setPostId( $ID );
|
56 |
+
$thumb->setTimestamp( time() );
|
57 |
+
$thumb->setDimensions( $options['width'] . 'x' . $options['height'] );
|
58 |
+
$thumb->save();
|
59 |
}
|
60 |
|
61 |
/**
|
64 |
* @param int $ID Document ID
|
65 |
* @param int $pg Page number to get thumb from.
|
66 |
* @param bool $generate_if_missing Whether to attempt generating the thumbnail if missing.
|
67 |
+
* @param bool|null &$is_default Whether the returned URL points to a default icon.
|
68 |
*
|
69 |
+
* @return string URL to the thumbnail.
|
70 |
*/
|
71 |
+
public static function getThumbnail( $ID, $pg = 1, $generate_if_missing = true, &$is_default = null ) {
|
72 |
$options = self::getOptions();
|
73 |
+
$dimensions = $options['width'] . 'x' . $options['height'];
|
74 |
|
75 |
// if we haven't saved a thumb, generate one
|
76 |
+
if ( ! DG_Thumb::thumbExists( $ID, $dimensions, false ) ) {
|
77 |
// short-circuit generation if not required
|
78 |
if ( ! $generate_if_missing ) {
|
79 |
return null;
|
88 |
if ( preg_match( $ext_preg, $file ) ) {
|
89 |
if ( DG_Logger::logEnabled() ) {
|
90 |
$toLog = sprintf( __( 'Attempting to generate thumbnail for attachment #%d with (%s)',
|
91 |
+
'document-gallery' ), $ID, DG_Util::callableToString( $thumber ) );
|
92 |
DG_Logger::writeLog( DG_LogLevel::Detail, $toLog );
|
93 |
}
|
94 |
|
95 |
if ( self::thumbnailGenerationHarness( $thumber, $ID, $pg ) ) {
|
|
|
|
|
96 |
break;
|
97 |
}
|
98 |
}
|
99 |
}
|
100 |
}
|
101 |
|
102 |
+
$thumb = DG_Thumb::getThumb( $ID, $dimensions );
|
103 |
+
if ( is_null( $thumb ) || ! $thumb->isSuccess() ) {
|
104 |
+
if ( is_null( $thumb ) ) {
|
105 |
self::setThumbnailFailed( $ID );
|
106 |
}
|
107 |
|
108 |
// fallback to default thumb for attachment type
|
109 |
$url = self::getDefaultThumbnail( $ID, $pg );
|
110 |
+
$is_default = true;
|
111 |
} else {
|
112 |
+
$url = $thumb->getUrl();
|
113 |
+
$is_default = false;
|
114 |
}
|
115 |
|
116 |
return $url;
|
117 |
}
|
118 |
|
119 |
/*==========================================================================
|
120 |
+
* AUDIO VIDEO THUMBNAILS
|
121 |
+
*=========================================================================*/
|
122 |
|
123 |
/**
|
124 |
* Uses wp_read_video_metadata() and wp_read_audio_metadata() to retrieve
|
184 |
}
|
185 |
|
186 |
/*==========================================================================
|
187 |
+
* IMAGICK THUMBNAILS
|
188 |
+
*=========================================================================*/
|
189 |
|
190 |
/**
|
191 |
* Uses WP_Image_Editor_Imagick to generate thumbnails.
|
371 |
}
|
372 |
|
373 |
/*==========================================================================
|
374 |
+
* DEFAULT THUMBNAILS
|
375 |
+
*=========================================================================*/
|
376 |
|
377 |
/**
|
378 |
* Get thumbnail for document with given ID from default images.
|
471 |
}
|
472 |
|
473 |
/*==========================================================================
|
474 |
+
* GENERAL THUMBNAIL HELPER FUNCTIONS
|
475 |
+
*=========================================================================*/
|
476 |
|
477 |
/**
|
478 |
* @return array WP_Post objects for each attachment that has been processed.
|
479 |
*/
|
480 |
public static function getThumbed() {
|
481 |
+
$thumbs = DG_Thumb::getThumbs();
|
482 |
+
if ( ! count( $thumbs ) ) return array();
|
483 |
+
|
484 |
+
$args = array(
|
485 |
'post_type' => 'attachment',
|
486 |
'post_status' => 'inherit',
|
487 |
'post_per_page' => - 1,
|
488 |
+
'post__in' => array_keys( $thumbs )
|
489 |
);
|
490 |
|
491 |
+
return get_posts( $args );
|
492 |
}
|
493 |
|
494 |
/**
|
600 |
* @param int $ID ID for the attachment that we need a thumbnail for.
|
601 |
* @param int|string $pg Page number of the attachment to get a thumbnail for or the system path to the image to be used.
|
602 |
*
|
603 |
+
* @return DG_Thumb|bool The generated thumbnail or false on failure.
|
604 |
*/
|
605 |
private static function thumbnailGenerationHarness( $generator, $ID, $pg = 1 ) {
|
606 |
// handle system page in $pg variable
|
613 |
|
614 |
// get some useful stuff
|
615 |
$doc_path = get_attached_file( $ID );
|
|
|
616 |
$dirname = dirname( $doc_path );
|
617 |
$basename = basename( $doc_path );
|
618 |
if ( false === ( $len = strrpos( $basename, '.' ) ) ) {
|
622 |
$ext = self::getExt( $temp_path );
|
623 |
|
624 |
$thumb_name = self::getUniqueThumbName( $dirname, $extless, $ext );
|
625 |
+
$thumb_path = "$dirname/$thumb_name";
|
626 |
|
627 |
// scale generated image down
|
628 |
$img = wp_get_image_editor( $temp_path );
|
650 |
|
651 |
// do some cleanup
|
652 |
@unlink( $temp_path );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
653 |
|
654 |
+
// save new thumb
|
655 |
+
DG_Logger::writeLog( DG_LogLevel::Detail, 'Creating thumb object.' );
|
656 |
+
$upload = wp_upload_dir();
|
657 |
+
$thumb = new DG_Thumb();
|
658 |
+
$thumb->setPostId( $ID );
|
659 |
+
$thumb->setDimensions( $options['width'] . 'x' . $options['height'] );
|
660 |
+
$thumb->setTimestamp( time() );
|
661 |
+
$thumb->setRelativePath( substr( $thumb_path, strlen( $upload['basedir'] ) + 1 ) );
|
662 |
+
$thumb->setGenerator( DG_Util::callableToString( $generator ) );
|
663 |
+
$thumb->save();
|
664 |
+
|
665 |
+
return $thumb;
|
666 |
}
|
667 |
|
668 |
/**
|
698 |
return wp_unique_filename( $dirname, str_replace( '.', '-', $extless ) . '-thumb.' . $ext );
|
699 |
}
|
700 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
701 |
/**
|
702 |
* Checks whether exec() may be used.
|
703 |
* Source: http://stackoverflow.com/a/12980534/866618
|
inc/class-util.php
CHANGED
@@ -35,18 +35,6 @@ class DG_Util {
|
|
35 |
return $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );
|
36 |
}
|
37 |
|
38 |
-
/**
|
39 |
-
* Whether the given attachment has a thumbanil graphic.
|
40 |
-
*
|
41 |
-
* @param $ID int The id of the attachment to be checked.
|
42 |
-
* @return bool Whether the given attachment has a thumbnail image.
|
43 |
-
*/
|
44 |
-
public static function hasThumb($ID) {
|
45 |
-
$options = DocumentGallery::getOptions();
|
46 |
-
$thumbs = $options['thumber']['thumbs'];
|
47 |
-
return array_key_exists($ID, $thumbs) && ! empty( $thumbs[ $ID ]['thumber'] );
|
48 |
-
}
|
49 |
-
|
50 |
/**
|
51 |
* @param mixed $maybeint Data you wish to have converted to a positive integer.
|
52 |
*
|
@@ -107,14 +95,24 @@ class DG_Util {
|
|
107 |
* @param bool $in_footer For scripts, dictates whether to put in footer.
|
108 |
*/
|
109 |
public static function enqueueAsset( $handle, $src, $deps = array(), $in_footer = true ) {
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
if ( preg_match( '/.js/', $src ) ) {
|
115 |
-
wp_enqueue_script( $handle, DG_URL . $src, $deps, DG_VERSION, $in_footer );
|
116 |
} else {
|
117 |
-
wp_enqueue_style( $handle,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
118 |
}
|
|
|
119 |
}
|
120 |
}
|
35 |
return $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );
|
36 |
}
|
37 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
/**
|
39 |
* @param mixed $maybeint Data you wish to have converted to a positive integer.
|
40 |
*
|
95 |
* @param bool $in_footer For scripts, dictates whether to put in footer.
|
96 |
*/
|
97 |
public static function enqueueAsset( $handle, $src, $deps = array(), $in_footer = true ) {
|
98 |
+
$src = self::getAssetPath( $src );
|
99 |
+
if ( stripos( strrev( $src ), 'sj.' ) === 0 ) {
|
100 |
+
wp_enqueue_script( $handle, $src, $deps, DG_VERSION, $in_footer );
|
|
|
|
|
|
|
101 |
} else {
|
102 |
+
wp_enqueue_style( $handle, $src, $deps, DG_VERSION );
|
103 |
+
}
|
104 |
+
}
|
105 |
+
|
106 |
+
/**
|
107 |
+
* Converts path to min version when WP is not running in debug mode and fully-qualifies path.
|
108 |
+
*
|
109 |
+
* @param $src string Relative path to asset from DG_URL.
|
110 |
+
* @return string The fully-qualified, potentially min version of the given path.
|
111 |
+
*/
|
112 |
+
public static function getAssetPath( $src ) {
|
113 |
+
if ( !defined('WP_DEBUG') || !WP_DEBUG ) {
|
114 |
+
$src = preg_replace( '/^(.*)\.(css|js)$/', '$1.min.$2', $src, 1 );
|
115 |
}
|
116 |
+
return DG_URL . $src;
|
117 |
}
|
118 |
}
|