Version Description
Download this release
Release Info
Developer | dan.rossiter |
Plugin | Document Gallery |
Version | 3.0.0-beta |
Comparing to | |
See all releases |
Code changes from version 2.3.7 to 3.0.0-beta
- README.txt +90 -58
- admin/class-admin.php +306 -133
- assets/css/admin.css +68 -6
- assets/css/style.css +4 -7
- assets/js/admin.js +183 -15
- document-gallery.php +20 -8
- inc/class-document.php +10 -11
- inc/class-gallery.php +181 -151
- inc/class-setup.php +75 -17
- inc/class-thumber.php +74 -154
- inc/class-util.php +80 -0
- log/index.php +2 -0
README.txt
CHANGED
@@ -59,8 +59,7 @@ customize behavior with various attributes, seen below:
|
|
59 |
|
60 |
`[dg [fancy=<true/false>] [attachment_pg=<true/false>]
|
61 |
[category/custom_taxon_name=<**comma-separated list of taxon values**> [relation=<AND/OR>]]
|
62 |
-
[descriptions=<true/false>] [
|
63 |
-
[images=<true/false>] [localpost=<true/false>] [order=<ASC/DESC>] [orderby=<**see below**>]]`
|
64 |
|
65 |
Though the shortcode above may seem far from "short," none of the attributes are
|
66 |
required and most users will find that the plugin meets your needs "out of the box"
|
@@ -77,7 +76,7 @@ under `Settings -> Document Gallery`.
|
|
77 |
|
78 |
This option determines whether each document icon will link to the actual file
|
79 |
or to its attachment page. If you want the user to be able to click on the
|
80 |
-
icon and directly
|
81 |
(the default). If you have information on the attachment page that you want the
|
82 |
link to go to, use `attachment_pg=true`.
|
83 |
|
@@ -91,6 +90,12 @@ or `taxon_name=taxon_value`. Multiple values for a single taxon may be separated
|
|
91 |
by commas. Note that if a taxon value contains spaces then the entire comma-
|
92 |
delimited list must be quoted.
|
93 |
|
|
|
|
|
|
|
|
|
|
|
|
|
94 |
**Descriptions Option**
|
95 |
|
96 |
If `true`, each document will take its own line with the description displayed
|
@@ -106,17 +111,51 @@ The success in generating thumbs will depend mostly on what your server supports
|
|
106 |
To fine-tune how thumbnails are generated, visit `Settings -> Document Gallery`
|
107 |
in your site's dashboard.
|
108 |
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
114 |
|
115 |
**Limit Option** *(New in Version 2.3)*
|
116 |
|
117 |
As the name suggests, this value will limit how many results are returned in the gallery.
|
118 |
If set to *-1*, the limit is infinite.
|
119 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
120 |
**Order Option**
|
121 |
|
122 |
This option works alongside the `orderby` option to determine whether the
|
@@ -143,31 +182,6 @@ documents are displayed in ascending or descending order.
|
|
143 |
* `none` - No order (available with Version 2.8).
|
144 |
* `post__in` - Preserve post ID order given in the post__in array.
|
145 |
|
146 |
-
**Images Option** *(New in Version 1.2)*
|
147 |
-
|
148 |
-
This option will tell the plugin to include all images attached to to a page or
|
149 |
-
post in addition to all documents.
|
150 |
-
|
151 |
-
**IDs Option** *(New in Version 1.2)*
|
152 |
-
|
153 |
-
This is an advanced option intended for experienced WordPress users. If this
|
154 |
-
option is used, the plugin will ignore attached documents, instead including
|
155 |
-
all attachments defined by the `ids` attribute (e.g.: `ids=10,2,4,42`).
|
156 |
-
|
157 |
-
*Note: If this attribute is used, the `order`, `orderby`, `images` and other
|
158 |
-
attributes which generally determine which attachments to include or how to
|
159 |
-
order them will be ignored. Order is defined by the order the ids are
|
160 |
-
provided.*
|
161 |
-
|
162 |
-
**Localpost Option** *(New in Version 1.4)*
|
163 |
-
|
164 |
-
By default a document gallery only looks at attachments of the page/post where
|
165 |
-
the `[dg]` shortcode is used. If you would like to search beyond that local scope,
|
166 |
-
you must set `localpost=false`.
|
167 |
-
|
168 |
-
This option would probably be useful especially when querying with the *category
|
169 |
-
or taxonomy* option, though it can be used with any options you chose.
|
170 |
-
|
171 |
**Relation Option** *(New in Version 1.4)*
|
172 |
|
173 |
The relation option should only be used when also using the *category or custom
|
@@ -273,7 +287,6 @@ These tags are as follows:
|
|
273 |
* **%title_attribute%**: The escaped title (above), safe for using HTML tag attributes.
|
274 |
* **%description%**: The attachment description (only present when rendering descriptions).
|
275 |
|
276 |
-
|
277 |
**Filter Thumbnail Generation Methods**
|
278 |
|
279 |
Document Gallery provides the `dg_thumbers` filter, which allows developers to
|
@@ -349,9 +362,35 @@ function dg_get_audio_video_thumbnail($ID, $pg) {
|
|
349 |
return $temp_file;
|
350 |
}`
|
351 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
352 |
== Frequently Asked Questions ==
|
353 |
|
354 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
355 |
= Q: Why is [insert thumbnail generation method] enabled on one of my WordPress installs, but not on another one? =
|
356 |
|
357 |
A: Document Gallery works very hard behind the scenes to ensure that it enables
|
@@ -373,30 +412,6 @@ thumbnail, this is much more work than is needed. Ghostscript, on the other hand
|
|
373 |
can handle reading only one page into memory, thus doing much less work before
|
374 |
returning our thumbnail.
|
375 |
|
376 |
-
= Q: Why isn't Google Drive Viewer enabled by default? =
|
377 |
-
|
378 |
-
A: Google Drive Viewer is the most commonly-supported thumbnail generation method,
|
379 |
-
alongside the Audio/Video generation, but is disabled by default. The reason
|
380 |
-
for this is that in order to use this method, Document Gallery has to send your
|
381 |
-
document over to Google's servers, where Google will generate the thumbnail for
|
382 |
-
you. For most users, this shouldn't be a big deal, but since some users
|
383 |
-
retain sensitive documents on their site, this was made opt-in to avoid
|
384 |
-
compromising anyone's security. If you don't have sensitive documents, I
|
385 |
-
would recommend enabling it, since it's currently the only way to generate a
|
386 |
-
thumbnail for any of the Microsoft Office files, as well as some less common
|
387 |
-
file types.
|
388 |
-
|
389 |
-
= Q: Ghostscript is installed on my server, but it's not working! =
|
390 |
-
|
391 |
-
A: Document Gallery does a pretty good job of detecting where Ghostscript is installed,
|
392 |
-
but on some installs it may need a little help. To check whether this is the case,
|
393 |
-
navigate to `Dashboard -> Settings -> Document Gallery` and see if there is a notice
|
394 |
-
next to the Ghostscript checkbox indicating that your server is not properly configured.
|
395 |
-
If that notice does exist, the next step is to go to the `Advanced` tab on that same page
|
396 |
-
and see if the Ghostscript path is set. If it is not, you'll need to manually fill it
|
397 |
-
with the location for your Ghostscript install (eg: `/usr/local/bin/gs`). Once that
|
398 |
-
change is saved, the Ghostscript checkbox should be enabled on the first tab.
|
399 |
-
|
400 |
== Screenshots ==
|
401 |
|
402 |
1. This is an example of "fancy" thumbnails. The images are a copy of the front
|
@@ -416,6 +431,23 @@ To see a list of features planned for the future as well as to propose your own
|
|
416 |
ideas for future Document Gallery development, take a look at our
|
417 |
[issue tracker](https://github.com/thenadz/document-gallery/issues).
|
418 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
419 |
= 2.3.7 =
|
420 |
* **Bug Fix:** There was an issue that resulted in an error being thrown in certain situations.
|
421 |
|
59 |
|
60 |
`[dg [fancy=<true/false>] [attachment_pg=<true/false>]
|
61 |
[category/custom_taxon_name=<**comma-separated list of taxon values**> [relation=<AND/OR>]]
|
62 |
+
[descriptions=<true/false>] [order=<ASC/DESC>] [orderby=<**see below**>]]`
|
|
|
63 |
|
64 |
Though the shortcode above may seem far from "short," none of the attributes are
|
65 |
required and most users will find that the plugin meets your needs "out of the box"
|
76 |
|
77 |
This option determines whether each document icon will link to the actual file
|
78 |
or to its attachment page. If you want the user to be able to click on the
|
79 |
+
icon and directly receive the option to download then use `attachment_pg=false`
|
80 |
(the default). If you have information on the attachment page that you want the
|
81 |
link to go to, use `attachment_pg=true`.
|
82 |
|
90 |
by commas. Note that if a taxon value contains spaces then the entire comma-
|
91 |
delimited list must be quoted.
|
92 |
|
93 |
+
**Columns Option** *(New in Version 3.0)*
|
94 |
+
|
95 |
+
The columns option does what it sounds like -- sets how many columns to use in
|
96 |
+
rendering your gallery. With `columns=-1`, you will get an infinite number of
|
97 |
+
columns. In other words, only 1 row with all icons.
|
98 |
+
|
99 |
**Descriptions Option**
|
100 |
|
101 |
If `true`, each document will take its own line with the description displayed
|
111 |
To fine-tune how thumbnails are generated, visit `Settings -> Document Gallery`
|
112 |
in your site's dashboard.
|
113 |
|
114 |
+
**ID Option** *(New in Version 3.0)*
|
115 |
+
|
116 |
+
This option indicates from which parent post/page to retrieve attachments.
|
117 |
+
If not explicitly set, the default will be the post/page where the shortcode
|
118 |
+
is being used.
|
119 |
+
|
120 |
+
If you do not wish to filter by parent, `id=-1` will match all attachments.
|
121 |
+
|
122 |
+
**IDs Option** *(New in Version 1.2)*
|
123 |
+
|
124 |
+
This is an advanced option intended for experienced WordPress users. If this
|
125 |
+
option is used, the plugin will ignore attached documents, instead including
|
126 |
+
all attachments defined by the `ids` attribute (e.g.: `ids=10,2,4,42`).
|
127 |
+
|
128 |
+
*Note: If this attribute is used, order defaults to the order of IDs given
|
129 |
+
rather than menu_order unless order is explicitly stated.*
|
130 |
+
|
131 |
+
**Images Option** *(New in Version 1.2)*
|
132 |
+
|
133 |
+
This option will tell the plugin to include all images attached to to a page or
|
134 |
+
post in addition to all documents.
|
135 |
+
|
136 |
+
**Include/Exclude Options** *(New in Version 3.0)*
|
137 |
+
|
138 |
+
As the name suggests, these options allow for explicitly adding or removing
|
139 |
+
matched attachments in your gallery. Like with the IDs options above, these
|
140 |
+
options take a comma-delimited list of attachment IDs.
|
141 |
|
142 |
**Limit Option** *(New in Version 2.3)*
|
143 |
|
144 |
As the name suggests, this value will limit how many results are returned in the gallery.
|
145 |
If set to *-1*, the limit is infinite.
|
146 |
|
147 |
+
**MIME Types Option** *(New in Version 3.0)*
|
148 |
+
|
149 |
+
This is a comma-delimited list of all
|
150 |
+
[MIME types](http://en.wikipedia.org/wiki/Internet_media_type#List_of_common_media_types)
|
151 |
+
to be included in the gallery. Most users will not need to modify this value.
|
152 |
+
|
153 |
+
One example use-case would be to include images in your gallery (which are
|
154 |
+
not included by default). To do this, you would simply set
|
155 |
+
`mime_types=application,video,text,audio,image`, where "image" is the only difference
|
156 |
+
from the default value. You could also create a gallery which only includes PDFs
|
157 |
+
by setting `mime_types=application/pdf`.
|
158 |
+
|
159 |
**Order Option**
|
160 |
|
161 |
This option works alongside the `orderby` option to determine whether the
|
182 |
* `none` - No order (available with Version 2.8).
|
183 |
* `post__in` - Preserve post ID order given in the post__in array.
|
184 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
185 |
**Relation Option** *(New in Version 1.4)*
|
186 |
|
187 |
The relation option should only be used when also using the *category or custom
|
287 |
* **%title_attribute%**: The escaped title (above), safe for using HTML tag attributes.
|
288 |
* **%description%**: The attachment description (only present when rendering descriptions).
|
289 |
|
|
|
290 |
**Filter Thumbnail Generation Methods**
|
291 |
|
292 |
Document Gallery provides the `dg_thumbers` filter, which allows developers to
|
362 |
return $temp_file;
|
363 |
}`
|
364 |
|
365 |
+
**Filter Inclusion of Default Document Gallery CSS**
|
366 |
+
|
367 |
+
If you wish to completely replace Document Gallery styling with your own CSS, you can prevent any any
|
368 |
+
CSS being loaded by returning false in `dg_use_default_gallery_style` filter, like so:
|
369 |
+
`add_filter('dg_use_default_gallery_style', '__return_false');`
|
370 |
+
|
371 |
+
*NOTE: By design, this will **NOT** disable inclusion of any custom CSS set at
|
372 |
+
`Dashboard -> Settings -> Document Gallery`*
|
373 |
+
|
374 |
== Frequently Asked Questions ==
|
375 |
|
376 |
|
377 |
+
= Q: Ghostscript is installed on my server, but it's not working! =
|
378 |
+
|
379 |
+
A: Document Gallery does a pretty good job of detecting where Ghostscript is installed,
|
380 |
+
but on some installs it may need a little help. To check whether this is the case,
|
381 |
+
navigate to `Dashboard -> Settings -> Document Gallery` and see if there is a notice
|
382 |
+
next to the Ghostscript checkbox indicating that your server is not properly configured.
|
383 |
+
If that notice does exist, the next step is to go to the `Advanced` tab on that same page
|
384 |
+
and see if the Ghostscript path is set. If it is not, you'll need to manually fill it
|
385 |
+
with the location for your Ghostscript install (eg: `/usr/local/bin/gs`). Once that
|
386 |
+
change is saved, the Ghostscript checkbox should be enabled on the first tab.
|
387 |
+
|
388 |
+
= Q: Why are all of my document icons in a single column? =
|
389 |
+
|
390 |
+
A: Assuming that you do not have the `columns` attribute set to 1, the likely cause
|
391 |
+
of this behavior is that descriptions are enabled. To fix this, simply use
|
392 |
+
`[dg descriptions=false]`.
|
393 |
+
|
394 |
= Q: Why is [insert thumbnail generation method] enabled on one of my WordPress installs, but not on another one? =
|
395 |
|
396 |
A: Document Gallery works very hard behind the scenes to ensure that it enables
|
412 |
can handle reading only one page into memory, thus doing much less work before
|
413 |
returning our thumbnail.
|
414 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
415 |
== Screenshots ==
|
416 |
|
417 |
1. This is an example of "fancy" thumbnails. The images are a copy of the front
|
431 |
ideas for future Document Gallery development, take a look at our
|
432 |
[issue tracker](https://github.com/thenadz/document-gallery/issues).
|
433 |
|
434 |
+
= 3.0 =
|
435 |
+
* **Enhancement:** Thumbnails can now be manually overridden. To do this, either navigate to
|
436 |
+
`Dashboard -> Settings -> Document Gallery -> Thumbnail Management` and add the image
|
437 |
+
to the target attachment, or set the thumbnail in the attachment edit window.
|
438 |
+
* **Enhancement:** Users can now specify the number of columns for a gallery.
|
439 |
+
* **Enhancement:** Users can now create galleries with specific filetype(s) by using the `mime_types`
|
440 |
+
option. Thanks for suggesting this functionality,
|
441 |
+
[mepmepmep](https://wordpress.org/support/topic/dynamic-gallery-for-all-documents-of-a-certain-type)!
|
442 |
+
* **Enhancement:** Options to `include` or `exclude` specific attachments in a gallery have been added.
|
443 |
+
* **Enhancement:** The document gallery CSS has been modified to make all icon images responsive.
|
444 |
+
We've also added the `dg_use_default_gallery_style` so that developers may completely disabled
|
445 |
+
Document Gallery styles and replace it with their own.
|
446 |
+
* **Deprecation:** The deprecated `dg_doc_icon` filter has been removed. Developers should use
|
447 |
+
`dg_icon_template`.
|
448 |
+
* **Deprecation:** The `localpost` option has been deprecated and will be removed at a future date.
|
449 |
+
If you are currently using `localpost=false` then it should be replaced by `id=-1`.
|
450 |
+
|
451 |
= 2.3.7 =
|
452 |
* **Bug Fix:** There was an issue that resulted in an error being thrown in certain situations.
|
453 |
|
admin/class-admin.php
CHANGED
@@ -6,19 +6,19 @@ class DG_Admin {
|
|
6 |
* @var string The hook for the Document Gallery settings page.
|
7 |
*/
|
8 |
private static $hook;
|
9 |
-
|
10 |
/**
|
11 |
* @var string The current tab being rendered.
|
12 |
*/
|
13 |
private static $current;
|
14 |
-
|
15 |
/**
|
16 |
* NOTE: This should only ever be accessed through getTabs().
|
17 |
*
|
18 |
* @var multitype:string Associative array containing all tab names, keyed by tab slug.
|
19 |
*/
|
20 |
private static $tabs;
|
21 |
-
|
22 |
/**
|
23 |
* Returns reference to tabs array, initializing if needed.
|
24 |
*
|
@@ -32,26 +32,26 @@ class DG_Admin {
|
|
32 |
'Logging' => __('Logging', 'document-gallery'),
|
33 |
'Advanced' => __('Advanced', 'document-gallery'));
|
34 |
}
|
35 |
-
|
36 |
return self::$tabs;
|
37 |
}
|
38 |
-
|
39 |
/**
|
40 |
* Renders Document Gallery options page.
|
41 |
*/
|
42 |
public static function renderOptions() { ?>
|
43 |
<div class="wrap">
|
44 |
-
|
45 |
|
46 |
-
|
47 |
<?php foreach (self::getTabs() as $tab => $name) {
|
48 |
$class = ($tab == self::$current) ? ' nav-tab-active' : '';
|
49 |
echo '<a class="nav-tab '.$tab.'-tab'.$class.'" href="?page=' . DG_OPTION_NAME . '&tab='.$tab.'">'.$name.'</a>';
|
50 |
} ?>
|
51 |
</h2>
|
52 |
|
53 |
-
|
54 |
-
|
55 |
<?php
|
56 |
settings_fields(DG_OPTION_NAME);
|
57 |
do_settings_sections(DG_OPTION_NAME);
|
@@ -71,6 +71,22 @@ class DG_Admin {
|
|
71 |
$settings = '<a href="options-general.php?page=' . DG_OPTION_NAME . '">' .
|
72 |
__('Settings', 'document-gallery') . '</a>';
|
73 |
array_unshift($links, $settings);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
74 |
return $links;
|
75 |
}
|
76 |
|
@@ -84,15 +100,19 @@ class DG_Admin {
|
|
84 |
'manage_options', DG_OPTION_NAME, array(__CLASS__, 'renderOptions'));
|
85 |
add_action('admin_enqueue_scripts', array(__CLASS__, 'enqueueScriptsAndStyles'));
|
86 |
}
|
87 |
-
|
88 |
/**
|
89 |
* Enqueues styles and scripts for the admin settings page.
|
90 |
*/
|
91 |
public static function enqueueScriptsAndStyles($hook) {
|
92 |
if ($hook !== DG_Admin::$hook) return;
|
93 |
-
|
94 |
wp_enqueue_style('document-gallery-admin', DG_URL . 'assets/css/admin.css', null, DG_VERSION);
|
95 |
wp_enqueue_script('document-gallery-admin', DG_URL . 'assets/js/admin.js', array('jquery'), DG_VERSION, true);
|
|
|
|
|
|
|
|
|
96 |
}
|
97 |
|
98 |
/**
|
@@ -111,7 +131,7 @@ class DG_Admin {
|
|
111 |
$funct = 'register' . self::$current . 'Settings';
|
112 |
DG_Admin::$funct();
|
113 |
}
|
114 |
-
|
115 |
/**
|
116 |
* Registers settings for the general tab.
|
117 |
*/
|
@@ -148,6 +168,19 @@ class DG_Admin {
|
|
148 |
'description' => __('Link to attachment page rather than to file', 'document-gallery')
|
149 |
));
|
150 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
151 |
add_settings_field(
|
152 |
'gallery_defaults_descriptions', 'descriptions',
|
153 |
array(__CLASS__, 'renderCheckboxField'),
|
@@ -172,30 +205,6 @@ class DG_Admin {
|
|
172 |
'description' => __('Use auto-generated document thumbnails', 'document-gallery')
|
173 |
));
|
174 |
|
175 |
-
add_settings_field(
|
176 |
-
'gallery_defaults_images', 'images',
|
177 |
-
array(__CLASS__, 'renderCheckboxField'),
|
178 |
-
DG_OPTION_NAME, 'gallery_defaults',
|
179 |
-
array (
|
180 |
-
'label_for' => 'label_gallery_defaults_images',
|
181 |
-
'name' => 'gallery_defaults][images',
|
182 |
-
'value' => esc_attr($defaults['images']),
|
183 |
-
'option_name' => DG_OPTION_NAME,
|
184 |
-
'description' => __('Include image attachments in gallery', 'document-gallery')
|
185 |
-
));
|
186 |
-
|
187 |
-
add_settings_field(
|
188 |
-
'gallery_defaults_localpost', 'localpost',
|
189 |
-
array(__CLASS__, 'renderCheckboxField'),
|
190 |
-
DG_OPTION_NAME, 'gallery_defaults',
|
191 |
-
array (
|
192 |
-
'label_for' => 'label_gallery_defaults_localpost',
|
193 |
-
'name' => 'gallery_defaults][localpost',
|
194 |
-
'value' => esc_attr($defaults['localpost']),
|
195 |
-
'option_name' => DG_OPTION_NAME,
|
196 |
-
'description' => __('Only look for attachments in post where [dg] is used', 'document-gallery')
|
197 |
-
));
|
198 |
-
|
199 |
add_settings_field(
|
200 |
'gallery_defaults_order', 'order',
|
201 |
array(__CLASS__, 'renderSelectField'),
|
@@ -245,8 +254,22 @@ class DG_Admin {
|
|
245 |
'value' => esc_attr($defaults['limit']),
|
246 |
'type' => 'number" min="-1" step="1',
|
247 |
'option_name' => DG_OPTION_NAME,
|
248 |
-
'description' => __('Limit the number of documents included. -1 means no limit.', 'document-gallery')
|
|
|
249 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
250 |
add_settings_field(
|
251 |
'gallery_defaults_post_status', 'post_status',
|
252 |
array(__CLASS__, 'renderSelectField'),
|
@@ -272,7 +295,7 @@ class DG_Admin {
|
|
272 |
'option_name' => DG_OPTION_NAME,
|
273 |
'description' => __('Which post type to look for when querying documents.', 'document-gallery')
|
274 |
));
|
275 |
-
|
276 |
add_settings_field(
|
277 |
'thumbnail_generation_av', 'Audio/Video',
|
278 |
array(__CLASS__, 'renderCheckboxField'),
|
@@ -315,21 +338,6 @@ class DG_Admin {
|
|
315 |
'disabled' => !DG_Thumber::isImagickAvailable()
|
316 |
));
|
317 |
|
318 |
-
add_settings_field(
|
319 |
-
'thumbnail_generation_google', 'Google Drive Viewer',
|
320 |
-
array(__CLASS__, 'renderCheckboxField'),
|
321 |
-
DG_OPTION_NAME, 'thumbnail_generation',
|
322 |
-
array (
|
323 |
-
'label_for' => 'label_thumbnail_generation_google',
|
324 |
-
'name' => 'thumbnail_generation][google',
|
325 |
-
'value' => esc_attr($active['google']),
|
326 |
-
'option_name' => DG_OPTION_NAME,
|
327 |
-
'description' => DG_Thumber::isGoogleDriveAvailable()
|
328 |
-
? __('Use <a href="https://drive.google.com/viewer" target="_blank">Google Drive Viewer</a> to generate thumbnails for MS Office files and many other file types remotely.', 'document-gallery')
|
329 |
-
: __('Your server does not allow remote HTTP access.', 'document-gallery'),
|
330 |
-
'disabled' => !DG_Thumber::isGoogleDriveAvailable()
|
331 |
-
));
|
332 |
-
|
333 |
add_settings_field(
|
334 |
'thumbnail_generation_width', 'Max Thumbnail Dimensions',
|
335 |
array(__CLASS__, 'renderMultiTextField'),
|
@@ -351,7 +359,7 @@ class DG_Admin {
|
|
351 |
'description' => __('The max width and height (in pixels) that thumbnails will be generated.', 'document-gallery'))
|
352 |
));
|
353 |
}
|
354 |
-
|
355 |
/**
|
356 |
* Registers settings for the thumbnail management tab.
|
357 |
*/
|
@@ -360,7 +368,7 @@ class DG_Admin {
|
|
360 |
'thumbnail_table', '',
|
361 |
array(__CLASS__, 'renderThumbnailSection'), DG_OPTION_NAME);
|
362 |
}
|
363 |
-
|
364 |
/**
|
365 |
* Registers settings for the logging tab.
|
366 |
*/
|
@@ -369,17 +377,17 @@ class DG_Admin {
|
|
369 |
'logging_table', '',
|
370 |
array(__CLASS__, 'renderLoggingSection'), DG_OPTION_NAME);
|
371 |
}
|
372 |
-
|
373 |
/**
|
374 |
* Registers settings for the advanced tab.
|
375 |
*/
|
376 |
private static function registerAdvancedSettings() {
|
377 |
global $dg_options;
|
378 |
-
|
379 |
add_settings_section(
|
380 |
'advanced', __('Advanced Thumbnail Generation', 'document-gallery'),
|
381 |
array(__CLASS__, 'renderAdvancedSection'), DG_OPTION_NAME);
|
382 |
-
|
383 |
add_settings_field(
|
384 |
'advanced_logging', 'Logging',
|
385 |
array(__CLASS__, 'renderCheckboxField'),
|
@@ -391,7 +399,7 @@ class DG_Admin {
|
|
391 |
'option_name' => DG_OPTION_NAME,
|
392 |
'description' => __('Whether to log debug and error information related to Document Gallery.', 'document-gallery')
|
393 |
));
|
394 |
-
|
395 |
add_settings_field(
|
396 |
'advanced_validation', 'Option Validation',
|
397 |
array(__CLASS__, 'renderCheckboxField'),
|
@@ -435,7 +443,7 @@ class DG_Admin {
|
|
435 |
'advanced_options_dump', __('Options Array Dump', 'document-gallery'),
|
436 |
array(__CLASS__, 'renderOptionsDumpSection'), DG_OPTION_NAME);
|
437 |
}
|
438 |
-
|
439 |
/**
|
440 |
* Validates submitted options, sanitizing any invalid options.
|
441 |
* @param array $values User-submitted new options.
|
@@ -466,12 +474,12 @@ class DG_Admin {
|
|
466 |
|
467 |
// handle gallery shortcode defaults
|
468 |
$errs = array();
|
469 |
-
$ret['gallery'] = DG_Gallery::sanitizeDefaults($values['gallery_defaults'], $errs
|
470 |
|
471 |
foreach ($errs as $k => $v) {
|
472 |
add_settings_error(DG_OPTION_NAME, str_replace('_', '-', $k), $v);
|
473 |
}
|
474 |
-
|
475 |
// handle setting width
|
476 |
if (isset($values['thumbnail_generation']['width'])) {
|
477 |
$width = (int)$values['thumbnail_generation']['width'];
|
@@ -484,7 +492,7 @@ class DG_Admin {
|
|
484 |
|
485 |
unset($values['thumbnail_generation']['width']);
|
486 |
}
|
487 |
-
|
488 |
// handle setting height
|
489 |
if (isset($values['thumbnail_generation']['height'])) {
|
490 |
$height = (int)$values['thumbnail_generation']['height'];
|
@@ -497,7 +505,7 @@ class DG_Admin {
|
|
497 |
|
498 |
unset($values['thumbnail_generation']['width']);
|
499 |
}
|
500 |
-
|
501 |
// delete thumb cache to force regeneration if max dimensions changed
|
502 |
if ($ret['thumber']['width'] !== $dg_options['thumber']['width'] ||
|
503 |
$ret['thumber']['height'] !== $dg_options['thumber']['height']) {
|
@@ -506,7 +514,7 @@ class DG_Admin {
|
|
506 |
@unlink($v['thumb_path']);
|
507 |
}
|
508 |
}
|
509 |
-
|
510 |
$ret['thumber']['thumbs'] = array();
|
511 |
$thumbs_cleared = true;
|
512 |
}
|
@@ -538,7 +546,7 @@ class DG_Admin {
|
|
538 |
|
539 |
return $ret;
|
540 |
}
|
541 |
-
|
542 |
/**
|
543 |
* Validates thumbnail management settings, sanitizing any invalid options.
|
544 |
* @param array $values User-submitted new options.
|
@@ -547,27 +555,111 @@ class DG_Admin {
|
|
547 |
private static function validateThumbnailSettings($values) {
|
548 |
global $dg_options;
|
549 |
$ret = $dg_options;
|
550 |
-
|
551 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
552 |
$deleted = array_values(array_intersect(array_keys($dg_options['thumber']['thumbs']), $values['ids']));
|
553 |
-
|
554 |
foreach ($deleted as $k) {
|
555 |
if (isset($ret['thumber']['thumbs'][$k]['thumber'])) {
|
556 |
@unlink($ret['thumber']['thumbs'][$k]['thumb_path']);
|
557 |
}
|
558 |
-
|
559 |
unset($ret['thumber']['thumbs'][$k]);
|
560 |
}
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
565 |
}
|
566 |
}
|
567 |
-
|
|
|
|
|
|
|
|
|
|
|
568 |
return $ret;
|
569 |
}
|
570 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
571 |
/**
|
572 |
* Validates logging settings, sanitizing any invalid options.
|
573 |
* @param array $values User-submitted new options.
|
@@ -580,7 +672,7 @@ class DG_Admin {
|
|
580 |
}
|
581 |
return $dg_options;
|
582 |
}
|
583 |
-
|
584 |
/**
|
585 |
* Validates advanced settings, sanitizing any invalid options.
|
586 |
* @param array $values User-submitted new options.
|
@@ -589,7 +681,7 @@ class DG_Admin {
|
|
589 |
private static function validateAdvancedSettings($values) {
|
590 |
global $dg_options;
|
591 |
$ret = $dg_options;
|
592 |
-
|
593 |
// handle setting the Ghostscript path
|
594 |
if (isset($values['gs']) &&
|
595 |
0 != strcmp($values['gs'], $ret['thumber']['gs'])) {
|
@@ -600,7 +692,7 @@ class DG_Admin {
|
|
600 |
__('Invalid Ghostscript path given: ', 'document-gallery') . $values['gs']);
|
601 |
}
|
602 |
}
|
603 |
-
|
604 |
// handle setting timeout
|
605 |
if (isset($values['timeout'])) {
|
606 |
$timeout = (int)$values['timeout'];
|
@@ -611,7 +703,7 @@ class DG_Admin {
|
|
611 |
__('Invalid timeout given: ', 'document-gallery') . $values['timeout']);
|
612 |
}
|
613 |
}
|
614 |
-
|
615 |
// validation checkbox
|
616 |
$ret['validation'] = isset($values['validation']);
|
617 |
|
@@ -620,7 +712,7 @@ class DG_Admin {
|
|
620 |
|
621 |
return $ret;
|
622 |
}
|
623 |
-
|
624 |
/**
|
625 |
* @return bool Whether to register settings.
|
626 |
*/
|
@@ -658,13 +750,13 @@ class DG_Admin {
|
|
658 |
__('Enter custom CSS styling for use with document galleries. To see which ids and classes you can style, take a look at <a href="%s" target="_blank">style.css</a>.'),
|
659 |
DG_URL . 'assets/css/style.css'); ?></p>
|
660 |
<table class="form-table">
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
|
666 |
-
|
667 |
-
|
668 |
</table>
|
669 |
<?php }
|
670 |
|
@@ -676,11 +768,11 @@ class DG_Admin {
|
|
676 |
<p><?php _e('Unless you <em>really</em> know what you\'re doing, you should not touch these values.', 'document-gallery'); ?></p>
|
677 |
<?php if (!DG_Thumber::isExecAvailable()) : ?>
|
678 |
<p>
|
679 |
-
|
680 |
</p>
|
681 |
<?php endif; ?>
|
682 |
<?php }
|
683 |
-
|
684 |
/**
|
685 |
* Renders a readonly textfield containing a dump of current DG options.
|
686 |
*/
|
@@ -690,13 +782,13 @@ class DG_Admin {
|
|
690 |
_e('The following <em>readonly text</em> should be provided when <a href="http://wordpress.org/support/plugin/document-gallery" target="_blank">reporting a bug</a>:', 'documet-gallery');
|
691 |
?></p>
|
692 |
<table class="form-table">
|
693 |
-
|
694 |
-
|
695 |
-
|
696 |
-
|
697 |
-
|
698 |
-
|
699 |
-
|
700 |
</table>
|
701 |
<?php }
|
702 |
|
@@ -709,20 +801,19 @@ class DG_Admin {
|
|
709 |
|
710 |
$URL_params = array('page' => DG_OPTION_NAME, 'tab' => 'Thumbnail');
|
711 |
$att_ids = array();
|
712 |
-
|
713 |
if (isset($_REQUEST['orderby']) && in_array(strtolower($_REQUEST['orderby']), array('title', 'date'))) {
|
714 |
$orderby = strtolower($_REQUEST['orderby']);
|
715 |
$URL_params['orderby'] = $orderby;
|
716 |
-
|
717 |
-
switch ($orderby)
|
718 |
-
{
|
719 |
case 'date':
|
720 |
foreach ($options['thumbs'] as $key => $node) {
|
721 |
$keyArray[$key] = $node['timestamp'];
|
722 |
$options['thumbs'][$key]['thumb_id'] = $att_ids[] = $key;
|
723 |
}
|
724 |
break;
|
725 |
-
|
726 |
case 'title':
|
727 |
foreach ($options['thumbs'] as $key => $node) {
|
728 |
$keyArray[$key] = basename($node['thumb_path']);
|
@@ -730,7 +821,7 @@ class DG_Admin {
|
|
730 |
}
|
731 |
break;
|
732 |
}
|
733 |
-
|
734 |
$order = strtolower($_REQUEST['order']);
|
735 |
if (!isset($_REQUEST['order']) || !in_array($order, array('asc', 'desc'))) {
|
736 |
$order = 'asc';
|
@@ -755,7 +846,7 @@ class DG_Admin {
|
|
755 |
} else {
|
756 |
$limit = intval($_REQUEST['limit']);
|
757 |
}
|
758 |
-
|
759 |
$URL_params['limit'] = $limit;
|
760 |
$select_limit = '';
|
761 |
foreach ($limit_options as $l_o) {
|
@@ -767,7 +858,7 @@ class DG_Admin {
|
|
767 |
if ($sheet <= 0 || $sheet > $lastsheet) {
|
768 |
$sheet = 1;
|
769 |
}
|
770 |
-
|
771 |
$offset = ($sheet - 1) * $limit;
|
772 |
|
773 |
$att_ids = array_slice($att_ids, $offset, $limit);
|
@@ -785,7 +876,7 @@ class DG_Admin {
|
|
785 |
$titles[$att->ID] = $att->post_title.'.'.$path_parts['extension'];
|
786 |
}
|
787 |
unset($atts);
|
788 |
-
|
789 |
$thead = '<tr>'.
|
790 |
'<th scope="col" class="manage-column column-cb check-column">'.
|
791 |
'<label class="screen-reader-text" for="cb-select-all-%1$d">'.__('Select All', 'document-gallery').'</label>'.
|
@@ -793,6 +884,7 @@ class DG_Admin {
|
|
793 |
'</th>'.
|
794 |
'<th scope="col" class="manage-column column-icon">'.__('Thumbnail', 'document-gallery').'</th>'.
|
795 |
'<th scope="col" class="manage-column column-title '.(($orderby != 'title')?'sortable desc':'sorted '.$order).'"><a href="?'.http_build_query(array_merge($URL_params, array('orderby'=>'title','order'=>(($orderby != 'title')?'asc':(($order == 'asc')?'desc':'asc'))))).'"><span>'.__('File name', 'document-gallery').'</span><span class="sorting-indicator"></span></th>'.
|
|
|
796 |
'<th scope="col" class="manage-column column-date '.(($orderby != 'date')?'sortable asc':'sorted '.$order).'"><a href="?'.http_build_query(array_merge($URL_params, array('orderby'=>'date','order'=>(($orderby != 'date')?'desc':(($order == 'asc')?'desc':'asc'))))).'"><span>'.__('Date', 'document-gallery').'</span><span class="sorting-indicator"></span></th>'.
|
797 |
'</tr>';
|
798 |
|
@@ -811,51 +903,132 @@ class DG_Admin {
|
|
811 |
'<span class="displaying-num"><select dir="rtl" class="limit_per_page">'.$select_limit.'</select> '.__('items per page', 'document-gallery').'</span>'.
|
812 |
'</div>'.
|
813 |
'<br class="clear" />';
|
814 |
-
|
815 |
-
// Avoiding json_encode to avoid compatibility issues on some systems
|
816 |
-
$json_like = '';
|
817 |
-
foreach ($URL_params as $k => $v) {
|
818 |
-
$json_like .= '"'.$k.'":"'.$v.'",';
|
819 |
-
}
|
820 |
?>
|
821 |
|
822 |
<script type="text/javascript">
|
823 |
-
var URL_params = <?php echo
|
824 |
-
|
825 |
<div class="thumbs-list-wrapper">
|
826 |
-
|
827 |
-
|
828 |
-
|
829 |
-
|
830 |
-
|
831 |
<?php printf($thead, 1); ?>
|
832 |
</thead>
|
833 |
-
|
834 |
<?php printf($thead, 2); ?>
|
835 |
</tfoot>
|
836 |
-
|
837 |
$i = 0;
|
838 |
foreach ($options['thumbs'] as $v) {
|
839 |
if ($i < $offset) { $i++; continue; }
|
840 |
if (++$i > $offset + $limit) { break; }
|
841 |
-
|
842 |
-
$icon = isset($v['thumb_url']) ? $v['thumb_url'] :
|
843 |
$title = isset($titles[$v['thumb_id']]) ? $titles[$v['thumb_id']] : '';
|
844 |
$date = DocumentGallery::localDateTimeFromTimestamp($v['timestamp']);
|
845 |
|
846 |
-
echo '<tr><td scope="row" class="check-column"><input type="checkbox" class="cb-ids" name="' . DG_OPTION_NAME . '[ids][]" value="' .
|
847 |
$v['thumb_id'].'"></td><td class="column-icon media-icon"><img src="' .
|
848 |
$icon.'" />'.'</td><td class="title column-title">' .
|
849 |
($title ? '<strong><a href="' . home_url('/?attachment_id='.$v['thumb_id']).'" target="_blank" title="'.__('View', 'document-gallery').' \'' .
|
850 |
$title.'\' '.__('attachment page', 'document-gallery').'">'.$title.'</a></strong>' : __('Attachment not found', 'document-gallery')) .
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
851 |
'</td><td class="date column-date">'.$date.'</td></tr>'.PHP_EOL;
|
852 |
} ?>
|
853 |
</tbody>
|
854 |
-
|
855 |
-
|
856 |
-
|
857 |
</div>
|
858 |
<?php }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
859 |
/**
|
860 |
* Render the Logging table.
|
861 |
*/
|
@@ -932,16 +1105,16 @@ var URL_params = <?php echo '{'.trim($json_like,', ').'}'; ?>;
|
|
932 |
echo '<div class="noLog">'.__('There are no log entries at this time.', 'document-gallery').'<br />'.__('For Your information:', 'document-gallery').' <strong><i>'.__('Logging', 'document-gallery').'</i></strong> '.(DG_Logger::logEnabled()?'<span class="loggingON">'.__('is turned ON', 'document-gallery').'!</span>':'<span class="loggingOFF">'.__('is turned OFF', 'document-gallery').'!</span>').'</div>';
|
933 |
}
|
934 |
}
|
935 |
-
|
936 |
/**
|
937 |
* Takes label name and returns SPAN tag.
|
938 |
* @param string $e label name.
|
939 |
* @return string SPAN tag
|
940 |
*/
|
941 |
private static function getLogLabelSpan($e) {
|
942 |
-
|
943 |
}
|
944 |
-
|
945 |
/**
|
946 |
* Render a checkbox field.
|
947 |
* @param array $args
|
@@ -953,7 +1126,7 @@ var URL_params = <?php echo '{'.trim($json_like,', ').'}'; ?>;
|
|
953 |
$args['name'],
|
954 |
$args['label_for'],
|
955 |
checked($args['value'], 1, false),
|
956 |
-
$args['disabled']
|
957 |
$args['description']);
|
958 |
}
|
959 |
|
@@ -970,7 +1143,7 @@ var URL_params = <?php echo '{'.trim($json_like,', ').'}'; ?>;
|
|
970 |
$args['label_for'],
|
971 |
$args['description']);
|
972 |
}
|
973 |
-
|
974 |
/**
|
975 |
* Accepts a two-dimensional array where each inner array consists of valid arguments for renderTextField.
|
976 |
* @param array $args
|
@@ -1001,7 +1174,7 @@ var URL_params = <?php echo '{'.trim($json_like,', ').'}'; ?>;
|
|
1001 |
|
1002 |
print '</select> ' . $args['description'];
|
1003 |
}
|
1004 |
-
|
1005 |
/**
|
1006 |
* Wraps the PHP exit language construct.
|
1007 |
*/
|
6 |
* @var string The hook for the Document Gallery settings page.
|
7 |
*/
|
8 |
private static $hook;
|
9 |
+
|
10 |
/**
|
11 |
* @var string The current tab being rendered.
|
12 |
*/
|
13 |
private static $current;
|
14 |
+
|
15 |
/**
|
16 |
* NOTE: This should only ever be accessed through getTabs().
|
17 |
*
|
18 |
* @var multitype:string Associative array containing all tab names, keyed by tab slug.
|
19 |
*/
|
20 |
private static $tabs;
|
21 |
+
|
22 |
/**
|
23 |
* Returns reference to tabs array, initializing if needed.
|
24 |
*
|
32 |
'Logging' => __('Logging', 'document-gallery'),
|
33 |
'Advanced' => __('Advanced', 'document-gallery'));
|
34 |
}
|
35 |
+
|
36 |
return self::$tabs;
|
37 |
}
|
38 |
+
|
39 |
/**
|
40 |
* Renders Document Gallery options page.
|
41 |
*/
|
42 |
public static function renderOptions() { ?>
|
43 |
<div class="wrap">
|
44 |
+
<h2><?php echo __('Document Gallery Settings', 'document-gallery'); ?></h2>
|
45 |
|
46 |
+
<h2 class="nav-tab-wrapper">
|
47 |
<?php foreach (self::getTabs() as $tab => $name) {
|
48 |
$class = ($tab == self::$current) ? ' nav-tab-active' : '';
|
49 |
echo '<a class="nav-tab '.$tab.'-tab'.$class.'" href="?page=' . DG_OPTION_NAME . '&tab='.$tab.'">'.$name.'</a>';
|
50 |
} ?>
|
51 |
</h2>
|
52 |
|
53 |
+
<form method="post" action="options.php" id="tab-<?php echo self::$current?>">
|
54 |
+
<input type="hidden" name="<?php echo DG_OPTION_NAME; ?>[tab]" value="<?php echo self::$current; ?>" />
|
55 |
<?php
|
56 |
settings_fields(DG_OPTION_NAME);
|
57 |
do_settings_sections(DG_OPTION_NAME);
|
71 |
$settings = '<a href="options-general.php?page=' . DG_OPTION_NAME . '">' .
|
72 |
__('Settings', 'document-gallery') . '</a>';
|
73 |
array_unshift($links, $settings);
|
74 |
+
|
75 |
+
return $links;
|
76 |
+
}
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Adds donate link to main plugin view.
|
80 |
+
*/
|
81 |
+
public static function addDonateLink($links, $file) {
|
82 |
+
if ($file === DG_BASENAME) {
|
83 |
+
global $dg_options;
|
84 |
+
|
85 |
+
$donate = '<strong><a href="' . $dg_options['meta']['donate_link'] . '">' .
|
86 |
+
__('Donate', 'document-gallery') . '</a></strong>';
|
87 |
+
$links[] = $donate;
|
88 |
+
}
|
89 |
+
|
90 |
return $links;
|
91 |
}
|
92 |
|
100 |
'manage_options', DG_OPTION_NAME, array(__CLASS__, 'renderOptions'));
|
101 |
add_action('admin_enqueue_scripts', array(__CLASS__, 'enqueueScriptsAndStyles'));
|
102 |
}
|
103 |
+
|
104 |
/**
|
105 |
* Enqueues styles and scripts for the admin settings page.
|
106 |
*/
|
107 |
public static function enqueueScriptsAndStyles($hook) {
|
108 |
if ($hook !== DG_Admin::$hook) return;
|
109 |
+
|
110 |
wp_enqueue_style('document-gallery-admin', DG_URL . 'assets/css/admin.css', null, DG_VERSION);
|
111 |
wp_enqueue_script('document-gallery-admin', DG_URL . 'assets/js/admin.js', array('jquery'), DG_VERSION, true);
|
112 |
+
wp_localize_script('document-gallery-admin', 'dg_admin_vars', array('upload_limit' => wp_max_upload_size()));
|
113 |
+
if ($hook == 'post.php') {
|
114 |
+
wp_localize_script('document-gallery-admin', 'ajax_object', array('ajax_url' => admin_url('admin-ajax.php')));
|
115 |
+
}
|
116 |
}
|
117 |
|
118 |
/**
|
131 |
$funct = 'register' . self::$current . 'Settings';
|
132 |
DG_Admin::$funct();
|
133 |
}
|
134 |
+
|
135 |
/**
|
136 |
* Registers settings for the general tab.
|
137 |
*/
|
168 |
'description' => __('Link to attachment page rather than to file', 'document-gallery')
|
169 |
));
|
170 |
|
171 |
+
add_settings_field(
|
172 |
+
'gallery_defaults_columns', 'columns',
|
173 |
+
array(__CLASS__, 'renderTextField'),
|
174 |
+
DG_OPTION_NAME, 'gallery_defaults',
|
175 |
+
array (
|
176 |
+
'label_for' => 'label_gallery_defaults_columns',
|
177 |
+
'name' => 'gallery_defaults][columns',
|
178 |
+
'value' => esc_attr($defaults['columns']),
|
179 |
+
'type' => 'number" min="1" step="1',
|
180 |
+
'option_name' => DG_OPTION_NAME,
|
181 |
+
'description' => __('The number of columns to display when not rendering descriptions.', 'document-gallery')
|
182 |
+
));
|
183 |
+
|
184 |
add_settings_field(
|
185 |
'gallery_defaults_descriptions', 'descriptions',
|
186 |
array(__CLASS__, 'renderCheckboxField'),
|
205 |
'description' => __('Use auto-generated document thumbnails', 'document-gallery')
|
206 |
));
|
207 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
208 |
add_settings_field(
|
209 |
'gallery_defaults_order', 'order',
|
210 |
array(__CLASS__, 'renderSelectField'),
|
254 |
'value' => esc_attr($defaults['limit']),
|
255 |
'type' => 'number" min="-1" step="1',
|
256 |
'option_name' => DG_OPTION_NAME,
|
257 |
+
'description' => __('Limit the number of documents included. -1 means no limit.', 'document-gallery')
|
258 |
+
));
|
259 |
|
260 |
+
add_settings_field(
|
261 |
+
'gallery_defaults_mime_types', 'mime_types',
|
262 |
+
array(__CLASS__, 'renderTextField'),
|
263 |
+
DG_OPTION_NAME, 'gallery_defaults',
|
264 |
+
array (
|
265 |
+
'label_for' => 'label_gallery_defaults_mime_types',
|
266 |
+
'name' => 'gallery_defaults][mime_types',
|
267 |
+
'value' => esc_attr($defaults['mime_types']),
|
268 |
+
'type' => 'text',
|
269 |
+
'option_name' => DG_OPTION_NAME,
|
270 |
+
'description' => __('Comma-delimited list of <a href="http://en.wikipedia.org/wiki/Internet_media_type#List_of_common_media_types">MIME types</a>.', 'document-gallery')
|
271 |
+
));
|
272 |
+
|
273 |
add_settings_field(
|
274 |
'gallery_defaults_post_status', 'post_status',
|
275 |
array(__CLASS__, 'renderSelectField'),
|
295 |
'option_name' => DG_OPTION_NAME,
|
296 |
'description' => __('Which post type to look for when querying documents.', 'document-gallery')
|
297 |
));
|
298 |
+
|
299 |
add_settings_field(
|
300 |
'thumbnail_generation_av', 'Audio/Video',
|
301 |
array(__CLASS__, 'renderCheckboxField'),
|
338 |
'disabled' => !DG_Thumber::isImagickAvailable()
|
339 |
));
|
340 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
341 |
add_settings_field(
|
342 |
'thumbnail_generation_width', 'Max Thumbnail Dimensions',
|
343 |
array(__CLASS__, 'renderMultiTextField'),
|
359 |
'description' => __('The max width and height (in pixels) that thumbnails will be generated.', 'document-gallery'))
|
360 |
));
|
361 |
}
|
362 |
+
|
363 |
/**
|
364 |
* Registers settings for the thumbnail management tab.
|
365 |
*/
|
368 |
'thumbnail_table', '',
|
369 |
array(__CLASS__, 'renderThumbnailSection'), DG_OPTION_NAME);
|
370 |
}
|
371 |
+
|
372 |
/**
|
373 |
* Registers settings for the logging tab.
|
374 |
*/
|
377 |
'logging_table', '',
|
378 |
array(__CLASS__, 'renderLoggingSection'), DG_OPTION_NAME);
|
379 |
}
|
380 |
+
|
381 |
/**
|
382 |
* Registers settings for the advanced tab.
|
383 |
*/
|
384 |
private static function registerAdvancedSettings() {
|
385 |
global $dg_options;
|
386 |
+
|
387 |
add_settings_section(
|
388 |
'advanced', __('Advanced Thumbnail Generation', 'document-gallery'),
|
389 |
array(__CLASS__, 'renderAdvancedSection'), DG_OPTION_NAME);
|
390 |
+
|
391 |
add_settings_field(
|
392 |
'advanced_logging', 'Logging',
|
393 |
array(__CLASS__, 'renderCheckboxField'),
|
399 |
'option_name' => DG_OPTION_NAME,
|
400 |
'description' => __('Whether to log debug and error information related to Document Gallery.', 'document-gallery')
|
401 |
));
|
402 |
+
|
403 |
add_settings_field(
|
404 |
'advanced_validation', 'Option Validation',
|
405 |
array(__CLASS__, 'renderCheckboxField'),
|
443 |
'advanced_options_dump', __('Options Array Dump', 'document-gallery'),
|
444 |
array(__CLASS__, 'renderOptionsDumpSection'), DG_OPTION_NAME);
|
445 |
}
|
446 |
+
|
447 |
/**
|
448 |
* Validates submitted options, sanitizing any invalid options.
|
449 |
* @param array $values User-submitted new options.
|
474 |
|
475 |
// handle gallery shortcode defaults
|
476 |
$errs = array();
|
477 |
+
$ret['gallery'] = DG_Gallery::sanitizeDefaults(null, $values['gallery_defaults'], $errs);
|
478 |
|
479 |
foreach ($errs as $k => $v) {
|
480 |
add_settings_error(DG_OPTION_NAME, str_replace('_', '-', $k), $v);
|
481 |
}
|
482 |
+
|
483 |
// handle setting width
|
484 |
if (isset($values['thumbnail_generation']['width'])) {
|
485 |
$width = (int)$values['thumbnail_generation']['width'];
|
492 |
|
493 |
unset($values['thumbnail_generation']['width']);
|
494 |
}
|
495 |
+
|
496 |
// handle setting height
|
497 |
if (isset($values['thumbnail_generation']['height'])) {
|
498 |
$height = (int)$values['thumbnail_generation']['height'];
|
505 |
|
506 |
unset($values['thumbnail_generation']['width']);
|
507 |
}
|
508 |
+
|
509 |
// delete thumb cache to force regeneration if max dimensions changed
|
510 |
if ($ret['thumber']['width'] !== $dg_options['thumber']['width'] ||
|
511 |
$ret['thumber']['height'] !== $dg_options['thumber']['height']) {
|
514 |
@unlink($v['thumb_path']);
|
515 |
}
|
516 |
}
|
517 |
+
|
518 |
$ret['thumber']['thumbs'] = array();
|
519 |
$thumbs_cleared = true;
|
520 |
}
|
546 |
|
547 |
return $ret;
|
548 |
}
|
549 |
+
|
550 |
/**
|
551 |
* Validates thumbnail management settings, sanitizing any invalid options.
|
552 |
* @param array $values User-submitted new options.
|
555 |
private static function validateThumbnailSettings($values) {
|
556 |
global $dg_options;
|
557 |
$ret = $dg_options;
|
558 |
+
$responseArr = array('result' => false);
|
559 |
+
|
560 |
+
if (isset($values['entry'])) {
|
561 |
+
$ID = intval($values['entry']);
|
562 |
+
} else {
|
563 |
+
$ID = -1;
|
564 |
+
}
|
565 |
+
|
566 |
+
// Thumbnail(s) cleanup;
|
567 |
+
// cleanup value is a marker
|
568 |
+
if ( isset($values['cleanup']) && isset($values['ids']) ) {
|
569 |
$deleted = array_values(array_intersect(array_keys($dg_options['thumber']['thumbs']), $values['ids']));
|
570 |
+
|
571 |
foreach ($deleted as $k) {
|
572 |
if (isset($ret['thumber']['thumbs'][$k]['thumber'])) {
|
573 |
@unlink($ret['thumber']['thumbs'][$k]['thumb_path']);
|
574 |
}
|
575 |
+
|
576 |
unset($ret['thumber']['thumbs'][$k]);
|
577 |
}
|
578 |
+
|
579 |
+
$responseArr['result'] = true;
|
580 |
+
$responseArr['deleted'] = $deleted;
|
581 |
+
}
|
582 |
+
// Thumbnail file manual refresh (one at a time)
|
583 |
+
// upload value is a marker
|
584 |
+
elseif ( isset($values['upload']) && isset($_FILES['file']) && isset($ret['thumber']['thumbs'][$ID]) ) {
|
585 |
+
$old_path = $ret['thumber']['thumbs'][$ID]['thumb_path'];
|
586 |
+
$uploaded_filename = self::validateUploadedFile();
|
587 |
+
if ($uploaded_filename && DG_Thumber::setThumbnail($ID, $uploaded_filename)) {
|
588 |
+
if ($dg_options['thumber']['thumbs'][$ID]['thumb_path'] !== $old_path) {
|
589 |
+
@unlink($old_path);
|
590 |
+
}
|
591 |
+
$responseArr['result'] = true;
|
592 |
+
$responseArr['url'] = $dg_options['thumber']['thumbs'][$ID]['thumb_url'];
|
593 |
+
$ret['thumber']['thumbs'][$ID] = $dg_options['thumber']['thumbs'][$ID];
|
594 |
}
|
595 |
}
|
596 |
+
|
597 |
+
if (isset($values['ajax'])) {
|
598 |
+
echo DG_Util::jsonEncode($responseArr);
|
599 |
+
add_filter('wp_redirect', array(__CLASS__, '_exit'), 1, 0);
|
600 |
+
}
|
601 |
+
|
602 |
return $ret;
|
603 |
}
|
604 |
+
|
605 |
+
/**
|
606 |
+
* Validates uploaded file as a semi for potential thumbnail.
|
607 |
+
* @param str $var File field name.
|
608 |
+
* @return bool|str False on failure, path to temp file on success.
|
609 |
+
*/
|
610 |
+
public static function validateUploadedFile($var = 'file') {
|
611 |
+
// checking if any file was delivered
|
612 |
+
if (!isset($_FILES[$var]))
|
613 |
+
return false;
|
614 |
+
// we gonna process only first one
|
615 |
+
if ( !is_array($_FILES[$var]['error']) ) {
|
616 |
+
$upload_err = $_FILES[$var]['error'];
|
617 |
+
$upload_path = $_FILES[$var]['tmp_name'];
|
618 |
+
$upload_size = $_FILES[$var]['size'];
|
619 |
+
$upload_type = $_FILES[$var]['type'];
|
620 |
+
$upload_name = $_FILES[$var]['name'];
|
621 |
+
} else {
|
622 |
+
$upload_err = $_FILES[$var]['error'][0];
|
623 |
+
$upload_path = $_FILES[$var]['tmp_name'][0];
|
624 |
+
$upload_size = $_FILES[$var]['size'][0];
|
625 |
+
$upload_type = $_FILES[$var]['type'][0];
|
626 |
+
$upload_name = $_FILES[$var]['name'][0];
|
627 |
+
}
|
628 |
+
$info = getimagesize($upload_path);
|
629 |
+
if ($info) {
|
630 |
+
if ($info['mime']!=$upload_type) {// in DG_Thumber::getExt() we'll define and set appropriate extension
|
631 |
+
DG_Logger::writeLog(
|
632 |
+
DG_LogLevel::Warning,
|
633 |
+
__('File extension doesn\'t match the MIME type of the image: ', 'document-gallery') .
|
634 |
+
$upload_name.' - '.$info['mime']);
|
635 |
+
}
|
636 |
+
if ($upload_size>wp_max_upload_size()) {
|
637 |
+
DG_Logger::writeLog(
|
638 |
+
DG_LogLevel::Warning,
|
639 |
+
__('Uploaded file size exceeds the allowable limit: ', 'document-gallery') .
|
640 |
+
$upload_name.' - '.$upload_size.'b');
|
641 |
+
return false;
|
642 |
+
}
|
643 |
+
} else {
|
644 |
+
DG_Logger::writeLog(
|
645 |
+
DG_LogLevel::Warning,
|
646 |
+
__('Uploaded file is not an image: ', 'document-gallery') .
|
647 |
+
$upload_name);
|
648 |
+
return false;
|
649 |
+
}
|
650 |
+
if ($upload_err == UPLOAD_ERR_OK && $upload_size > 0) {
|
651 |
+
$temp_file = $upload_path;
|
652 |
+
} else {
|
653 |
+
DG_Logger::writeLog(
|
654 |
+
DG_LogLevel::Error,
|
655 |
+
__('Failed to get uploaded file: ', 'document-gallery') .
|
656 |
+
$upload_err);
|
657 |
+
return false;
|
658 |
+
}
|
659 |
+
|
660 |
+
return $temp_file;
|
661 |
+
}
|
662 |
+
|
663 |
/**
|
664 |
* Validates logging settings, sanitizing any invalid options.
|
665 |
* @param array $values User-submitted new options.
|
672 |
}
|
673 |
return $dg_options;
|
674 |
}
|
675 |
+
|
676 |
/**
|
677 |
* Validates advanced settings, sanitizing any invalid options.
|
678 |
* @param array $values User-submitted new options.
|
681 |
private static function validateAdvancedSettings($values) {
|
682 |
global $dg_options;
|
683 |
$ret = $dg_options;
|
684 |
+
|
685 |
// handle setting the Ghostscript path
|
686 |
if (isset($values['gs']) &&
|
687 |
0 != strcmp($values['gs'], $ret['thumber']['gs'])) {
|
692 |
__('Invalid Ghostscript path given: ', 'document-gallery') . $values['gs']);
|
693 |
}
|
694 |
}
|
695 |
+
|
696 |
// handle setting timeout
|
697 |
if (isset($values['timeout'])) {
|
698 |
$timeout = (int)$values['timeout'];
|
703 |
__('Invalid timeout given: ', 'document-gallery') . $values['timeout']);
|
704 |
}
|
705 |
}
|
706 |
+
|
707 |
// validation checkbox
|
708 |
$ret['validation'] = isset($values['validation']);
|
709 |
|
712 |
|
713 |
return $ret;
|
714 |
}
|
715 |
+
|
716 |
/**
|
717 |
* @return bool Whether to register settings.
|
718 |
*/
|
750 |
__('Enter custom CSS styling for use with document galleries. To see which ids and classes you can style, take a look at <a href="%s" target="_blank">style.css</a>.'),
|
751 |
DG_URL . 'assets/css/style.css'); ?></p>
|
752 |
<table class="form-table">
|
753 |
+
<tbody>
|
754 |
+
<tr valign="top">
|
755 |
+
<td>
|
756 |
+
<textarea name="<?php echo DG_OPTION_NAME; ?>[css]" rows="10" cols="50" class="large-text code"><?php echo $dg_options['css']['text']; ?></textarea>
|
757 |
+
</td>
|
758 |
+
</tr>
|
759 |
+
</tbody>
|
760 |
</table>
|
761 |
<?php }
|
762 |
|
768 |
<p><?php _e('Unless you <em>really</em> know what you\'re doing, you should not touch these values.', 'document-gallery'); ?></p>
|
769 |
<?php if (!DG_Thumber::isExecAvailable()) : ?>
|
770 |
<p>
|
771 |
+
<em><?php _e('NOTE: <code>exec()</code> is not accessible. Ghostscript will not function.', 'document-gallery'); ?></em>
|
772 |
</p>
|
773 |
<?php endif; ?>
|
774 |
<?php }
|
775 |
+
|
776 |
/**
|
777 |
* Renders a readonly textfield containing a dump of current DG options.
|
778 |
*/
|
782 |
_e('The following <em>readonly text</em> should be provided when <a href="http://wordpress.org/support/plugin/document-gallery" target="_blank">reporting a bug</a>:', 'documet-gallery');
|
783 |
?></p>
|
784 |
<table class="form-table">
|
785 |
+
<tbody>
|
786 |
+
<tr valign="top">
|
787 |
+
<td>
|
788 |
+
<textarea readonly="true" rows="10" cols="50" id="options-dump" class="large-text code"><?php print_r($dg_options); ?></textarea>
|
789 |
+
</td>
|
790 |
+
</tr>
|
791 |
+
</tbody>
|
792 |
</table>
|
793 |
<?php }
|
794 |
|
801 |
|
802 |
$URL_params = array('page' => DG_OPTION_NAME, 'tab' => 'Thumbnail');
|
803 |
$att_ids = array();
|
804 |
+
|
805 |
if (isset($_REQUEST['orderby']) && in_array(strtolower($_REQUEST['orderby']), array('title', 'date'))) {
|
806 |
$orderby = strtolower($_REQUEST['orderby']);
|
807 |
$URL_params['orderby'] = $orderby;
|
808 |
+
|
809 |
+
switch ($orderby) {
|
|
|
810 |
case 'date':
|
811 |
foreach ($options['thumbs'] as $key => $node) {
|
812 |
$keyArray[$key] = $node['timestamp'];
|
813 |
$options['thumbs'][$key]['thumb_id'] = $att_ids[] = $key;
|
814 |
}
|
815 |
break;
|
816 |
+
|
817 |
case 'title':
|
818 |
foreach ($options['thumbs'] as $key => $node) {
|
819 |
$keyArray[$key] = basename($node['thumb_path']);
|
821 |
}
|
822 |
break;
|
823 |
}
|
824 |
+
|
825 |
$order = strtolower($_REQUEST['order']);
|
826 |
if (!isset($_REQUEST['order']) || !in_array($order, array('asc', 'desc'))) {
|
827 |
$order = 'asc';
|
846 |
} else {
|
847 |
$limit = intval($_REQUEST['limit']);
|
848 |
}
|
849 |
+
|
850 |
$URL_params['limit'] = $limit;
|
851 |
$select_limit = '';
|
852 |
foreach ($limit_options as $l_o) {
|
858 |
if ($sheet <= 0 || $sheet > $lastsheet) {
|
859 |
$sheet = 1;
|
860 |
}
|
861 |
+
|
862 |
$offset = ($sheet - 1) * $limit;
|
863 |
|
864 |
$att_ids = array_slice($att_ids, $offset, $limit);
|
876 |
$titles[$att->ID] = $att->post_title.'.'.$path_parts['extension'];
|
877 |
}
|
878 |
unset($atts);
|
879 |
+
|
880 |
$thead = '<tr>'.
|
881 |
'<th scope="col" class="manage-column column-cb check-column">'.
|
882 |
'<label class="screen-reader-text" for="cb-select-all-%1$d">'.__('Select All', 'document-gallery').'</label>'.
|
884 |
'</th>'.
|
885 |
'<th scope="col" class="manage-column column-icon">'.__('Thumbnail', 'document-gallery').'</th>'.
|
886 |
'<th scope="col" class="manage-column column-title '.(($orderby != 'title')?'sortable desc':'sorted '.$order).'"><a href="?'.http_build_query(array_merge($URL_params, array('orderby'=>'title','order'=>(($orderby != 'title')?'asc':(($order == 'asc')?'desc':'asc'))))).'"><span>'.__('File name', 'document-gallery').'</span><span class="sorting-indicator"></span></th>'.
|
887 |
+
'<th scope="col" class="manage-column column-thumbupload"></th>'.
|
888 |
'<th scope="col" class="manage-column column-date '.(($orderby != 'date')?'sortable asc':'sorted '.$order).'"><a href="?'.http_build_query(array_merge($URL_params, array('orderby'=>'date','order'=>(($orderby != 'date')?'desc':(($order == 'asc')?'desc':'asc'))))).'"><span>'.__('Date', 'document-gallery').'</span><span class="sorting-indicator"></span></th>'.
|
889 |
'</tr>';
|
890 |
|
903 |
'<span class="displaying-num"><select dir="rtl" class="limit_per_page">'.$select_limit.'</select> '.__('items per page', 'document-gallery').'</span>'.
|
904 |
'</div>'.
|
905 |
'<br class="clear" />';
|
|
|
|
|
|
|
|
|
|
|
|
|
906 |
?>
|
907 |
|
908 |
<script type="text/javascript">
|
909 |
+
var URL_params = <?php echo DG_Util::jsonEncode($URL_params); ?>;
|
910 |
+
</script>
|
911 |
<div class="thumbs-list-wrapper">
|
912 |
+
<div>
|
913 |
+
<div class="tablenav top"><?php echo $pagination; ?></div>
|
914 |
+
<table id="ThumbsTable" class="wp-list-table widefat fixed media"
|
915 |
+
cellpadding="0" cellspacing="0">
|
916 |
+
<thead>
|
917 |
<?php printf($thead, 1); ?>
|
918 |
</thead>
|
919 |
+
<tfoot>
|
920 |
<?php printf($thead, 2); ?>
|
921 |
</tfoot>
|
922 |
+
<tbody><?php
|
923 |
$i = 0;
|
924 |
foreach ($options['thumbs'] as $v) {
|
925 |
if ($i < $offset) { $i++; continue; }
|
926 |
if (++$i > $offset + $limit) { break; }
|
927 |
+
|
928 |
+
$icon = isset($v['thumb_url']) ? $v['thumb_url'] : DG_Thumber::getDefaultThumbnail($v['thumb_id']);
|
929 |
$title = isset($titles[$v['thumb_id']]) ? $titles[$v['thumb_id']] : '';
|
930 |
$date = DocumentGallery::localDateTimeFromTimestamp($v['timestamp']);
|
931 |
|
932 |
+
echo '<tr data-entry="'.$v['thumb_id'].'"><td scope="row" class="check-column"><input type="checkbox" class="cb-ids" name="' . DG_OPTION_NAME . '[ids][]" value="' .
|
933 |
$v['thumb_id'].'"></td><td class="column-icon media-icon"><img src="' .
|
934 |
$icon.'" />'.'</td><td class="title column-title">' .
|
935 |
($title ? '<strong><a href="' . home_url('/?attachment_id='.$v['thumb_id']).'" target="_blank" title="'.__('View', 'document-gallery').' \'' .
|
936 |
$title.'\' '.__('attachment page', 'document-gallery').'">'.$title.'</a></strong>' : __('Attachment not found', 'document-gallery')) .
|
937 |
+
'</td><td class="column-thumbupload">' .
|
938 |
+
'<span class="manual-download">' .
|
939 |
+
'<span class="dashicons dashicons-upload"></span>' .
|
940 |
+
'<span class="html5dndmarker">Drop file here<span> or </span></span>' .
|
941 |
+
'<span class="buttons-area">' .
|
942 |
+
'<input id="upload-button'.$v['thumb_id'].'" type="file" />' .
|
943 |
+
'<input id="trigger-button'.$v['thumb_id'].'" type="button" value="Select File" class="button" />' .
|
944 |
+
'</span>' .
|
945 |
+
'</span>' .
|
946 |
'</td><td class="date column-date">'.$date.'</td></tr>'.PHP_EOL;
|
947 |
} ?>
|
948 |
</tbody>
|
949 |
+
</table>
|
950 |
+
<div class="tablenav bottom"><?php echo $pagination; ?></div>
|
951 |
+
</div>
|
952 |
</div>
|
953 |
<?php }
|
954 |
+
|
955 |
+
/**
|
956 |
+
* Adds meta box to the attchements' edit pages.
|
957 |
+
*/
|
958 |
+
public static function addMetaBox() {
|
959 |
+
$screens = array( 'attachment' );
|
960 |
+
foreach ( $screens as $screen ) {
|
961 |
+
add_meta_box(
|
962 |
+
DG_OPTION_NAME.'_gen_box',
|
963 |
+
__( '<b>Thumbnail</b> for <i><b>Document Gallery</b></i>', 'document-gallery' ),
|
964 |
+
array(__CLASS__, 'renderMetaBox'),
|
965 |
+
$screen,
|
966 |
+
'normal'
|
967 |
+
);
|
968 |
+
}
|
969 |
+
DG_Admin::$hook = 'post.php';
|
970 |
+
add_action('admin_enqueue_scripts', array(__CLASS__, 'enqueueScriptsAndStyles'));
|
971 |
+
}
|
972 |
+
|
973 |
+
/**
|
974 |
+
* Render a Meta Box.
|
975 |
+
*/
|
976 |
+
public static function renderMetaBox($post) {
|
977 |
+
global $dg_options;
|
978 |
+
wp_nonce_field( DG_OPTION_NAME.'_meta_box', DG_OPTION_NAME.'_meta_box_nonce' );
|
979 |
+
$ID = $post->ID;
|
980 |
+
$icon = isset($dg_options['thumber']['thumbs'][$ID]['thumb_url']) ? $dg_options['thumber']['thumbs'][$ID]['thumb_url'] : DG_Thumber::getDefaultThumbnail($ID);
|
981 |
+
|
982 |
+
echo '<table id="ThumbsTable" class="wp-list-table widefat fixed media" cellpadding="0" cellspacing="0">'.
|
983 |
+
'<tbody><tr data-entry="'.$ID.'"><td class="column-icon media-icon"><img src="' .
|
984 |
+
$icon.'" />'.'</td><td class="column-thumbupload">' .
|
985 |
+
'<span class="manual-download">' .
|
986 |
+
'<span class="dashicons dashicons-upload"></span>' .
|
987 |
+
'<span class="html5dndmarker">Drop file here<span> or </span></span>' .
|
988 |
+
'<span class="buttons-area">' .
|
989 |
+
'<input id="upload-button'.$ID.'" type="file" />' .
|
990 |
+
'<input id="trigger-button'.$ID.'" type="button" value="Select File" class="button" />' .
|
991 |
+
'</span>' .
|
992 |
+
'</span>' .
|
993 |
+
'</td></tr></tbody></table>'.
|
994 |
+
(empty($dg_options['thumber']['thumbs'][$ID]) ? '<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;
|
995 |
+
}
|
996 |
+
|
997 |
+
/**
|
998 |
+
* Save a Meta Box.
|
999 |
+
*/
|
1000 |
+
public static function saveMetaBox($post_id) {
|
1001 |
+
// Check if our nonce is set.
|
1002 |
+
// Verify that the nonce is valid.
|
1003 |
+
// If this is an autosave, our form has not been submitted, so we don't want to do anything.
|
1004 |
+
if ( !isset($_POST[DG_OPTION_NAME.'_meta_box_nonce']) || !wp_verify_nonce($_POST[DG_OPTION_NAME.'_meta_box_nonce'], DG_OPTION_NAME.'_meta_box') || (defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE) ) {
|
1005 |
+
return;
|
1006 |
+
}
|
1007 |
+
|
1008 |
+
global $dg_options;
|
1009 |
+
$responseArr = array('result' => false);
|
1010 |
+
if (isset($_POST[DG_OPTION_NAME]['entry'])) {
|
1011 |
+
$ID = intval($_POST[DG_OPTION_NAME]['entry']);
|
1012 |
+
} else {
|
1013 |
+
$ID = -1;
|
1014 |
+
}
|
1015 |
+
if ( isset($_POST[DG_OPTION_NAME]['upload']) && isset($_FILES['file']) && isset($dg_options['thumber']['thumbs'][$ID]) ) {
|
1016 |
+
$old_path = $dg_options['thumber']['thumbs'][$ID]['thumb_path'];
|
1017 |
+
$uploaded_filename = self::validateUploadedFile();
|
1018 |
+
if ($uploaded_filename && DG_Thumber::setThumbnail($ID, $uploaded_filename)) {
|
1019 |
+
if ($dg_options['thumber']['thumbs'][$ID]['thumb_path'] !== $old_path) {
|
1020 |
+
@unlink($old_path);
|
1021 |
+
}
|
1022 |
+
$responseArr['result'] = true;
|
1023 |
+
$responseArr['url'] = $dg_options['thumber']['thumbs'][$ID]['thumb_url'];
|
1024 |
+
}
|
1025 |
+
}
|
1026 |
+
if (isset($_POST[DG_OPTION_NAME]['ajax'])) {
|
1027 |
+
echo DG_Util::jsonEncode($responseArr);
|
1028 |
+
wp_die();
|
1029 |
+
}
|
1030 |
+
}
|
1031 |
+
|
1032 |
/**
|
1033 |
* Render the Logging table.
|
1034 |
*/
|
1105 |
echo '<div class="noLog">'.__('There are no log entries at this time.', 'document-gallery').'<br />'.__('For Your information:', 'document-gallery').' <strong><i>'.__('Logging', 'document-gallery').'</i></strong> '.(DG_Logger::logEnabled()?'<span class="loggingON">'.__('is turned ON', 'document-gallery').'!</span>':'<span class="loggingOFF">'.__('is turned OFF', 'document-gallery').'!</span>').'</div>';
|
1106 |
}
|
1107 |
}
|
1108 |
+
|
1109 |
/**
|
1110 |
* Takes label name and returns SPAN tag.
|
1111 |
* @param string $e label name.
|
1112 |
* @return string SPAN tag
|
1113 |
*/
|
1114 |
private static function getLogLabelSpan($e) {
|
1115 |
+
return '<span class="logLabel ' . strtolower($e) . '">' . strtoupper($e) . '</span>';
|
1116 |
}
|
1117 |
+
|
1118 |
/**
|
1119 |
* Render a checkbox field.
|
1120 |
* @param array $args
|
1126 |
$args['name'],
|
1127 |
$args['label_for'],
|
1128 |
checked($args['value'], 1, false),
|
1129 |
+
disabled($args['disabled'], true, false),
|
1130 |
$args['description']);
|
1131 |
}
|
1132 |
|
1143 |
$args['label_for'],
|
1144 |
$args['description']);
|
1145 |
}
|
1146 |
+
|
1147 |
/**
|
1148 |
* Accepts a two-dimensional array where each inner array consists of valid arguments for renderTextField.
|
1149 |
* @param array $args
|
1174 |
|
1175 |
print '</select> ' . $args['description'];
|
1176 |
}
|
1177 |
+
|
1178 |
/**
|
1179 |
* Wraps the PHP exit language construct.
|
1180 |
*/
|
assets/css/admin.css
CHANGED
@@ -16,7 +16,7 @@ div.thumbs-list-wrapper>div, div.log-list-wrapper>div{
|
|
16 |
-moz-border-radius: 10px;
|
17 |
background: #B9C9FE;
|
18 |
color: #039;
|
19 |
-
width:
|
20 |
margin: 10px auto;
|
21 |
}
|
22 |
#ThumbsTable tbody, #LogTable tbody {
|
@@ -40,7 +40,7 @@ div.thumbs-list-wrapper>div, div.log-list-wrapper>div{
|
|
40 |
#LogTable td {
|
41 |
text-align: left;
|
42 |
}
|
43 |
-
td.title.column-title{
|
44 |
text-align: left !important;
|
45 |
}
|
46 |
#ThumbsTable img{
|
@@ -58,11 +58,20 @@ tr.selected{
|
|
58 |
tr.selected:hover{
|
59 |
background: #D8D3E5 !important;
|
60 |
}
|
61 |
-
.
|
62 |
white-space: nowrap;
|
|
|
63 |
}
|
64 |
.column-entry, .column-title {
|
65 |
-
width: 100
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
66 |
}
|
67 |
.nav-tab:before, .deleteSelected:before, .clearLog:before, .expandAll:before, .collapseAll:before, .logLabel.date:before, .collapser:after, .expander:after{
|
68 |
display: inline-block;
|
@@ -148,7 +157,7 @@ tr.selected:hover{
|
|
148 |
}
|
149 |
.logLabel.date {
|
150 |
background: #999999;
|
151 |
-
white-space: nowrap
|
152 |
font-weight: inherit;
|
153 |
}
|
154 |
.logLabel.date:before{
|
@@ -282,7 +291,60 @@ th input{
|
|
282 |
td input{
|
283 |
margin-right: 0 !important;
|
284 |
}
|
285 |
-
|
286 |
textarea[readonly], input[readonly], select[readonly] {
|
287 |
background-color: #dcdcdc;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
288 |
}
|
16 |
-moz-border-radius: 10px;
|
17 |
background: #B9C9FE;
|
18 |
color: #039;
|
19 |
+
width: 100%;
|
20 |
margin: 10px auto;
|
21 |
}
|
22 |
#ThumbsTable tbody, #LogTable tbody {
|
40 |
#LogTable td {
|
41 |
text-align: left;
|
42 |
}
|
43 |
+
td.title.column-title, .column-thumbupload {
|
44 |
text-align: left !important;
|
45 |
}
|
46 |
#ThumbsTable img{
|
58 |
tr.selected:hover{
|
59 |
background: #D8D3E5 !important;
|
60 |
}
|
61 |
+
.check-column, .column-icon {
|
62 |
white-space: nowrap;
|
63 |
+
width: 1%;
|
64 |
}
|
65 |
.column-entry, .column-title {
|
66 |
+
/*width: 100%;*/
|
67 |
+
}
|
68 |
+
.column-thumbupload {
|
69 |
+
white-space: nowrap;
|
70 |
+
width: 35%;
|
71 |
+
}
|
72 |
+
#document_gallery_gen_box .column-thumbupload {
|
73 |
+
width: auto;
|
74 |
+
padding-left: 7em;
|
75 |
}
|
76 |
.nav-tab:before, .deleteSelected:before, .clearLog:before, .expandAll:before, .collapseAll:before, .logLabel.date:before, .collapser:after, .expander:after{
|
77 |
display: inline-block;
|
157 |
}
|
158 |
.logLabel.date {
|
159 |
background: #999999;
|
160 |
+
/*white-space: nowrap;*/
|
161 |
font-weight: inherit;
|
162 |
}
|
163 |
.logLabel.date:before{
|
291 |
td input{
|
292 |
margin-right: 0 !important;
|
293 |
}
|
|
|
294 |
textarea[readonly], input[readonly], select[readonly] {
|
295 |
background-color: #dcdcdc;
|
296 |
+
}
|
297 |
+
.nowrap {
|
298 |
+
white-space: nowrap;
|
299 |
+
}
|
300 |
+
.column-level {
|
301 |
+
white-space: nowrap;
|
302 |
+
width: 6em;
|
303 |
+
}
|
304 |
+
.column-date {
|
305 |
+
width: 16em !important;
|
306 |
+
}
|
307 |
+
.column-thumbupload {
|
308 |
+
-webkit-user-select: none;
|
309 |
+
-moz-user-select: none;
|
310 |
+
-ms-user-select: none;
|
311 |
+
user-select: none;
|
312 |
+
cursor: context-menu;
|
313 |
+
}
|
314 |
+
.column-thumbupload > * {
|
315 |
+
visibility: hidden;
|
316 |
+
}
|
317 |
+
.column-thumbupload .dashicons {
|
318 |
+
font-size: x-large;
|
319 |
+
padding-top: 2px;
|
320 |
+
padding-left: 16px;
|
321 |
+
padding-right: 10px;
|
322 |
+
vertical-align: text-bottom;
|
323 |
+
}
|
324 |
+
/*Attempt to add fancy shadows*/
|
325 |
+
/*#ThumbsTable tr:hover {
|
326 |
+
z-index: 3;
|
327 |
+
border-color: #ccc;
|
328 |
+
-webkit-box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
|
329 |
+
-moz-box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
|
330 |
+
-ms-box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
|
331 |
+
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
|
332 |
+
}*/
|
333 |
+
#ThumbsTable tr:hover .column-thumbupload > *, #document_gallery_gen_box #ThumbsTable tr .column-thumbupload > * {
|
334 |
+
visibility: visible;
|
335 |
+
}
|
336 |
+
.dragover {
|
337 |
+
outline: 3px dashed #83b4d8;
|
338 |
+
}
|
339 |
+
.html5dndmarker span {
|
340 |
+
padding: 0px 10px;
|
341 |
+
}
|
342 |
+
.buttons-area input:first-child {
|
343 |
+
display: none !important;
|
344 |
+
}
|
345 |
+
#document_gallery_gen_box h3 span {
|
346 |
+
font-weight: 100;
|
347 |
+
}
|
348 |
+
#document_gallery_gen_box h3 span i b {
|
349 |
+
font-weight: 500;
|
350 |
}
|
assets/css/style.css
CHANGED
@@ -1,8 +1,8 @@
|
|
1 |
div.document-icon{ text-align: center; }
|
2 |
|
3 |
div.document-icon img{
|
4 |
-
|
5 |
-
max-
|
6 |
border: none;
|
7 |
}
|
8 |
|
@@ -18,9 +18,6 @@ div.document-icon{
|
|
18 |
display: inline-block;
|
19 |
vertical-align: top;
|
20 |
overflow: hidden;
|
21 |
-
/* percents round up in some browsers, making
|
22 |
-
only 3 icons fit per line so can't use 25% */
|
23 |
-
width: 24.5%;
|
24 |
}
|
25 |
div.document-icon-wrapper{
|
26 |
width: 100%;
|
@@ -43,8 +40,8 @@ div.descriptions.document-icon-wrapper{
|
|
43 |
}
|
44 |
|
45 |
div.descriptions.document-icon-wrapper img{
|
46 |
-
|
47 |
-
max-
|
48 |
}
|
49 |
|
50 |
/* clearfix */
|
1 |
div.document-icon{ text-align: center; }
|
2 |
|
3 |
div.document-icon img{
|
4 |
+
width: 89px;
|
5 |
+
max-width: 100%;
|
6 |
border: none;
|
7 |
}
|
8 |
|
18 |
display: inline-block;
|
19 |
vertical-align: top;
|
20 |
overflow: hidden;
|
|
|
|
|
|
|
21 |
}
|
22 |
div.document-icon-wrapper{
|
23 |
width: 100%;
|
40 |
}
|
41 |
|
42 |
div.descriptions.document-icon-wrapper img{
|
43 |
+
width: 65px;
|
44 |
+
max-width: 100%;
|
45 |
}
|
46 |
|
47 |
/* clearfix */
|
assets/js/admin.js
CHANGED
@@ -17,7 +17,7 @@ jQuery(document).ready(function(){
|
|
17 |
});
|
18 |
jQuery('input.current-page').bind('keypress', {}, function(e) {
|
19 |
var code = (e.keyCode ? e.keyCode : e.which);
|
20 |
-
if (code == 13) {
|
21 |
e.preventDefault();
|
22 |
jQuery(location).attr('href','?'+jQuery.param(jQuery.extend(URL_params,{ sheet: this.value })));
|
23 |
}
|
@@ -26,20 +26,25 @@ jQuery(document).ready(function(){
|
|
26 |
jQuery(location).attr('href','?'+jQuery.param(jQuery.extend(URL_params,{ limit: this.value })));
|
27 |
});
|
28 |
jQuery('#tab-Thumbnail').submit( function (event) {
|
29 |
-
|
30 |
-
|
31 |
var a = jQuery(this).attr('action');
|
32 |
-
var b = jQuery(this).serialize() +
|
|
|
|
|
33 |
jQuery.post(a, b, function(response) {
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
|
|
|
|
|
|
43 |
} ).fail(function() {
|
44 |
console.log( 'Problem in reaching the server' );
|
45 |
});
|
@@ -63,8 +68,7 @@ jQuery(document).ready(function(){
|
|
63 |
|
64 |
jQuery('.expander').click(toggleSpoiler);
|
65 |
|
66 |
-
if (jQuery('.spoiler-body').length)
|
67 |
-
{
|
68 |
jQuery('.expandAll, .collapseAll').addClass('button');
|
69 |
jQuery('.expandAll').click(function(e) {
|
70 |
e.preventDefault();
|
@@ -90,4 +94,168 @@ jQuery(document).ready(function(){
|
|
90 |
}
|
91 |
}
|
92 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
93 |
});
|
17 |
});
|
18 |
jQuery('input.current-page').bind('keypress', {}, function(e) {
|
19 |
var code = (e.keyCode ? e.keyCode : e.which);
|
20 |
+
if (code == 13) {//Enter keycode
|
21 |
e.preventDefault();
|
22 |
jQuery(location).attr('href','?'+jQuery.param(jQuery.extend(URL_params,{ sheet: this.value })));
|
23 |
}
|
26 |
jQuery(location).attr('href','?'+jQuery.param(jQuery.extend(URL_params,{ limit: this.value })));
|
27 |
});
|
28 |
jQuery('#tab-Thumbnail').submit( function (event) {
|
29 |
+
event.preventDefault();
|
30 |
+
if (jQuery('.cb-ids:checked').length > 0) {
|
31 |
var a = jQuery(this).attr('action');
|
32 |
+
var b = jQuery(this).serialize() +
|
33 |
+
'&document_gallery%5Bajax%5D=true' +
|
34 |
+
'&document_gallery%5Bcleanup%5D=true';
|
35 |
jQuery.post(a, b, function(response) {
|
36 |
+
if (response.indexOf("\n") == -1) {
|
37 |
+
eval('var reply = ' + response + ';');
|
38 |
+
if (reply.result) {
|
39 |
+
var result = reply.deleted;
|
40 |
+
for (var index in result) {
|
41 |
+
jQuery('input[type=checkbox][value='+result[index]+']').closest('tr').fadeOut('slow', 0.00, function() {jQuery(this).slideUp('slow', function() {jQuery(this).remove();});});
|
42 |
+
}
|
43 |
+
}
|
44 |
+
} else {
|
45 |
+
console.log('Invalid response from server:');
|
46 |
+
console.log(response);
|
47 |
+
}
|
48 |
} ).fail(function() {
|
49 |
console.log( 'Problem in reaching the server' );
|
50 |
});
|
68 |
|
69 |
jQuery('.expander').click(toggleSpoiler);
|
70 |
|
71 |
+
if (jQuery('.spoiler-body').length) {
|
|
|
72 |
jQuery('.expandAll, .collapseAll').addClass('button');
|
73 |
jQuery('.expandAll').click(function(e) {
|
74 |
e.preventDefault();
|
94 |
}
|
95 |
}
|
96 |
});
|
97 |
+
|
98 |
+
function DragDropFilesStop(e) {
|
99 |
+
e = e || event;
|
100 |
+
if (e.dataTransfer.types) {
|
101 |
+
//Testing if dragenter/dragover Event Contains Files - http://css-tricks.com/snippets/javascript/test-if-dragenterdragover-event-contains-files/
|
102 |
+
for (var i = 0; i < e.dataTransfer.types.length; i++) {
|
103 |
+
if (e.dataTransfer.types[i] == 'Files') {
|
104 |
+
//Or maybe it is better just to test e.dataTransfer.files[0].name - http://stackoverflow.com/a/12622904/3951387
|
105 |
+
//NO: before drop the list is not accessible
|
106 |
+
e.stopPropagation();
|
107 |
+
e.preventDefault();
|
108 |
+
e.dataTransfer.dropEffect = 'none';
|
109 |
+
break;
|
110 |
+
}
|
111 |
+
}
|
112 |
+
//jQuery way - Not working
|
113 |
+
/*if (jQuery.inArray('Files', e.dataTransfer.types)) {
|
114 |
+
e.stopPropagation();
|
115 |
+
e.preventDefault();
|
116 |
+
e.dataTransfer.dropEffect = 'none';
|
117 |
+
}*/
|
118 |
+
}
|
119 |
+
}
|
120 |
+
|
121 |
+
//Preventing browser from acting on drag&dropped files beside the dedicated areas
|
122 |
+
window.addEventListener('dragover', DragDropFilesStop, false);
|
123 |
+
window.addEventListener('drop', DragDropFilesStop, false);
|
124 |
+
|
125 |
+
function handleDragOver(e) {
|
126 |
+
e = e || event;
|
127 |
+
if (e.originalEvent.dataTransfer.types) {
|
128 |
+
for (var i = 0; i < e.originalEvent.dataTransfer.types.length; i++) {
|
129 |
+
if (e.originalEvent.dataTransfer.types[i] == 'Files') {
|
130 |
+
e.stopPropagation();
|
131 |
+
e.preventDefault();
|
132 |
+
//Have to exploit broker to access standart properties while using jQuery to bind handlers - http://stackoverflow.com/a/14792183/3951387
|
133 |
+
e.originalEvent.dataTransfer.dropEffect = 'move';
|
134 |
+
return false;
|
135 |
+
}
|
136 |
+
}
|
137 |
+
}
|
138 |
+
}
|
139 |
+
|
140 |
+
//Firing HTML5 DragLeave only when all the DragEnter'ed child elements were DragLeave'd - http://stackoverflow.com/a/21002544
|
141 |
+
var counter = {};
|
142 |
+
function handleDragEnter(e) {
|
143 |
+
// this / e.target is the current hover target.
|
144 |
+
e = e || event;
|
145 |
+
if (e.originalEvent.dataTransfer.types) {
|
146 |
+
for (var i = 0; i < e.originalEvent.dataTransfer.types.length; i++) {
|
147 |
+
if (e.originalEvent.dataTransfer.types[i] == 'Files') {
|
148 |
+
this.classList.add('dragover');
|
149 |
+
counter[jQuery(this).data('entry')]++;//or without jQuery: this.getAttribute('data-entry')
|
150 |
+
break;
|
151 |
+
}
|
152 |
+
}
|
153 |
+
}
|
154 |
+
}
|
155 |
+
|
156 |
+
function handleDragLeave(e) {
|
157 |
+
e = e || event;
|
158 |
+
if (e.originalEvent.dataTransfer.types) {
|
159 |
+
for (var i = 0; i < e.originalEvent.dataTransfer.types.length; i++) {
|
160 |
+
if (e.originalEvent.dataTransfer.types[i] == 'Files') {
|
161 |
+
counter[jQuery(this).data('entry')]--;
|
162 |
+
if (counter[jQuery(this).data('entry')] === 0) {
|
163 |
+
this.classList.remove('dragover');// this / e.target is previous target element.
|
164 |
+
}
|
165 |
+
break;
|
166 |
+
}
|
167 |
+
}
|
168 |
+
}
|
169 |
+
}
|
170 |
+
|
171 |
+
function handleDrop(e) {
|
172 |
+
e = e || event;
|
173 |
+
if (e.originalEvent.dataTransfer.types) {
|
174 |
+
for (var i = 0; i < e.originalEvent.dataTransfer.types.length; i++) {
|
175 |
+
if (e.originalEvent.dataTransfer.types[i] == 'Files') {
|
176 |
+
|
177 |
+
e.stopPropagation();// Stops some browsers from redirecting.
|
178 |
+
e.preventDefault();
|
179 |
+
|
180 |
+
processFiles(e.originalEvent.dataTransfer.files,jQuery(this).data('entry'));
|
181 |
+
counter[jQuery(this).data('entry')] = 0;
|
182 |
+
this.classList.remove('dragover');
|
183 |
+
break;
|
184 |
+
}
|
185 |
+
}
|
186 |
+
}
|
187 |
+
}
|
188 |
+
|
189 |
+
function handleBrowseButton(e) {
|
190 |
+
e = e || event;
|
191 |
+
processFiles(e.target.files,jQuery(this).closest('tr').data('entry'));
|
192 |
+
//Was thinking about purging input:file control - http://stackoverflow.com/questions/1043957/clearing-input-type-file-using-jquery
|
193 |
+
//Decided just to get rid of name properties thus such controls wouldn't be taken into consideration during form submit or processed with FormData
|
194 |
+
}
|
195 |
+
|
196 |
+
function processFiles(files,entry) {
|
197 |
+
for (var i = 0, f; f = files[i]; i++) {
|
198 |
+
//Processing only first qualifying file
|
199 |
+
if (f.type.indexOf('image/') == 0 && typeof dg_admin_vars.upload_limit != 'undefined' && f.size <= parseInt(dg_admin_vars.upload_limit)) {
|
200 |
+
var target;
|
201 |
+
var formData= new FormData(jQuery('[data-entry='+entry+']').closest('form')[0]);
|
202 |
+
if (typeof ajax_object != 'undefined' && typeof ajax_object.ajax_url != 'undefined') {
|
203 |
+
target = ajax_object.ajax_url;
|
204 |
+
formData.append('action', 'dg_upload_thumb');
|
205 |
+
} else {
|
206 |
+
target = jQuery('#tab-Thumbnail').attr('action');
|
207 |
+
}
|
208 |
+
formData.append('document_gallery[entry]', entry);
|
209 |
+
formData.append('document_gallery[ajax]', 'true');
|
210 |
+
formData.append('document_gallery[upload]', 'true');
|
211 |
+
formData.append('file', f);
|
212 |
+
var xhr = new XMLHttpRequest();
|
213 |
+
xhr.open('POST', target);
|
214 |
+
var theImg = jQuery('[data-entry='+entry+']').find('.column-icon img');
|
215 |
+
xhr.onreadystatechange = function() {
|
216 |
+
if (xhr.readyState == 4) {
|
217 |
+
if (xhr.responseText.indexOf("\n") == -1) {
|
218 |
+
eval('var response = ' + xhr.responseText + ';');
|
219 |
+
if (response.result) {
|
220 |
+
// check if generated thumbnail has the same url
|
221 |
+
if (response.url === theImg.attr('src')) {
|
222 |
+
theImg.attr('src', theImg.attr('src') + '?' + new Date().getTime());
|
223 |
+
} else {
|
224 |
+
theImg.attr('src', response.url);
|
225 |
+
}
|
226 |
+
}
|
227 |
+
} else {
|
228 |
+
console.log('Invalid response from server:');
|
229 |
+
console.log(xhr.responseText);
|
230 |
+
}
|
231 |
+
}
|
232 |
+
}
|
233 |
+
xhr.send(formData);
|
234 |
+
break;
|
235 |
+
}
|
236 |
+
}
|
237 |
+
}
|
238 |
+
|
239 |
+
// Prepairing all the drop-zones on page load
|
240 |
+
jQuery('#ThumbsTable tbody tr').each(function() {
|
241 |
+
jQuery(this)
|
242 |
+
.on('dragenter', handleDragEnter)
|
243 |
+
.on('dragover', handleDragOver)
|
244 |
+
.on('dragleave', handleDragLeave)
|
245 |
+
.on('drop', handleDrop);
|
246 |
+
counter[jQuery(this).data('entry')] = 0;
|
247 |
+
jQuery(this).find('input:button').on('click', function() {
|
248 |
+
jQuery(this).prevAll('input:file').click();
|
249 |
+
});
|
250 |
+
jQuery(this).find('input:file').on('change', handleBrowseButton);
|
251 |
+
});
|
252 |
+
|
253 |
+
//Checking Drag&Drop support
|
254 |
+
//Structure is Not supported in Chrome's WebKit
|
255 |
+
/*if (!('files' in DataTransfer.prototype)) {//Determine presence of HTML5 drag'n'drop file upload API - http://stackoverflow.com/a/2312859/3951387
|
256 |
+
jQuery('.html5dndmarker').hide();
|
257 |
+
}*/
|
258 |
+
if (!('draggable' in document.createElement('span'))) {
|
259 |
+
jQuery('.html5dndmarker').hide();
|
260 |
+
}
|
261 |
});
|
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__));
|
@@ -26,6 +26,9 @@ global $dg_options;
|
|
26 |
define('DG_OPTION_NAME', 'document_gallery');
|
27 |
$dg_options = get_option(DG_OPTION_NAME, null);
|
28 |
|
|
|
|
|
|
|
29 |
// logging functionality
|
30 |
include_once DG_PATH . 'inc/class-logger.php';
|
31 |
|
@@ -52,17 +55,25 @@ if (is_admin()) {
|
|
52 |
// admin house keeping
|
53 |
include_once DG_PATH . 'admin/class-admin.php';
|
54 |
|
55 |
-
// add
|
56 |
add_filter('plugin_action_links_' . DG_BASENAME, array('DG_Admin', 'addSettingsLink'));
|
|
|
57 |
|
58 |
// build options page
|
59 |
add_action('admin_menu', array('DG_Admin', 'addAdminPage'));
|
|
|
|
|
|
|
|
|
|
|
60 |
if (DG_Admin::doRegisterSettings()) {
|
61 |
add_action('admin_init', array('DG_Admin', 'registerSettings'));
|
62 |
}
|
63 |
} else {
|
64 |
// styling for gallery
|
65 |
-
|
|
|
|
|
66 |
add_action('wp_print_scripts', array('DocumentGallery', 'printCustomStyle'));
|
67 |
}
|
68 |
|
@@ -197,7 +208,6 @@ class DocumentGallery {
|
|
197 |
*/
|
198 |
private static function isValidOptionsStructure($o, $schema = null) {
|
199 |
if (is_null($schema)) {
|
200 |
-
include_once DG_PATH . 'inc/class-setup.php';
|
201 |
$schema = DG_Setup::getDefaultOptions(true);
|
202 |
}
|
203 |
|
@@ -228,13 +238,15 @@ class DocumentGallery {
|
|
228 |
*/
|
229 |
public static function localDateTimeFromTimestamp($timestamp) {
|
230 |
static $gmt_offet = null;
|
231 |
-
static $
|
|
|
232 |
if (is_null($gmt_offet)) {
|
233 |
$gmt_offet = get_option('gmt_offset');
|
234 |
-
$
|
|
|
235 |
}
|
236 |
|
237 |
-
return date_i18n($
|
238 |
}
|
239 |
|
240 |
/**
|
5 |
Plugin Name: Document Gallery
|
6 |
Plugin URI: http://wordpress.org/extend/plugins/document-gallery/
|
7 |
Description: Display non-images (and images) in gallery format on a page or post with the [dg] shortcode.
|
8 |
+
Version: 3.0.0-beta
|
9 |
Author: Dan Rossiter
|
10 |
Author URI: http://danrossiter.org/
|
11 |
License: GPLv2
|
12 |
Text Domain: document-gallery
|
13 |
*/
|
14 |
|
15 |
+
define('DG_VERSION', '3.0.0-beta');
|
16 |
|
17 |
// define helper paths & URLs
|
18 |
define('DG_BASENAME', plugin_basename(__FILE__));
|
26 |
define('DG_OPTION_NAME', 'document_gallery');
|
27 |
$dg_options = get_option(DG_OPTION_NAME, null);
|
28 |
|
29 |
+
// DG general utility functions
|
30 |
+
include_once DG_PATH . 'inc/class-util.php';
|
31 |
+
|
32 |
// logging functionality
|
33 |
include_once DG_PATH . 'inc/class-logger.php';
|
34 |
|
55 |
// admin house keeping
|
56 |
include_once DG_PATH . 'admin/class-admin.php';
|
57 |
|
58 |
+
// add links to plugin index
|
59 |
add_filter('plugin_action_links_' . DG_BASENAME, array('DG_Admin', 'addSettingsLink'));
|
60 |
+
add_filter('plugin_row_meta', array('DG_Admin', 'addDonateLink'), 10, 2);
|
61 |
|
62 |
// build options page
|
63 |
add_action('admin_menu', array('DG_Admin', 'addAdminPage'));
|
64 |
+
|
65 |
+
// add meta box for managing thumbnail generation to attachment Edit Media page
|
66 |
+
add_action('add_meta_boxes', array('DG_Admin', 'addMetaBox'));
|
67 |
+
add_action('wp_ajax_dg_upload_thumb', array('DG_Admin', 'saveMetaBox'));
|
68 |
+
|
69 |
if (DG_Admin::doRegisterSettings()) {
|
70 |
add_action('admin_init', array('DG_Admin', 'registerSettings'));
|
71 |
}
|
72 |
} else {
|
73 |
// styling for gallery
|
74 |
+
if (apply_filters('dg_use_default_gallery_style', true )) {
|
75 |
+
add_action('wp_enqueue_scripts', array('DocumentGallery', 'enqueueGalleryStyle'));
|
76 |
+
}
|
77 |
add_action('wp_print_scripts', array('DocumentGallery', 'printCustomStyle'));
|
78 |
}
|
79 |
|
208 |
*/
|
209 |
private static function isValidOptionsStructure($o, $schema = null) {
|
210 |
if (is_null($schema)) {
|
|
|
211 |
$schema = DG_Setup::getDefaultOptions(true);
|
212 |
}
|
213 |
|
238 |
*/
|
239 |
public static function localDateTimeFromTimestamp($timestamp) {
|
240 |
static $gmt_offet = null;
|
241 |
+
static $wp_date_format = null;
|
242 |
+
static $wp_time_format = null;
|
243 |
if (is_null($gmt_offet)) {
|
244 |
$gmt_offet = get_option('gmt_offset');
|
245 |
+
$wp_date_format = get_option('date_format');
|
246 |
+
$wp_time_format = get_option('time_format');
|
247 |
}
|
248 |
|
249 |
+
return '<span class="nowrap">'.date_i18n($wp_date_format, $timestamp + $gmt_offet * 3600).'</span> <span class="nowrap">'.date_i18n($wp_time_format, $timestamp + $gmt_offet * 3600).'</span>';
|
250 |
}
|
251 |
|
252 |
/**
|
inc/class-document.php
CHANGED
@@ -29,12 +29,12 @@ class DG_Document {
|
|
29 |
|
30 |
// init general document data
|
31 |
$this->gallery = $gallery;
|
32 |
-
$this->description = $attachment->post_content;
|
33 |
$this->ID = $attachment->ID;
|
34 |
$this->link = $gallery->linkToAttachmentPg()
|
35 |
? get_attachment_link($attachment->ID)
|
36 |
: wp_get_attachment_url($attachment->ID);
|
37 |
-
$this->title =
|
38 |
$this->title_attribute = esc_attr(strip_tags($this->title));
|
39 |
}
|
40 |
|
@@ -46,7 +46,6 @@ class DG_Document {
|
|
46 |
* Returns HTML representing this Document.
|
47 |
* @filter dg_icon_template Filters the DG icon HTML. Passes a single
|
48 |
* bool value indicating whether the gallery is using descriptions or not.
|
49 |
-
* @filter dg_doc_icon Deprecated. To be removed in a future relesase.
|
50 |
* @return string
|
51 |
*/
|
52 |
public function __toString() {
|
@@ -65,20 +64,20 @@ class DG_Document {
|
|
65 |
$description = ' <p>%description%</p>';
|
66 |
}
|
67 |
|
68 |
-
|
69 |
-
$doc_icon = apply_filters(
|
70 |
-
'dg_icon_template',
|
71 |
' <div class="document-icon">' . PHP_EOL .
|
72 |
' <a href="%link%"><img src="%img%" title="%title_attribute%" alt="%title_attribute%" /><br>%title%</a>' . PHP_EOL .
|
73 |
' </div>' . PHP_EOL .
|
74 |
-
$description
|
|
|
|
|
|
|
|
|
|
|
75 |
$this->gallery->useDescriptions(),
|
76 |
$this->ID);
|
77 |
|
78 |
-
|
79 |
-
|
80 |
-
// deprecated: users may filter icon here
|
81 |
-
return apply_filters('dg_doc_icon', $core, $this->ID, $this->gallery->useDescriptions());
|
82 |
}
|
83 |
}
|
84 |
|
29 |
|
30 |
// init general document data
|
31 |
$this->gallery = $gallery;
|
32 |
+
$this->description = wptexturize($attachment->post_content);
|
33 |
$this->ID = $attachment->ID;
|
34 |
$this->link = $gallery->linkToAttachmentPg()
|
35 |
? get_attachment_link($attachment->ID)
|
36 |
: wp_get_attachment_url($attachment->ID);
|
37 |
+
$this->title = wptexturize($attachment->post_title);
|
38 |
$this->title_attribute = esc_attr(strip_tags($this->title));
|
39 |
}
|
40 |
|
46 |
* Returns HTML representing this Document.
|
47 |
* @filter dg_icon_template Filters the DG icon HTML. Passes a single
|
48 |
* bool value indicating whether the gallery is using descriptions or not.
|
|
|
49 |
* @return string
|
50 |
*/
|
51 |
public function __toString() {
|
64 |
$description = ' <p>%description%</p>';
|
65 |
}
|
66 |
|
67 |
+
$doc_icon =
|
|
|
|
|
68 |
' <div class="document-icon">' . PHP_EOL .
|
69 |
' <a href="%link%"><img src="%img%" title="%title_attribute%" alt="%title_attribute%" /><br>%title%</a>' . PHP_EOL .
|
70 |
' </div>' . PHP_EOL .
|
71 |
+
$description;
|
72 |
+
|
73 |
+
// allow developers to filter icon output
|
74 |
+
$doc_icon = apply_filters(
|
75 |
+
'dg_icon_template',
|
76 |
+
$doc_icon,
|
77 |
$this->gallery->useDescriptions(),
|
78 |
$this->ID);
|
79 |
|
80 |
+
return str_replace($find, $repl, $doc_icon);
|
|
|
|
|
|
|
81 |
}
|
82 |
}
|
83 |
|
inc/class-gallery.php
CHANGED
@@ -77,8 +77,7 @@ class DG_Gallery {
|
|
77 |
* Initializes static values for this class.
|
78 |
*/
|
79 |
public static function init() {
|
80 |
-
if (!isset(self::$comment))
|
81 |
-
{
|
82 |
self::$comment =
|
83 |
PHP_EOL . '<!-- ' . __('Generated using Document Gallery. Get yours here: ', 'document-gallery') .
|
84 |
'http://wordpress.org/extend/plugins/document-gallery -->' . PHP_EOL;
|
@@ -93,9 +92,49 @@ class DG_Gallery {
|
|
93 |
* @param multitype:string $atts Array of attributes used in shortcode.
|
94 |
*/
|
95 |
public function __construct($atts) {
|
|
|
|
|
|
|
|
|
96 |
// empty string is passed when no arguments are given, but constructor expects an array
|
97 |
$atts = empty($atts) ? array() : $atts;
|
98 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
99 |
|
100 |
// values used to construct tax query (may be empty)
|
101 |
$this->taxa = array_diff_key($atts, $defaults);
|
@@ -103,35 +142,37 @@ class DG_Gallery {
|
|
103 |
// all recognized attributes go here
|
104 |
$this->atts = shortcode_atts($defaults, $atts);
|
105 |
|
106 |
-
// goes through all values in
|
107 |
-
$this->atts = self::sanitizeDefaults($this->atts, $this->errs);
|
108 |
|
109 |
// query DB for all documents requested
|
110 |
-
include_once DG_PATH . 'inc/class-document.php';
|
111 |
try {
|
112 |
-
$
|
113 |
-
|
114 |
-
foreach($docs as $doc) {
|
115 |
$this->docs[] = new DG_Document($doc, $this);
|
116 |
}
|
117 |
} catch(InvalidArgumentException $e) {
|
118 |
// errors will be printed in __toString()
|
119 |
}
|
120 |
}
|
121 |
-
|
122 |
/**
|
123 |
* Cleans up user input, making sure we don't pass crap on to WP core.
|
|
|
124 |
* @param multitype:string $defaults The defaults array to sanitize.
|
125 |
* @param multitype:string &$errs The array of errors, which will be appended with any errors found.
|
126 |
-
* @param bool $isDefaults Whether we're sanitizing the defaults array
|
127 |
*/
|
128 |
-
public static function sanitizeDefaults($defaults, &$errs
|
129 |
-
$old_defaults
|
|
|
|
|
130 |
|
131 |
// remove invalid keys
|
132 |
-
$sanitized =
|
133 |
-
|
134 |
-
|
|
|
|
|
135 |
foreach ($old_defaults as $k => $v) {
|
136 |
if (!isset($sanitized[$k])) {
|
137 |
if (is_bool($v)) {
|
@@ -141,29 +182,15 @@ class DG_Gallery {
|
|
141 |
// missing value
|
142 |
$sanitized[$k] = $v;
|
143 |
}
|
144 |
-
}
|
145 |
-
|
146 |
-
|
147 |
-
$sanitized[$k] = self::sanitizeParameter($k, $sanitized[$k], $errs);
|
148 |
-
}
|
149 |
-
|
150 |
-
// process mime_types attribute separately since default value varies depending on images attribute
|
151 |
-
// TODO: Cleaner way to handle this?
|
152 |
-
if (!$isDefaults) {
|
153 |
-
if (isset($defaults['mime_types'])) {
|
154 |
-
$sanitized['mime_types'] = self::sanitizeMimeTypes($defaults['mime_types'], $err);
|
155 |
-
if (isset($err)) {
|
156 |
-
$errs['mime_types'] = $err;
|
157 |
-
unset($err);
|
158 |
-
}
|
159 |
-
} else {
|
160 |
-
$sanitized['mime_types'] = self::getDefaultMimeTypes($sanitized['images']);
|
161 |
}
|
162 |
}
|
163 |
|
164 |
return $sanitized;
|
165 |
}
|
166 |
-
|
167 |
/**
|
168 |
*
|
169 |
* @param string $key The key to reference the current value in the defaults array.
|
@@ -176,9 +203,10 @@ class DG_Gallery {
|
|
176 |
$funct = $key;
|
177 |
$funct[0] = strtoupper($funct[0]);
|
178 |
$funct = 'sanitize' . preg_replace_callback('/_([a-z])/', array(__CLASS__, 'secondCharToUpper'), $funct);
|
179 |
-
|
180 |
$callable = array(__CLASS__, $funct);
|
181 |
-
|
|
|
182 |
if (DG_Logger::logEnabled() && !method_exists(__CLASS__, $funct)) {
|
183 |
DG_Logger::writeLog(
|
184 |
DG_LogLevel::Error,
|
@@ -188,15 +216,15 @@ class DG_Gallery {
|
|
188 |
|
189 |
// call param-specific sanitization
|
190 |
$ret = call_user_func_array($callable, array($value, &$err));
|
191 |
-
|
192 |
// check for error and return default
|
193 |
-
if (
|
194 |
$defaults = self::getOptions();
|
195 |
$ret = $defaults[$key];
|
196 |
-
|
197 |
$errs[$key] = $err;
|
198 |
}
|
199 |
-
|
200 |
return $ret;
|
201 |
}
|
202 |
|
@@ -216,6 +244,16 @@ class DG_Gallery {
|
|
216 |
return $ret;
|
217 |
}
|
218 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
219 |
/**
|
220 |
* Takes the provided value and returns a sanitized value.
|
221 |
* @param string $value The descriptions value to be sanitized.
|
@@ -232,6 +270,16 @@ class DG_Gallery {
|
|
232 |
return $ret;
|
233 |
}
|
234 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
235 |
/**
|
236 |
* Takes the provided value and returns a sanitized value.
|
237 |
* @param string $value The fancy value to be sanitized.
|
@@ -247,27 +295,32 @@ class DG_Gallery {
|
|
247 |
|
248 |
return $ret;
|
249 |
}
|
250 |
-
|
251 |
/**
|
252 |
* Takes the provided value and returns a sanitized value.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
253 |
* @param string $value The ids value to be sanitized.
|
254 |
* @param multitype:string &$errs The array of errors, which will be appended with any errors found.
|
255 |
-
* @return bool|multitype:int The sanitized
|
256 |
*/
|
257 |
-
private static function
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
$
|
264 |
-
|
265 |
-
if(!empty($bad)) {
|
266 |
-
$err = _n('The following ID is invalid: ',
|
267 |
-
'The following IDs are invalid: ',
|
268 |
-
count($bad), 'document-gallery') . implode(', ', $bad);
|
269 |
-
$ret = null;
|
270 |
-
}
|
271 |
}
|
272 |
|
273 |
return $ret;
|
@@ -275,18 +328,12 @@ class DG_Gallery {
|
|
275 |
|
276 |
/**
|
277 |
* Takes the provided value and returns a sanitized value.
|
278 |
-
* @param string $value The
|
279 |
* @param multitype:string &$errs The array of errors, which will be appended with any errors found.
|
280 |
-
* @return bool The sanitized
|
281 |
*/
|
282 |
-
private static function
|
283 |
-
|
284 |
-
|
285 |
-
if(is_null($ret)) {
|
286 |
-
$err = sprintf(self::$binary_err, 'images', 'true', 'false', $value);
|
287 |
-
}
|
288 |
-
|
289 |
-
return $ret;
|
290 |
}
|
291 |
|
292 |
/**
|
@@ -297,27 +344,11 @@ class DG_Gallery {
|
|
297 |
*/
|
298 |
private static function sanitizeLimit($value, &$err) {
|
299 |
$ret = intval($value);
|
300 |
-
|
301 |
if (is_null($ret) || $ret < -1) {
|
302 |
$err = sprintf(self::$unary_err, 'limit', '>= -1');
|
303 |
$ret = null;
|
304 |
}
|
305 |
-
|
306 |
-
return $ret;
|
307 |
-
}
|
308 |
-
|
309 |
-
/**
|
310 |
-
* Takes the provided value and returns a sanitized value.
|
311 |
-
* @param string $value The localpost value to be sanitized.
|
312 |
-
* @param multitype:string &$errs The array of errors, which will be appended with any errors found.
|
313 |
-
* @return bool The sanitized localpost value.
|
314 |
-
*/
|
315 |
-
private static function sanitizeLocalpost($value, &$err) {
|
316 |
-
$ret = self::toBool($value);
|
317 |
-
|
318 |
-
if(is_null($ret)) {
|
319 |
-
$err = sprintf(self::$binary_err, 'localpost', 'true', 'false', $value);
|
320 |
-
}
|
321 |
|
322 |
return $ret;
|
323 |
}
|
@@ -332,20 +363,6 @@ class DG_Gallery {
|
|
332 |
// TODO: do some actual sanitization...
|
333 |
return $value;
|
334 |
}
|
335 |
-
|
336 |
-
/**
|
337 |
-
* Gets the default mime types if no attribute is set.
|
338 |
-
* @param bool $ingImages Whether images are included in this gallery.
|
339 |
-
* @return string The comma-delimited mime types.
|
340 |
-
*/
|
341 |
-
private static function getDefaultMimeTypes($incImages) {
|
342 |
-
$mime_types = array('application', 'video', 'text', 'audio');
|
343 |
-
if ($incImages) {
|
344 |
-
$mime_types[] = 'image';
|
345 |
-
}
|
346 |
-
|
347 |
-
return implode(',', $mime_types);
|
348 |
-
}
|
349 |
|
350 |
/**
|
351 |
* Takes the provided value and returns a sanitized value.
|
@@ -355,7 +372,7 @@ class DG_Gallery {
|
|
355 |
*/
|
356 |
private static function sanitizeOrder($value, &$err) {
|
357 |
$ret = strtoupper($value);
|
358 |
-
|
359 |
if(!in_array($ret, self::getOrderOptions())) {
|
360 |
$err = sprintf(self::$binary_err, 'order', 'ASC', 'DESC', $value);
|
361 |
$ret = null;
|
@@ -379,7 +396,7 @@ class DG_Gallery {
|
|
379 |
*/
|
380 |
private static function sanitizeOrderby($value, &$err) {
|
381 |
$ret = ('ID' === strtoupper($value)) ? 'ID' : strtolower($value);
|
382 |
-
|
383 |
if (!in_array($ret, self::getOrderbyOptions())) {
|
384 |
$err = sprintf(self::$unary_err, 'orderby', $value);
|
385 |
$ret = null;
|
@@ -396,7 +413,7 @@ class DG_Gallery {
|
|
396 |
'menu_order', 'modified', 'name', 'none',
|
397 |
'parent', 'post__in', 'rand', 'title');
|
398 |
}
|
399 |
-
|
400 |
/**
|
401 |
* Takes the provided value and returns a sanitized value.
|
402 |
* @param string $value The post_status value to be sanitized.
|
@@ -404,16 +421,16 @@ class DG_Gallery {
|
|
404 |
* @return string The sanitized post_status value.
|
405 |
*/
|
406 |
private static function sanitizePostStatus($value, &$err) {
|
407 |
-
$ret = preg_grep('
|
408 |
$ret = reset($ret);
|
409 |
-
|
410 |
if($ret === false) {
|
411 |
$err = sprintf(self::$unary_err, 'post_status', $value);
|
412 |
}
|
413 |
-
|
414 |
return $ret;
|
415 |
}
|
416 |
-
|
417 |
/**
|
418 |
* @return multitype:string All registered post statuses.
|
419 |
*/
|
@@ -424,10 +441,10 @@ class DG_Gallery {
|
|
424 |
$statuses[] = 'any';
|
425 |
asort($statuses);
|
426 |
}
|
427 |
-
|
428 |
return $statuses;
|
429 |
}
|
430 |
-
|
431 |
/**
|
432 |
* Takes the provided value and returns a sanitized value.
|
433 |
* @param string $value The post_type value to be sanitized.
|
@@ -435,16 +452,16 @@ class DG_Gallery {
|
|
435 |
* @return string The sanitized post_type value.
|
436 |
*/
|
437 |
private static function sanitizePostType($value, &$err) {
|
438 |
-
$ret = preg_grep('
|
439 |
$ret = reset($ret);
|
440 |
-
|
441 |
if($ret === false) {
|
442 |
$err = sprintf(self::$unary_err, 'post_type', $value);
|
443 |
}
|
444 |
-
|
445 |
return $ret;
|
446 |
}
|
447 |
-
|
448 |
/**
|
449 |
* @return multitype:string All registered post types.
|
450 |
*/
|
@@ -455,7 +472,7 @@ class DG_Gallery {
|
|
455 |
$types[] = 'any';
|
456 |
asort($types);
|
457 |
}
|
458 |
-
|
459 |
return $types;
|
460 |
}
|
461 |
|
@@ -467,7 +484,7 @@ class DG_Gallery {
|
|
467 |
*/
|
468 |
private static function sanitizeRelation($value, &$err) {
|
469 |
$ret = strtoupper($value);
|
470 |
-
|
471 |
if(!in_array($ret, self::getRelationOptions())) {
|
472 |
$err = sprintf(self::$binary_err, 'relation', 'AND', 'OR', $value);
|
473 |
$ret = null;
|
@@ -490,7 +507,7 @@ class DG_Gallery {
|
|
490 |
*/
|
491 |
private function sanitizeOperator($operator) {
|
492 |
$ret = strtoupper($operator);
|
493 |
-
|
494 |
if (!in_array($ret, self::getOperatorOptions())) {
|
495 |
$this->errs[] = sprintf(self::$binary_err, $key, 'IN", "NOT IN", "OR', 'AND', $operator);
|
496 |
$ret = null;
|
@@ -507,9 +524,10 @@ class DG_Gallery {
|
|
507 |
public static function getOperatorOptions() {
|
508 |
return array('IN', 'NOT IN', 'AND', 'OR');
|
509 |
}
|
510 |
-
|
511 |
/**
|
512 |
* Gets all valid Documents based on the attributes passed by the user.
|
|
|
513 |
* @return multitype:unknown Contains all documents matching the query.
|
514 |
* @throws InvalidArgumentException Thrown when $this->errs is not empty.
|
515 |
*/
|
@@ -522,19 +540,28 @@ class DG_Gallery {
|
|
522 |
'post_type' => $this->atts['post_type'],
|
523 |
'post_mime_type' => $this->atts['mime_types']);
|
524 |
|
525 |
-
$query['post_parent'] =
|
526 |
-
$this->atts['localpost']
|
527 |
-
&& ($post = get_post()) ? $post->ID : '';
|
528 |
-
|
529 |
$this->setTaxa($query);
|
530 |
|
531 |
if(!empty($this->errs)) {
|
532 |
throw new InvalidArgumentException();
|
533 |
}
|
534 |
|
535 |
-
|
536 |
-
|
537 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
538 |
}
|
539 |
|
540 |
/**
|
@@ -549,7 +576,7 @@ class DG_Gallery {
|
|
549 |
$operator = array();
|
550 |
$suffix = array('relation', 'operator');
|
551 |
$pattern = '/(.+)_(?:' . implode('|', $suffix) . ')$/i';
|
552 |
-
|
553 |
// find any relations for taxa
|
554 |
$iterable = $this->taxa;
|
555 |
foreach ($iterable as $key => $value) {
|
@@ -561,7 +588,7 @@ class DG_Gallery {
|
|
561 |
}
|
562 |
}
|
563 |
}
|
564 |
-
|
565 |
// build tax query
|
566 |
foreach ($this->taxa as $taxon => $terms) {
|
567 |
$terms = $this->getTermIdsByNames($taxon, explode(',', $terms));
|
@@ -619,11 +646,11 @@ class DG_Gallery {
|
|
619 |
private function getTermXByNames($x, $taxon, $term_names) {
|
620 |
$ret = array();
|
621 |
$valid = true;
|
622 |
-
|
623 |
// taxons may optionally be prefixed by 'tax_' --
|
624 |
// this is only useful when avoiding collisions with other attributes
|
625 |
if (!taxonomy_exists($taxon)) {
|
626 |
-
$tmp = preg_replace('
|
627 |
if ($count > 0 && taxonomy_exists($tmp)) {
|
628 |
$taxon = $tmp;
|
629 |
} else {
|
@@ -647,22 +674,6 @@ class DG_Gallery {
|
|
647 |
return $ret;
|
648 |
}
|
649 |
|
650 |
-
/**
|
651 |
-
* Given a list of IDs, all attachments represented by these IDs are returned.
|
652 |
-
* @return multitype:Post The posts matched.
|
653 |
-
*/
|
654 |
-
private function getAttachmentsByIds() {
|
655 |
-
$args = array(
|
656 |
-
'post_type' => $this->atts['post_type'],
|
657 |
-
'post_status' => $this->atts['post_status'],
|
658 |
-
'numberposts' => $this->atts['limit'],
|
659 |
-
'post__in' => $this->atts['ids'],
|
660 |
-
'orderby' => 'post__in'
|
661 |
-
);
|
662 |
-
|
663 |
-
return count($args['post__in']) ? get_posts($args) : array();
|
664 |
-
}
|
665 |
-
|
666 |
/**
|
667 |
* @param string $string To take second char from.
|
668 |
* @return char Capitalized second char of given string.
|
@@ -670,7 +681,7 @@ class DG_Gallery {
|
|
670 |
private static function secondCharToUpper($string) {
|
671 |
return strtoupper($string[1]);
|
672 |
}
|
673 |
-
|
674 |
/**
|
675 |
* Function returns false for positive ints, true otherwise.
|
676 |
* @param string $var could be anything.
|
@@ -691,16 +702,16 @@ class DG_Gallery {
|
|
691 |
if (is_null($val)) {
|
692 |
return false;
|
693 |
}
|
694 |
-
|
695 |
if (is_bool($val)) {
|
696 |
return $val;
|
697 |
}
|
698 |
-
|
699 |
if (is_int($val)) {
|
700 |
if (1 === $val) {
|
701 |
return true;
|
702 |
}
|
703 |
-
|
704 |
if (0 === $val) {
|
705 |
return false;
|
706 |
}
|
@@ -731,22 +742,31 @@ class DG_Gallery {
|
|
731 |
* @return string HTML representing this Gallery.
|
732 |
*/
|
733 |
public function __toString() {
|
|
|
|
|
|
|
734 |
static $find = null;
|
735 |
if (is_null($find)) {
|
736 |
$find = array('%class%', '%icons%');
|
737 |
}
|
738 |
-
|
739 |
-
if(!empty($this->errs)) {
|
740 |
return '<p>' . implode('</p><p>', $this->errs) . '</p>';
|
741 |
}
|
742 |
|
743 |
-
if(empty($this->docs)) {
|
744 |
return self::$no_docs;
|
745 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
746 |
|
747 |
$icon_wrapper = apply_filters(
|
748 |
'dg_row_template',
|
749 |
-
|
750 |
$this->useDescriptions());
|
751 |
|
752 |
$core = '';
|
@@ -762,10 +782,20 @@ class DG_Gallery {
|
|
762 |
$core .= str_replace($find, $repl, $icon_wrapper);
|
763 |
}
|
764 |
} else {
|
765 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
766 |
$repl[1] = '';
|
767 |
|
768 |
-
$min = min($i+
|
769 |
for($x = $i; $x < $min; $x++) {
|
770 |
$repl[1] .= $this->docs[$x];
|
771 |
}
|
77 |
* Initializes static values for this class.
|
78 |
*/
|
79 |
public static function init() {
|
80 |
+
if (!isset(self::$comment)) {
|
|
|
81 |
self::$comment =
|
82 |
PHP_EOL . '<!-- ' . __('Generated using Document Gallery. Get yours here: ', 'document-gallery') .
|
83 |
'http://wordpress.org/extend/plugins/document-gallery -->' . PHP_EOL;
|
92 |
* @param multitype:string $atts Array of attributes used in shortcode.
|
93 |
*/
|
94 |
public function __construct($atts) {
|
95 |
+
include_once DG_PATH . 'inc/class-document.php';
|
96 |
+
|
97 |
+
$post = get_post();
|
98 |
+
|
99 |
// empty string is passed when no arguments are given, but constructor expects an array
|
100 |
$atts = empty($atts) ? array() : $atts;
|
101 |
+
|
102 |
+
if (!empty($atts['ids'])) {
|
103 |
+
// 'ids' is explicitly ordered, unless you specify otherwise.
|
104 |
+
if (empty($atts['orderby'])) {
|
105 |
+
$atts['orderby'] = 'post__in';
|
106 |
+
}
|
107 |
+
|
108 |
+
$atts['include'] = $atts['ids'];
|
109 |
+
unset($atts['ids']);
|
110 |
+
}
|
111 |
+
|
112 |
+
// allow abbreviated columns attribute
|
113 |
+
if (!empty($atts['cols'])) {
|
114 |
+
$atts['columns'] = $atts['cols'];
|
115 |
+
unset($atts['cols']);
|
116 |
+
}
|
117 |
+
|
118 |
+
if (!empty($atts['images'])) {
|
119 |
+
$options = self::getOptions();
|
120 |
+
$mimes = trim(isset($atts['mime_types']) ? $atts['mime_types'] : $options['mime_types']);
|
121 |
+
if (!preg_match('/[,^]image[,$]/', $mimes)) {
|
122 |
+
$atts['mime_types'] = empty($mimes) ? 'image' : ($mimes . ',image');
|
123 |
+
}
|
124 |
+
}
|
125 |
+
|
126 |
+
/**
|
127 |
+
* @deprecated localpost will be removed at some point.
|
128 |
+
*/
|
129 |
+
if (!empty($atts['localpost'])) {
|
130 |
+
$atts['id'] = -1;
|
131 |
+
unset($atts['localpost']);
|
132 |
+
}
|
133 |
+
|
134 |
+
// merge options w/ default values not stored in options
|
135 |
+
$defaults = array_merge(
|
136 |
+
array('id' => $post->ID, 'include' => '', 'exclude' => ''),
|
137 |
+
self::getOptions());
|
138 |
|
139 |
// values used to construct tax query (may be empty)
|
140 |
$this->taxa = array_diff_key($atts, $defaults);
|
142 |
// all recognized attributes go here
|
143 |
$this->atts = shortcode_atts($defaults, $atts);
|
144 |
|
145 |
+
// goes through all values in atts, setting errs as needed
|
146 |
+
$this->atts = self::sanitizeDefaults($defaults, $this->atts, $this->errs);
|
147 |
|
148 |
// query DB for all documents requested
|
|
|
149 |
try {
|
150 |
+
foreach($this->getDocuments() as $doc) {
|
|
|
|
|
151 |
$this->docs[] = new DG_Document($doc, $this);
|
152 |
}
|
153 |
} catch(InvalidArgumentException $e) {
|
154 |
// errors will be printed in __toString()
|
155 |
}
|
156 |
}
|
157 |
+
|
158 |
/**
|
159 |
* Cleans up user input, making sure we don't pass crap on to WP core.
|
160 |
+
* @param multitype:string $old_defaults The previous set of defaults.
|
161 |
* @param multitype:string $defaults The defaults array to sanitize.
|
162 |
* @param multitype:string &$errs The array of errors, which will be appended with any errors found.
|
163 |
+
* @param bool $isDefaults Whether we're sanitizing the defaults array from DG_Admin.
|
164 |
*/
|
165 |
+
public static function sanitizeDefaults($old_defaults, $defaults, &$errs) {
|
166 |
+
if (is_null($old_defaults)) {
|
167 |
+
$old_defaults = self::getOptions();
|
168 |
+
}
|
169 |
|
170 |
// remove invalid keys
|
171 |
+
$sanitized = is_array($defaults)
|
172 |
+
? array_intersect_key($defaults, $old_defaults)
|
173 |
+
: array();
|
174 |
+
|
175 |
+
// add any missing keys & sanitize each new value
|
176 |
foreach ($old_defaults as $k => $v) {
|
177 |
if (!isset($sanitized[$k])) {
|
178 |
if (is_bool($v)) {
|
182 |
// missing value
|
183 |
$sanitized[$k] = $v;
|
184 |
}
|
185 |
+
} else if ($sanitized[$k] != $v) {
|
186 |
+
// sanitize value if different from old value
|
187 |
+
$sanitized[$k] = self::sanitizeParameter($k, $sanitized[$k], $errs);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
188 |
}
|
189 |
}
|
190 |
|
191 |
return $sanitized;
|
192 |
}
|
193 |
+
|
194 |
/**
|
195 |
*
|
196 |
* @param string $key The key to reference the current value in the defaults array.
|
203 |
$funct = $key;
|
204 |
$funct[0] = strtoupper($funct[0]);
|
205 |
$funct = 'sanitize' . preg_replace_callback('/_([a-z])/', array(__CLASS__, 'secondCharToUpper'), $funct);
|
206 |
+
|
207 |
$callable = array(__CLASS__, $funct);
|
208 |
+
|
209 |
+
// avoid looking for method beforehand unless we're running in debug mode -- expensive call
|
210 |
if (DG_Logger::logEnabled() && !method_exists(__CLASS__, $funct)) {
|
211 |
DG_Logger::writeLog(
|
212 |
DG_LogLevel::Error,
|
216 |
|
217 |
// call param-specific sanitization
|
218 |
$ret = call_user_func_array($callable, array($value, &$err));
|
219 |
+
|
220 |
// check for error and return default
|
221 |
+
if (isset($err)) {
|
222 |
$defaults = self::getOptions();
|
223 |
$ret = $defaults[$key];
|
224 |
+
|
225 |
$errs[$key] = $err;
|
226 |
}
|
227 |
+
|
228 |
return $ret;
|
229 |
}
|
230 |
|
244 |
return $ret;
|
245 |
}
|
246 |
|
247 |
+
/**
|
248 |
+
* Takes the provided value and returns a sanitized value.
|
249 |
+
* @param string $value The columns value to be sanitized.
|
250 |
+
* @param multitype:string &$errs The array of errors, which will be appended with any errors found.
|
251 |
+
* @return int The sanitized columns value.
|
252 |
+
*/
|
253 |
+
public static function sanitizeColumns($value, &$err) {
|
254 |
+
return $value != -1 ? absint($value) : null;
|
255 |
+
}
|
256 |
+
|
257 |
/**
|
258 |
* Takes the provided value and returns a sanitized value.
|
259 |
* @param string $value The descriptions value to be sanitized.
|
270 |
return $ret;
|
271 |
}
|
272 |
|
273 |
+
/**
|
274 |
+
* Takes the provided value and returns a sanitized value.
|
275 |
+
* @param string $value The exclude value to be sanitized.
|
276 |
+
* @param multitype:string &$errs The array of errors, which will be appended with any errors found.
|
277 |
+
* @return bool The sanitized exclude value.
|
278 |
+
*/
|
279 |
+
private static function sanitizeExclude($value, &$err) {
|
280 |
+
return self::sanitizeIdList('Exclude', $value, $err);
|
281 |
+
}
|
282 |
+
|
283 |
/**
|
284 |
* Takes the provided value and returns a sanitized value.
|
285 |
* @param string $value The fancy value to be sanitized.
|
295 |
|
296 |
return $ret;
|
297 |
}
|
298 |
+
|
299 |
/**
|
300 |
* Takes the provided value and returns a sanitized value.
|
301 |
+
* @param string $value The id value to be sanitized.
|
302 |
+
* @param multitype:string &$errs The array of errors, which will be appended with any errors found.
|
303 |
+
* @return int The sanitized id value.
|
304 |
+
*/
|
305 |
+
private static function sanitizeId($value, &$err) {
|
306 |
+
return $value != -1 ? absint($value) : null;
|
307 |
+
}
|
308 |
+
|
309 |
+
/**
|
310 |
+
* Takes the provided comma-delimited list of IDs and returns null if it is invalid.
|
311 |
+
* @param string $name Name of the value being sanitized. Used in error string when needed.
|
312 |
* @param string $value The ids value to be sanitized.
|
313 |
* @param multitype:string &$errs The array of errors, which will be appended with any errors found.
|
314 |
+
* @return bool|multitype:int The sanitized comma-delimited list of IDs value.
|
315 |
*/
|
316 |
+
private static function sanitizeIdList($name, $value, &$err) {
|
317 |
+
static $regex = '/(?:|\d+(?:,\d+)*)/';
|
318 |
+
|
319 |
+
$ret = $value;
|
320 |
+
|
321 |
+
if (!preg_match($regex, $value)) {
|
322 |
+
$err = sprintf(__('%s may only be a comma-delimited list of integers.', 'document-gallery'), name);
|
323 |
+
$ret = null;
|
|
|
|
|
|
|
|
|
|
|
|
|
324 |
}
|
325 |
|
326 |
return $ret;
|
328 |
|
329 |
/**
|
330 |
* Takes the provided value and returns a sanitized value.
|
331 |
+
* @param string $value The ids value to be sanitized.
|
332 |
* @param multitype:string &$errs The array of errors, which will be appended with any errors found.
|
333 |
+
* @return bool|multitype:int The sanitized ids value.
|
334 |
*/
|
335 |
+
private static function sanitizeInclude($value, &$err) {
|
336 |
+
return self::sanitizeIdList('Include', $value, $err);
|
|
|
|
|
|
|
|
|
|
|
|
|
337 |
}
|
338 |
|
339 |
/**
|
344 |
*/
|
345 |
private static function sanitizeLimit($value, &$err) {
|
346 |
$ret = intval($value);
|
347 |
+
|
348 |
if (is_null($ret) || $ret < -1) {
|
349 |
$err = sprintf(self::$unary_err, 'limit', '>= -1');
|
350 |
$ret = null;
|
351 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
352 |
|
353 |
return $ret;
|
354 |
}
|
363 |
// TODO: do some actual sanitization...
|
364 |
return $value;
|
365 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
366 |
|
367 |
/**
|
368 |
* Takes the provided value and returns a sanitized value.
|
372 |
*/
|
373 |
private static function sanitizeOrder($value, &$err) {
|
374 |
$ret = strtoupper($value);
|
375 |
+
|
376 |
if(!in_array($ret, self::getOrderOptions())) {
|
377 |
$err = sprintf(self::$binary_err, 'order', 'ASC', 'DESC', $value);
|
378 |
$ret = null;
|
396 |
*/
|
397 |
private static function sanitizeOrderby($value, &$err) {
|
398 |
$ret = ('ID' === strtoupper($value)) ? 'ID' : strtolower($value);
|
399 |
+
|
400 |
if (!in_array($ret, self::getOrderbyOptions())) {
|
401 |
$err = sprintf(self::$unary_err, 'orderby', $value);
|
402 |
$ret = null;
|
413 |
'menu_order', 'modified', 'name', 'none',
|
414 |
'parent', 'post__in', 'rand', 'title');
|
415 |
}
|
416 |
+
|
417 |
/**
|
418 |
* Takes the provided value and returns a sanitized value.
|
419 |
* @param string $value The post_status value to be sanitized.
|
421 |
* @return string The sanitized post_status value.
|
422 |
*/
|
423 |
private static function sanitizePostStatus($value, &$err) {
|
424 |
+
$ret = preg_grep('/^' . preg_quote($value) .'$/i', self::getPostStatuses());
|
425 |
$ret = reset($ret);
|
426 |
+
|
427 |
if($ret === false) {
|
428 |
$err = sprintf(self::$unary_err, 'post_status', $value);
|
429 |
}
|
430 |
+
|
431 |
return $ret;
|
432 |
}
|
433 |
+
|
434 |
/**
|
435 |
* @return multitype:string All registered post statuses.
|
436 |
*/
|
441 |
$statuses[] = 'any';
|
442 |
asort($statuses);
|
443 |
}
|
444 |
+
|
445 |
return $statuses;
|
446 |
}
|
447 |
+
|
448 |
/**
|
449 |
* Takes the provided value and returns a sanitized value.
|
450 |
* @param string $value The post_type value to be sanitized.
|
452 |
* @return string The sanitized post_type value.
|
453 |
*/
|
454 |
private static function sanitizePostType($value, &$err) {
|
455 |
+
$ret = preg_grep('/^' . preg_quote($value) .'$/i', self::getPostTypes());
|
456 |
$ret = reset($ret);
|
457 |
+
|
458 |
if($ret === false) {
|
459 |
$err = sprintf(self::$unary_err, 'post_type', $value);
|
460 |
}
|
461 |
+
|
462 |
return $ret;
|
463 |
}
|
464 |
+
|
465 |
/**
|
466 |
* @return multitype:string All registered post types.
|
467 |
*/
|
472 |
$types[] = 'any';
|
473 |
asort($types);
|
474 |
}
|
475 |
+
|
476 |
return $types;
|
477 |
}
|
478 |
|
484 |
*/
|
485 |
private static function sanitizeRelation($value, &$err) {
|
486 |
$ret = strtoupper($value);
|
487 |
+
|
488 |
if(!in_array($ret, self::getRelationOptions())) {
|
489 |
$err = sprintf(self::$binary_err, 'relation', 'AND', 'OR', $value);
|
490 |
$ret = null;
|
507 |
*/
|
508 |
private function sanitizeOperator($operator) {
|
509 |
$ret = strtoupper($operator);
|
510 |
+
|
511 |
if (!in_array($ret, self::getOperatorOptions())) {
|
512 |
$this->errs[] = sprintf(self::$binary_err, $key, 'IN", "NOT IN", "OR', 'AND', $operator);
|
513 |
$ret = null;
|
524 |
public static function getOperatorOptions() {
|
525 |
return array('IN', 'NOT IN', 'AND', 'OR');
|
526 |
}
|
527 |
+
|
528 |
/**
|
529 |
* Gets all valid Documents based on the attributes passed by the user.
|
530 |
+
* NOTE: Keys in returned array are arbitrary and will vary. They should be ignored.
|
531 |
* @return multitype:unknown Contains all documents matching the query.
|
532 |
* @throws InvalidArgumentException Thrown when $this->errs is not empty.
|
533 |
*/
|
540 |
'post_type' => $this->atts['post_type'],
|
541 |
'post_mime_type' => $this->atts['mime_types']);
|
542 |
|
|
|
|
|
|
|
|
|
543 |
$this->setTaxa($query);
|
544 |
|
545 |
if(!empty($this->errs)) {
|
546 |
throw new InvalidArgumentException();
|
547 |
}
|
548 |
|
549 |
+
// NOTE: Derived from gallery shortcode
|
550 |
+
if (!empty($this->atts['include'])) {
|
551 |
+
$query['include'] = $this->atts['include'];
|
552 |
+
$attachments = get_posts($query);
|
553 |
+
} else {
|
554 |
+
// id == 0 => all attachments w/o a parent
|
555 |
+
// id == null => all matched attachments
|
556 |
+
$query['post_parent'] = $this->atts['id'];
|
557 |
+
if (!empty($exclude)) {
|
558 |
+
$query['exclude'] = $this->atts['exclude'];
|
559 |
+
}
|
560 |
+
|
561 |
+
$attachments = get_children($query);
|
562 |
+
}
|
563 |
+
|
564 |
+
return $attachments;
|
565 |
}
|
566 |
|
567 |
/**
|
576 |
$operator = array();
|
577 |
$suffix = array('relation', 'operator');
|
578 |
$pattern = '/(.+)_(?:' . implode('|', $suffix) . ')$/i';
|
579 |
+
|
580 |
// find any relations for taxa
|
581 |
$iterable = $this->taxa;
|
582 |
foreach ($iterable as $key => $value) {
|
588 |
}
|
589 |
}
|
590 |
}
|
591 |
+
|
592 |
// build tax query
|
593 |
foreach ($this->taxa as $taxon => $terms) {
|
594 |
$terms = $this->getTermIdsByNames($taxon, explode(',', $terms));
|
646 |
private function getTermXByNames($x, $taxon, $term_names) {
|
647 |
$ret = array();
|
648 |
$valid = true;
|
649 |
+
|
650 |
// taxons may optionally be prefixed by 'tax_' --
|
651 |
// this is only useful when avoiding collisions with other attributes
|
652 |
if (!taxonomy_exists($taxon)) {
|
653 |
+
$tmp = preg_replace('/^tax_(.*)/', '$1', $taxon, 1, $count);
|
654 |
if ($count > 0 && taxonomy_exists($tmp)) {
|
655 |
$taxon = $tmp;
|
656 |
} else {
|
674 |
return $ret;
|
675 |
}
|
676 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
677 |
/**
|
678 |
* @param string $string To take second char from.
|
679 |
* @return char Capitalized second char of given string.
|
681 |
private static function secondCharToUpper($string) {
|
682 |
return strtoupper($string[1]);
|
683 |
}
|
684 |
+
|
685 |
/**
|
686 |
* Function returns false for positive ints, true otherwise.
|
687 |
* @param string $var could be anything.
|
702 |
if (is_null($val)) {
|
703 |
return false;
|
704 |
}
|
705 |
+
|
706 |
if (is_bool($val)) {
|
707 |
return $val;
|
708 |
}
|
709 |
+
|
710 |
if (is_int($val)) {
|
711 |
if (1 === $val) {
|
712 |
return true;
|
713 |
}
|
714 |
+
|
715 |
if (0 === $val) {
|
716 |
return false;
|
717 |
}
|
742 |
* @return string HTML representing this Gallery.
|
743 |
*/
|
744 |
public function __toString() {
|
745 |
+
static $instance = 0;
|
746 |
+
$instance++;
|
747 |
+
|
748 |
static $find = null;
|
749 |
if (is_null($find)) {
|
750 |
$find = array('%class%', '%icons%');
|
751 |
}
|
752 |
+
|
753 |
+
if (!empty($this->errs)) {
|
754 |
return '<p>' . implode('</p><p>', $this->errs) . '</p>';
|
755 |
}
|
756 |
|
757 |
+
if (empty($this->docs)) {
|
758 |
return self::$no_docs;
|
759 |
}
|
760 |
+
|
761 |
+
$selector = "document-gallery-$instance";
|
762 |
+
$template =
|
763 |
+
"<div id='$selector' class='%class%'>". PHP_EOL .
|
764 |
+
'%icons%' . PHP_EOL .
|
765 |
+
'</div>' . PHP_EOL;
|
766 |
|
767 |
$icon_wrapper = apply_filters(
|
768 |
'dg_row_template',
|
769 |
+
$template,
|
770 |
$this->useDescriptions());
|
771 |
|
772 |
$core = '';
|
782 |
$core .= str_replace($find, $repl, $icon_wrapper);
|
783 |
}
|
784 |
} else {
|
785 |
+
global $dg_gallery_style;
|
786 |
+
|
787 |
+
$count = count($this->docs);
|
788 |
+
$cols = !is_null($this->atts['columns']) ? $this->atts['columns'] : $count;
|
789 |
+
|
790 |
+
if (apply_filters('dg_use_default_gallery_style', true )) {
|
791 |
+
$itemwidth = $cols > 0 ? (floor(100/$cols) - 1) : 100;
|
792 |
+
$core .= "<style type='text/css'>#$selector .document-icon{width:$itemwidth%}</style>";
|
793 |
+
}
|
794 |
+
|
795 |
+
for($i = 0; $i < $count; $i += $cols) {
|
796 |
$repl[1] = '';
|
797 |
|
798 |
+
$min = min($i + $cols, $count);
|
799 |
for($x = $i; $x < $min; $x++) {
|
800 |
$repl[1] .= $this->docs[$x];
|
801 |
}
|
inc/class-setup.php
CHANGED
@@ -16,9 +16,10 @@ class DG_Setup {
|
|
16 |
public static function getDefaultOptions($skeleton = false) {
|
17 |
include_once DG_PATH . 'inc/class-thumber.php';
|
18 |
|
19 |
-
$gs = null;
|
20 |
if (!$skeleton) {
|
21 |
$gs = DG_Thumber::getGhostscriptExecutable();
|
|
|
22 |
}
|
23 |
|
24 |
return array(
|
@@ -51,14 +52,8 @@ class DG_Setup {
|
|
51 |
// include thumbnail of actual document in gallery display
|
52 |
'fancy' => true,
|
53 |
|
54 |
-
// comma-
|
55 |
-
'
|
56 |
-
|
57 |
-
// if true, all images attached to current page will be included also
|
58 |
-
'images' => false,
|
59 |
-
|
60 |
-
// include just attached to the post using shortcode
|
61 |
-
'localpost' => true,
|
62 |
|
63 |
// ascending/descending order for included documents
|
64 |
'order' => 'ASC',
|
@@ -77,6 +72,9 @@ class DG_Setup {
|
|
77 |
|
78 |
// the max number of thumbnails to return
|
79 |
'limit' => -1,
|
|
|
|
|
|
|
80 |
),
|
81 |
'css' => array(
|
82 |
// plain text of CSS to be edited by user
|
@@ -85,9 +83,14 @@ class DG_Setup {
|
|
85 |
// "minified" text to be rendered on pages
|
86 |
'minified' => ''
|
87 |
),
|
88 |
-
|
89 |
-
|
90 |
-
|
|
|
|
|
|
|
|
|
|
|
91 |
|
92 |
// whether to validate DG option structure on save
|
93 |
'validation' => false,
|
@@ -97,6 +100,13 @@ class DG_Setup {
|
|
97 |
);
|
98 |
}
|
99 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
/**
|
101 |
* Runs every page load, updates as needed.
|
102 |
*/
|
@@ -104,7 +114,7 @@ class DG_Setup {
|
|
104 |
global $dg_options;
|
105 |
|
106 |
// do update
|
107 |
-
if (!is_null($dg_options) && DG_VERSION !== $dg_options['version']) {
|
108 |
$blogs = array(null);
|
109 |
|
110 |
if (is_multisite()) {
|
@@ -130,9 +140,11 @@ class DG_Setup {
|
|
130 |
// version-specific updates
|
131 |
self::twoPointTwo($options);
|
132 |
self::twoPointThree($options);
|
|
|
133 |
|
134 |
-
// update plugin
|
135 |
-
$options['version'] = DG_VERSION;
|
|
|
136 |
|
137 |
// remove previously-failed thumbs
|
138 |
$thumbs = $options['thumber']['thumbs'];
|
@@ -155,7 +167,7 @@ class DG_Setup {
|
|
155 |
* @param array $options The options to be modified.
|
156 |
*/
|
157 |
private static function twoPointTwo(&$options) {
|
158 |
-
if (version_compare($options['version'], '2.2', '<')) {
|
159 |
$thumbs = array();
|
160 |
|
161 |
// "created_timestamp" moving to just "timestamp"
|
@@ -192,7 +204,7 @@ class DG_Setup {
|
|
192 |
* @param array $options The options to be modified.
|
193 |
*/
|
194 |
private static function twoPointThree(&$options) {
|
195 |
-
if (version_compare($options['version'], '2.3', '<')) {
|
196 |
include_once DG_PATH . 'inc/class-thumber.php';
|
197 |
|
198 |
unset($options['css']['last-modified']);
|
@@ -214,6 +226,42 @@ class DG_Setup {
|
|
214 |
}
|
215 |
}
|
216 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
217 |
/**
|
218 |
* Sets up Document Gallery on all blog(s) activated.
|
219 |
* @param bool $networkwide Whether this is a network-wide update (multisite only).
|
@@ -292,6 +340,16 @@ class DG_Setup {
|
|
292 |
|
293 |
DocumentGallery::deleteOptions($blog);
|
294 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
295 |
|
296 |
/**
|
297 |
* Blocks instantiation. All functions are static.
|
16 |
public static function getDefaultOptions($skeleton = false) {
|
17 |
include_once DG_PATH . 'inc/class-thumber.php';
|
18 |
|
19 |
+
$gs = $donate_link = null;
|
20 |
if (!$skeleton) {
|
21 |
$gs = DG_Thumber::getGhostscriptExecutable();
|
22 |
+
$donate_link = self::getDonateLink();
|
23 |
}
|
24 |
|
25 |
return array(
|
52 |
// include thumbnail of actual document in gallery display
|
53 |
'fancy' => true,
|
54 |
|
55 |
+
// comma-delimited list of all mime types to be included
|
56 |
+
'mime_types' => implode(',', self::getDefaultMimeTypes()),
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
|
58 |
// ascending/descending order for included documents
|
59 |
'order' => 'ASC',
|
72 |
|
73 |
// the max number of thumbnails to return
|
74 |
'limit' => -1,
|
75 |
+
|
76 |
+
// # of columns to be used in gallery
|
77 |
+
'columns' => 4
|
78 |
),
|
79 |
'css' => array(
|
80 |
// plain text of CSS to be edited by user
|
83 |
// "minified" text to be rendered on pages
|
84 |
'minified' => ''
|
85 |
),
|
86 |
+
|
87 |
+
'meta' => array(
|
88 |
+
// current DG version
|
89 |
+
'version' => DG_VERSION,
|
90 |
+
|
91 |
+
// URL to donate to plugin development
|
92 |
+
'donate_link' => $donate_link
|
93 |
+
),
|
94 |
|
95 |
// whether to validate DG option structure on save
|
96 |
'validation' => false,
|
100 |
);
|
101 |
}
|
102 |
|
103 |
+
/**
|
104 |
+
* @return multitype:string The default MIME types to include in gallery.
|
105 |
+
*/
|
106 |
+
public static function getDefaultMimeTypes() {
|
107 |
+
return array('application', 'video', 'text', 'audio');
|
108 |
+
}
|
109 |
+
|
110 |
/**
|
111 |
* Runs every page load, updates as needed.
|
112 |
*/
|
114 |
global $dg_options;
|
115 |
|
116 |
// do update
|
117 |
+
if (!is_null($dg_options) && (isset($options['version']) || DG_VERSION !== $dg_options['meta']['version'])) {
|
118 |
$blogs = array(null);
|
119 |
|
120 |
if (is_multisite()) {
|
140 |
// version-specific updates
|
141 |
self::twoPointTwo($options);
|
142 |
self::twoPointThree($options);
|
143 |
+
self::threePointZeroBeta($options);
|
144 |
|
145 |
+
// update plugin meta data
|
146 |
+
$options['meta']['version'] = DG_VERSION;
|
147 |
+
$options['meta']['donate_link'] = self::getDonateLink();
|
148 |
|
149 |
// remove previously-failed thumbs
|
150 |
$thumbs = $options['thumber']['thumbs'];
|
167 |
* @param array $options The options to be modified.
|
168 |
*/
|
169 |
private static function twoPointTwo(&$options) {
|
170 |
+
if (isset($options['version']) && version_compare($options['version'], '2.2', '<')) {
|
171 |
$thumbs = array();
|
172 |
|
173 |
// "created_timestamp" moving to just "timestamp"
|
204 |
* @param array $options The options to be modified.
|
205 |
*/
|
206 |
private static function twoPointThree(&$options) {
|
207 |
+
if (isset($options['version']) && version_compare($options['version'], '2.3', '<')) {
|
208 |
include_once DG_PATH . 'inc/class-thumber.php';
|
209 |
|
210 |
unset($options['css']['last-modified']);
|
226 |
}
|
227 |
}
|
228 |
|
229 |
+
/**
|
230 |
+
* Creating new meta branch in options to store plugin meta information.
|
231 |
+
*
|
232 |
+
* "Localpost" no longer supported. Replaced by "id" attribute.
|
233 |
+
* "Images" no longer supported. Replaced by "mime_types" attribute.
|
234 |
+
* "Ids" still supported, but not stored in DB.
|
235 |
+
*
|
236 |
+
* Google thumber no longer supported.
|
237 |
+
*
|
238 |
+
* Added "columns" attribute.
|
239 |
+
* Added "mime_types" attribute.
|
240 |
+
*
|
241 |
+
* @param array $options The options to be modified.
|
242 |
+
*/
|
243 |
+
private static function threePointZeroBeta(&$options) {
|
244 |
+
if (isset($options['version']) /*&& version_compare($options['version'], '3.0.0-beta', '<')*/) {
|
245 |
+
$options['meta'] = array('version' => $options['version']);
|
246 |
+
unset($options['version']);
|
247 |
+
|
248 |
+
$images = $options['gallery']['images'];
|
249 |
+
|
250 |
+
unset($options['gallery']['localpost']);
|
251 |
+
unset($options['gallery']['ids']);
|
252 |
+
unset($options['gallery']['images']);
|
253 |
+
|
254 |
+
unset($options['thumber']['active']['google']);
|
255 |
+
|
256 |
+
$defaults = self::getDefaultOptions();
|
257 |
+
$options['gallery']['columns'] = $defaults['gallery']['columns'];
|
258 |
+
$options['gallery']['mime_types'] = $defaults['gallery']['mime_types'];
|
259 |
+
if ($images) {
|
260 |
+
$options['gallery']['mime_types'] .= ',image';
|
261 |
+
}
|
262 |
+
}
|
263 |
+
}
|
264 |
+
|
265 |
/**
|
266 |
* Sets up Document Gallery on all blog(s) activated.
|
267 |
* @param bool $networkwide Whether this is a network-wide update (multisite only).
|
340 |
|
341 |
DocumentGallery::deleteOptions($blog);
|
342 |
}
|
343 |
+
|
344 |
+
/**
|
345 |
+
* NOTE: This is expensive as is involves file I/O reading the README. Only use when
|
346 |
+
* the equivilent value in options array is not viable.
|
347 |
+
* @return string URL where users can donate to plugin.
|
348 |
+
*/
|
349 |
+
private static function getDonateLink() {
|
350 |
+
$data = get_file_data(DG_PATH . 'README.txt', array('donate' => 'Donate link'));
|
351 |
+
return $data['donate'];
|
352 |
+
}
|
353 |
|
354 |
/**
|
355 |
* Blocks instantiation. All functions are static.
|
inc/class-thumber.php
CHANGED
@@ -23,7 +23,29 @@ class DG_Thumber {
|
|
23 |
}
|
24 |
|
25 |
return array('av' => true, 'gs' => $gs_active,
|
26 |
-
'imagick' => $imagick_active
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
}
|
28 |
|
29 |
/**
|
@@ -38,7 +60,7 @@ class DG_Thumber {
|
|
38 |
if (is_null($start)) {
|
39 |
$start = time();
|
40 |
}
|
41 |
-
|
42 |
$options = self::getOptions();
|
43 |
|
44 |
// if we haven't saved a thumb, generate one
|
@@ -60,15 +82,10 @@ class DG_Thumber {
|
|
60 |
'document-gallery'), $ID, is_array($thumber) ? implode('::',$thumber) : print_r($thumber, true));
|
61 |
DG_Logger::writeLog(DG_LogLevel::Detail, $toLog);
|
62 |
}
|
63 |
-
|
64 |
-
if (
|
65 |
-
|
66 |
-
|
67 |
-
'thumb_url' => $thumb['url'],
|
68 |
-
'thumb_path' => $thumb['path'],
|
69 |
-
'thumber' => $thumber
|
70 |
-
);
|
71 |
-
self::setOptions($options);
|
72 |
break;
|
73 |
}
|
74 |
}
|
@@ -78,8 +95,7 @@ class DG_Thumber {
|
|
78 |
$new = empty($options['thumbs'][$ID]);
|
79 |
if ($new || empty($options['thumbs'][$ID]['thumber'])) {
|
80 |
if ($new) {
|
81 |
-
$
|
82 |
-
self::setOptions($options);
|
83 |
}
|
84 |
|
85 |
// fallback to default thumb for attachment type
|
@@ -229,10 +245,10 @@ class DG_Thumber {
|
|
229 |
if (is_null($gs)) {
|
230 |
$options = self::getOptions();
|
231 |
$gs = $options['gs'];
|
232 |
-
|
233 |
if (false !== $gs) {
|
234 |
-
$gs = escapeshellarg($gs) . ' -sDEVICE=png16m -dFirstPage=%d'
|
235 |
-
. ' -dLastPage=%d -dBATCH -dNOPAUSE -dPDFFitPage -sOutputFile=%s %s 2>&1';
|
236 |
}
|
237 |
}
|
238 |
|
@@ -243,7 +259,7 @@ class DG_Thumber {
|
|
243 |
$doc_path = get_attached_file($ID);
|
244 |
$temp_path = self::getTempFile();
|
245 |
|
246 |
-
exec(sprintf($gs, $pg, $
|
247 |
|
248 |
if ($ret != 0) {
|
249 |
DG_Logger::writeLog(DG_LogLevel::Error, __('Ghostscript failed: ', 'document-gallery') . print_r($out));
|
@@ -311,140 +327,31 @@ class DG_Thumber {
|
|
311 |
if (!empty($executable)) {
|
312 |
return $executable;
|
313 |
}
|
314 |
-
|
315 |
// GoDaddy and others aren't setup in such a way that
|
316 |
// the above works so we need to fallback to a direct
|
317 |
// filesystem check in most common location
|
318 |
exec('test -e /usr/bin/gs', $dummy, $ret);
|
319 |
$executable = ($ret === 0) ? '/usr/bin/gs' : false;
|
320 |
-
|
321 |
return $executable;
|
322 |
}
|
323 |
|
324 |
return $executable;
|
325 |
}
|
326 |
-
|
327 |
/**
|
328 |
* @return bool Whether we can use the GS executable.
|
329 |
*/
|
330 |
public static function isGhostscriptAvailable() {
|
331 |
static $ret = null;
|
332 |
-
|
333 |
if (is_null($ret)) {
|
334 |
$options = self::getOptions();
|
335 |
$ret = $options['gs'] && self::isExecAvailable();
|
336 |
}
|
337 |
-
|
338 |
-
return $ret;
|
339 |
-
}
|
340 |
-
|
341 |
-
/*==========================================================================
|
342 |
-
* GOOGLE DRIVE VIEWER THUMBNAILS
|
343 |
-
*=========================================================================*/
|
344 |
-
|
345 |
-
/**
|
346 |
-
* Get thumbnail for document with given ID from Google Drive Viewer.
|
347 |
-
*
|
348 |
-
* NOTE: Caller must verify that extension is supported.
|
349 |
-
*
|
350 |
-
* @param str $ID The attachment ID to retrieve thumbnail for.
|
351 |
-
* @param int $pg The page number to make thumbnail of -- index starts at 1.
|
352 |
-
* @return bool|str False on failure, URL to thumb on success.
|
353 |
-
*/
|
354 |
-
public static function getGoogleDriveThumbnail($ID, $pg = 1) {
|
355 |
-
// User agent for Lynx 2.8.7rel.2 -- Why? Because I can.
|
356 |
-
static $user_agent = 'Lynx/2.8.7rel.2 libwww-FM/2.14 SSL-MM/1.4.1 OpenSSL/1.0.0a';
|
357 |
-
static $timeout = 60;
|
358 |
-
|
359 |
-
$google_viewer = 'https://docs.google.com/viewer?url=%s&a=bi&pagenumber=%d&w=%d';
|
360 |
-
$doc_url = wp_get_attachment_url($ID);
|
361 |
-
if (!$doc_url) {
|
362 |
-
return false;
|
363 |
-
}
|
364 |
-
|
365 |
-
$temp_file = self::getTempFile();
|
366 |
-
|
367 |
-
// args for use in HTTP request
|
368 |
-
$args = array(
|
369 |
-
'timeout' => $timeout, // these requests can take a LONG time
|
370 |
-
'redirection' => 5,
|
371 |
-
'httpversion' => '1.0',
|
372 |
-
'user-agent' => $user_agent,
|
373 |
-
'blocking' => true,
|
374 |
-
'headers' => array(),
|
375 |
-
'cookies' => array(),
|
376 |
-
'body' => null,
|
377 |
-
'compress' => false,
|
378 |
-
'decompress' => true,
|
379 |
-
'sslverify' => true,
|
380 |
-
'stream' => true,
|
381 |
-
'filename' => $temp_file
|
382 |
-
);
|
383 |
-
|
384 |
-
// prevent PHP timeout before HTTP completes
|
385 |
-
@set_time_limit($timeout);
|
386 |
-
|
387 |
-
$options = self::getOptions();
|
388 |
-
$google_viewer = sprintf($google_viewer, urlencode($doc_url), (int)$pg, $options['width']);
|
389 |
-
|
390 |
-
// get thumbnail from Google Drive Viewer & check for error on return
|
391 |
-
$response = wp_remote_get($google_viewer, $args);
|
392 |
-
|
393 |
-
if (is_wp_error($response) || !preg_match('/[23][0-9]{2}/', $response['response']['code'])) {
|
394 |
-
DG_Logger::writeLog(DG_LogLevel::Warning, __('Failed to retrieve thumbnail from Google: ', 'document-gallery') .
|
395 |
-
(is_wp_error($response)
|
396 |
-
? $response->get_error_message()
|
397 |
-
: $response['response']['message']));
|
398 |
-
|
399 |
-
@unlink($temp_file);
|
400 |
-
return false;
|
401 |
-
}
|
402 |
-
|
403 |
-
return $temp_file;
|
404 |
-
}
|
405 |
-
|
406 |
-
/**
|
407 |
-
* @return array All extensions supported by Google Drive Viewer.
|
408 |
-
*/
|
409 |
-
private static function getGoogleDriveExts() {
|
410 |
-
return array(
|
411 |
-
'tiff', 'bmp', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx',
|
412 |
-
'pdf', 'pages', 'ai', 'psd', 'dxf', 'svg', 'eps', 'ps', 'ttf'
|
413 |
-
);
|
414 |
-
}
|
415 |
|
416 |
-
|
417 |
-
* @return bool Whether Google Drive can access files on this system.
|
418 |
-
*/
|
419 |
-
public static function isGoogleDriveAvailable() {
|
420 |
-
static $available = null;
|
421 |
-
|
422 |
-
if (is_null($available)) {
|
423 |
-
// to check if we're visible externally, retrieve image for file we know exists.
|
424 |
-
$user_agent = 'Lynx/2.8.7rel.2 libwww-FM/2.14 SSL-MM/1.4.1 OpenSSL/1.0.0a';
|
425 |
-
$google_viewer = 'https://docs.google.com/viewer?url=%s&a=bi&pagenumber=1&w=1';
|
426 |
-
$google_viewer = sprintf($google_viewer, urlencode(DG_URL . 'LICENSE.txt'));
|
427 |
-
|
428 |
-
// args for use in HTTP request
|
429 |
-
$args = array(
|
430 |
-
'redirection' => 5,
|
431 |
-
'httpversion' => '1.0',
|
432 |
-
'user-agent' => $user_agent,
|
433 |
-
'blocking' => true,
|
434 |
-
'headers' => array(),
|
435 |
-
'cookies' => array(),
|
436 |
-
'body' => null,
|
437 |
-
'compress' => false,
|
438 |
-
'decompress' => true,
|
439 |
-
'sslverify' => true
|
440 |
-
);
|
441 |
-
|
442 |
-
$response = wp_remote_get($google_viewer, $args);
|
443 |
-
|
444 |
-
$available = (!is_wp_error($response) && $response['response']['code'] != 404);
|
445 |
-
}
|
446 |
-
|
447 |
-
return $available;
|
448 |
}
|
449 |
|
450 |
/*==========================================================================
|
@@ -646,25 +553,19 @@ class DG_Thumber {
|
|
646 |
}
|
647 |
}
|
648 |
|
649 |
-
// Google Drive Viewer
|
650 |
-
if ($active['google']) {
|
651 |
-
$exts = implode('|', self::getGoogleDriveExts());
|
652 |
-
$thumbers[$exts] = array(__CLASS__, 'getGoogleDriveThumbnail');
|
653 |
-
}
|
654 |
-
|
655 |
// allow users to filter thumbers used
|
656 |
$thumbers = apply_filters('dg_thumbers', $thumbers);
|
657 |
-
|
658 |
// strip out anything that can't be called
|
659 |
$thumbers = array_filter($thumbers, 'is_callable');
|
660 |
-
|
661 |
// log which thumbers are being used
|
662 |
if (DG_Logger::logEnabled()) {
|
663 |
if (count($thumbers) > 0) {
|
664 |
$entry = __('Thumbnail Generators: ', 'document-gallery');
|
665 |
foreach ($thumbers as $k => $v) {
|
666 |
$thumber = is_array($v) ? implode('::', $v) : print_r($v, true);
|
667 |
-
|
668 |
// TODO: The following works for all internal regexes, but may have unpredictable
|
669 |
// results if developer adds additional thumbnail generators using different regexes
|
670 |
$filetypes = str_replace('|', ', ', $k);
|
@@ -683,15 +584,22 @@ class DG_Thumber {
|
|
683 |
|
684 |
/**
|
685 |
* Template that handles generating a thumbnail.
|
|
|
|
|
|
|
686 |
*
|
687 |
* @param callable $generator Takes ID and pg and returns path to temp file or false.
|
688 |
* @param int $ID ID for the attachment that we need a thumbnail for.
|
689 |
-
* @param int $pg
|
690 |
-
* @return bool
|
691 |
*/
|
692 |
-
|
|
|
|
|
|
|
|
|
693 |
// delegate thumbnail generation to $generator
|
694 |
-
|
695 |
return false;
|
696 |
}
|
697 |
|
@@ -736,9 +644,16 @@ class DG_Thumber {
|
|
736 |
@unlink($temp_path);
|
737 |
self::deleteThumbMeta($ID);
|
738 |
|
739 |
-
|
740 |
-
|
741 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
742 |
}
|
743 |
|
744 |
/**
|
@@ -755,7 +670,7 @@ class DG_Thumber {
|
|
755 |
$tmp = untrailingslashit(get_temp_dir());
|
756 |
}
|
757 |
|
758 |
-
return $tmp . DIRECTORY_SEPARATOR . wp_unique_filename($tmp,
|
759 |
}
|
760 |
|
761 |
/**
|
@@ -791,7 +706,7 @@ class DG_Thumber {
|
|
791 |
$modified = true;
|
792 |
}
|
793 |
}
|
794 |
-
|
795 |
if ($modified) { self::setOptions($options); }
|
796 |
}
|
797 |
|
@@ -829,13 +744,18 @@ class DG_Thumber {
|
|
829 |
* @param str $filename Name of the file to get extension from.
|
830 |
* @return str|bool Returns the file extension on success, false on failure.
|
831 |
*/
|
832 |
-
private static function getExt($filename) {
|
833 |
-
|
834 |
-
|
835 |
-
|
836 |
-
|
|
|
|
|
837 |
}
|
838 |
}
|
|
|
|
|
|
|
839 |
|
840 |
return false;
|
841 |
}
|
23 |
}
|
24 |
|
25 |
return array('av' => true, 'gs' => $gs_active,
|
26 |
+
'imagick' => $imagick_active);
|
27 |
+
}
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Sets the thumbnail for the given attachment ID.
|
31 |
+
*
|
32 |
+
* @param int $ID Document ID.
|
33 |
+
* @param string $path System path to thumbnail.
|
34 |
+
* @return bool Whether set was successful.
|
35 |
+
*/
|
36 |
+
public static function setThumbnail($ID, $path, $generator = 'unknown') {
|
37 |
+
return self::thumbnailGenerationHarness($generator, $ID, $path);
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Sets the thumbnail for the given attachment ID to a failed state.
|
42 |
+
*
|
43 |
+
* @param int $ID Document ID.
|
44 |
+
*/
|
45 |
+
public static function setThumbnailFailed($ID) {
|
46 |
+
$options = self::getOptions();
|
47 |
+
$options['thumbs'][$ID] = array('timestamp' => time());
|
48 |
+
self::setOptions($options);
|
49 |
}
|
50 |
|
51 |
/**
|
60 |
if (is_null($start)) {
|
61 |
$start = time();
|
62 |
}
|
63 |
+
|
64 |
$options = self::getOptions();
|
65 |
|
66 |
// if we haven't saved a thumb, generate one
|
82 |
'document-gallery'), $ID, is_array($thumber) ? implode('::',$thumber) : print_r($thumber, true));
|
83 |
DG_Logger::writeLog(DG_LogLevel::Detail, $toLog);
|
84 |
}
|
85 |
+
|
86 |
+
if (self::thumbnailGenerationHarness($thumber, $ID, $pg)) {
|
87 |
+
// harness updates options so we need a new copy
|
88 |
+
$options = self::getOptions();
|
|
|
|
|
|
|
|
|
|
|
89 |
break;
|
90 |
}
|
91 |
}
|
95 |
$new = empty($options['thumbs'][$ID]);
|
96 |
if ($new || empty($options['thumbs'][$ID]['thumber'])) {
|
97 |
if ($new) {
|
98 |
+
self::setThumbnailFailed($ID);
|
|
|
99 |
}
|
100 |
|
101 |
// fallback to default thumb for attachment type
|
245 |
if (is_null($gs)) {
|
246 |
$options = self::getOptions();
|
247 |
$gs = $options['gs'];
|
248 |
+
|
249 |
if (false !== $gs) {
|
250 |
+
$gs = escapeshellarg($gs) . ' -sDEVICE=png16m -dFirstPage=%1$d'
|
251 |
+
. ' -dLastPage=%1$d -dBATCH -dNOPAUSE -dPDFFitPage -sOutputFile=%2$s %3$s 2>&1';
|
252 |
}
|
253 |
}
|
254 |
|
259 |
$doc_path = get_attached_file($ID);
|
260 |
$temp_path = self::getTempFile();
|
261 |
|
262 |
+
exec(sprintf($gs, $pg, $temp_path, $doc_path), $out, $ret);
|
263 |
|
264 |
if ($ret != 0) {
|
265 |
DG_Logger::writeLog(DG_LogLevel::Error, __('Ghostscript failed: ', 'document-gallery') . print_r($out));
|
327 |
if (!empty($executable)) {
|
328 |
return $executable;
|
329 |
}
|
330 |
+
|
331 |
// GoDaddy and others aren't setup in such a way that
|
332 |
// the above works so we need to fallback to a direct
|
333 |
// filesystem check in most common location
|
334 |
exec('test -e /usr/bin/gs', $dummy, $ret);
|
335 |
$executable = ($ret === 0) ? '/usr/bin/gs' : false;
|
336 |
+
|
337 |
return $executable;
|
338 |
}
|
339 |
|
340 |
return $executable;
|
341 |
}
|
342 |
+
|
343 |
/**
|
344 |
* @return bool Whether we can use the GS executable.
|
345 |
*/
|
346 |
public static function isGhostscriptAvailable() {
|
347 |
static $ret = null;
|
348 |
+
|
349 |
if (is_null($ret)) {
|
350 |
$options = self::getOptions();
|
351 |
$ret = $options['gs'] && self::isExecAvailable();
|
352 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
353 |
|
354 |
+
return $ret;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
355 |
}
|
356 |
|
357 |
/*==========================================================================
|
553 |
}
|
554 |
}
|
555 |
|
|
|
|
|
|
|
|
|
|
|
|
|
556 |
// allow users to filter thumbers used
|
557 |
$thumbers = apply_filters('dg_thumbers', $thumbers);
|
558 |
+
|
559 |
// strip out anything that can't be called
|
560 |
$thumbers = array_filter($thumbers, 'is_callable');
|
561 |
+
|
562 |
// log which thumbers are being used
|
563 |
if (DG_Logger::logEnabled()) {
|
564 |
if (count($thumbers) > 0) {
|
565 |
$entry = __('Thumbnail Generators: ', 'document-gallery');
|
566 |
foreach ($thumbers as $k => $v) {
|
567 |
$thumber = is_array($v) ? implode('::', $v) : print_r($v, true);
|
568 |
+
|
569 |
// TODO: The following works for all internal regexes, but may have unpredictable
|
570 |
// results if developer adds additional thumbnail generators using different regexes
|
571 |
$filetypes = str_replace('|', ', ', $k);
|
584 |
|
585 |
/**
|
586 |
* Template that handles generating a thumbnail.
|
587 |
+
*
|
588 |
+
* If image has already been generated through other means, $pg may be set to the system path where the
|
589 |
+
* thumbnail is located. In this case, $generator will not be invoked, but *will* be kept for historical purposes.
|
590 |
*
|
591 |
* @param callable $generator Takes ID and pg and returns path to temp file or false.
|
592 |
* @param int $ID ID for the attachment that we need a thumbnail for.
|
593 |
+
* @param int|str $pg Page number of the attachment to get a thumbnail for or the system path to the image to be used.
|
594 |
+
* @return bool Whether generation was successful.
|
595 |
*/
|
596 |
+
private static function thumbnailGenerationHarness($generator, $ID, $pg = 1) {
|
597 |
+
// handle system page in $pg variable
|
598 |
+
if (is_string($pg) && !is_numeric($pg)) {
|
599 |
+
$temp_path = $pg;
|
600 |
+
}
|
601 |
// delegate thumbnail generation to $generator
|
602 |
+
elseif (false === ($temp_path = call_user_func($generator, $ID, $pg))) {
|
603 |
return false;
|
604 |
}
|
605 |
|
644 |
@unlink($temp_path);
|
645 |
self::deleteThumbMeta($ID);
|
646 |
|
647 |
+
// store new thumbnail in DG options
|
648 |
+
$options['thumbs'][$ID] = array(
|
649 |
+
'timestamp' => time(),
|
650 |
+
'thumb_url' => preg_replace('#'.preg_quote($basename).'$#', $thumb_name, $doc_url),
|
651 |
+
'thumb_path' => $thumb_path,
|
652 |
+
'thumber' => $generator
|
653 |
+
);
|
654 |
+
self::setOptions($options);
|
655 |
+
|
656 |
+
return true;
|
657 |
}
|
658 |
|
659 |
/**
|
670 |
$tmp = untrailingslashit(get_temp_dir());
|
671 |
}
|
672 |
|
673 |
+
return $tmp . DIRECTORY_SEPARATOR . wp_unique_filename($tmp, $base.'.'.$ext);
|
674 |
}
|
675 |
|
676 |
/**
|
706 |
$modified = true;
|
707 |
}
|
708 |
}
|
709 |
+
|
710 |
if ($modified) { self::setOptions($options); }
|
711 |
}
|
712 |
|
744 |
* @param str $filename Name of the file to get extension from.
|
745 |
* @return str|bool Returns the file extension on success, false on failure.
|
746 |
*/
|
747 |
+
private static function getExt($filename, $img = false) {
|
748 |
+
$options = $img ? array('jpg', 'jpeg', 'gif', 'png', 'bmp') : array_keys(wp_get_mime_types());
|
749 |
+
if ($ext = pathinfo($filename, PATHINFO_EXTENSION)) {
|
750 |
+
$res = preg_grep('/^(?:.*\|)?' . $ext . '(?:\|.*)?$/i', $options);
|
751 |
+
$res = reset($res);
|
752 |
+
if ($res!== false) {
|
753 |
+
return $ext;
|
754 |
}
|
755 |
}
|
756 |
+
elseif ( ($info = getimagesize($filename)) && ($ext = image_type_to_extension($info[2], false)) ) {
|
757 |
+
return $ext;
|
758 |
+
}
|
759 |
|
760 |
return false;
|
761 |
}
|
inc/class-util.php
ADDED
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
defined('WPINC') OR exit;
|
3 |
+
|
4 |
+
/**
|
5 |
+
* General utility function for Document Gallery.
|
6 |
+
*
|
7 |
+
* @author drossiter
|
8 |
+
*/
|
9 |
+
class DG_Util {
|
10 |
+
/**
|
11 |
+
* @var callable Either native JSON encode or custom JSON encode if needed.
|
12 |
+
*/
|
13 |
+
private static $nativeJsonEncode;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Wraps JSON encoding functionality, utilizing native functions if available.
|
17 |
+
*
|
18 |
+
* @param unknown $decoded Value to be encoded.
|
19 |
+
* @return string The JSON string.
|
20 |
+
*/
|
21 |
+
public static function jsonEncode($decoded) {
|
22 |
+
if (!isset(self::$nativeJsonEncode)) {
|
23 |
+
self::$nativeJsonEncode = function_exists('json_encode');
|
24 |
+
}
|
25 |
+
|
26 |
+
// do encoding
|
27 |
+
return self::$nativeJsonEncode ? json_encode($decoded) : self::_jsonEncode($decoded);
|
28 |
+
}
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Home-made JSON encode to replace mssing json_encode when needed.
|
32 |
+
*
|
33 |
+
* @param unknown $decoded Value to be encoded.
|
34 |
+
* @return string The JSON string.
|
35 |
+
*/
|
36 |
+
private static function _jsonEncode($decoded) {
|
37 |
+
if (self::isJsonObj($decoded)) {
|
38 |
+
$ret = '';
|
39 |
+
$first = true;
|
40 |
+
foreach ($decoded as $k => $v) {
|
41 |
+
if (!$first) $ret .= ',';
|
42 |
+
$ret .= "\"$k\":" . self::_jsonEncode($v);
|
43 |
+
$first = false;
|
44 |
+
}
|
45 |
+
|
46 |
+
return "\{$ret\}";
|
47 |
+
} elseif (is_array($decoded)) {
|
48 |
+
return '[' . implode(',', array_map(array(__CLASS__, __FUNCTION__), $decoded)) . ']';
|
49 |
+
} elseif (is_bool($decoded)) {
|
50 |
+
static $boolMap = array('false', 'true');
|
51 |
+
return $boolMap[(int)$decoded];
|
52 |
+
} elseif (is_string($decoded)) {
|
53 |
+
return '"' . str_replace(array('\\', '"'), array('\\\\', '\\"'), $decoded) . '"';
|
54 |
+
}
|
55 |
+
|
56 |
+
return (string)$decoded;
|
57 |
+
}
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Returns true for PHP objects and associative arrays.
|
61 |
+
*
|
62 |
+
* @param unknown $decoded Value to be checked.
|
63 |
+
* @return bool Whether passed value should be encoded as a JSON object.
|
64 |
+
*/
|
65 |
+
private static function isJsonObj($decoded) {
|
66 |
+
$ret = is_object($decoded);
|
67 |
+
|
68 |
+
if (!$ret && is_array($decoded)) {
|
69 |
+
$next = 0;
|
70 |
+
foreach (array_keys($decoded) as $k) {
|
71 |
+
if ($next++ !== $k) {
|
72 |
+
$ret = true;
|
73 |
+
break;
|
74 |
+
}
|
75 |
+
}
|
76 |
+
}
|
77 |
+
|
78 |
+
return $ret;
|
79 |
+
}
|
80 |
+
}
|
log/index.php
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
1 |
+
<?php // silence is golden
|
2 |
+
die();
|