PluginProbe
Document Gallery / 2.2
Document Gallery v2.2
trunk 0.8 0.8.5 1.0 1.0.1 1.0.2 1.0.3 1.0.4 1.1 1.2 1.2.1 1.3 1.3.1 1.4 1.4.1 1.4.2 1.4.3 2.0 2.0.1 2.0.10 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 All 94 releases
document-gallery / document-gallery.php

document-gallery.php in Document Gallery 2.2, at document-gallery.php

358 lines 11.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 defined('WPINC') OR exit;
3
4 /*
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: 2.2
9 Author: Dan Rossiter
10 Author URI: http://danrossiter.org/
11 License: GPLv2
12 Text Domain: document-gallery
13 */
14
15 define('DG_VERSION', '2.2');
16
17 // define helper paths & URLs
18 define('DG_BASENAME', plugin_basename(__FILE__));
19 define('DG_URL', plugin_dir_url(__FILE__));
20 define('DG_PATH', plugin_dir_path(__FILE__));
21 define('DG_WPINC_PATH', ABSPATH . WPINC . '/');
22 define('DG_WPADMIN_PATH', ABSPATH . 'wp-admin/');
23
24 // init DG options for use throughout plugin
25 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
32 // handle activation, updates, and uninstallation
33 include_once DG_PATH . 'inc/class-setup.php';
34 register_activation_hook(__FILE__, array('DG_Setup', 'activate'));
35 add_action('wpmu_new_blog', array('DG_Setup','activateNewBlog'));
36 register_uninstall_hook(__FILE__, array('DG_Setup', 'uninstall'));
37 DG_Setup::maybeUpdate();
38
39 // validate options if desired
40 if ($dg_options['validation']) {
41 add_action('init', function(){
42 add_filter('pre_update_option_' . DG_OPTION_NAME,
43 array('DocumentGallery', 'validateOptionsStructure'), 10, 2);
44 });
45 }
46
47 // I18n
48 add_action('plugins_loaded', array('DocumentGallery', 'loadTextDomain'));
49
50 // cleanup cached data when thumbed attachment deleted
51 include_once DG_PATH . 'inc/class-thumber.php';
52 add_action('delete_attachment', array('DG_Thumber', 'deleteThumbMeta'));
53
54 if (is_admin()) {
55 // admin house keeping
56 include_once DG_PATH . 'admin/class-admin.php';
57
58 // add settings link
59 add_filter('plugin_action_links_' . DG_BASENAME, array('DG_Admin', 'addSettingsLink'));
60
61 // build options page
62 add_action('admin_menu', array('DG_Admin', 'addAdminPage'));
63 if (DG_Admin::doRegisterSettings()) {
64 add_action('admin_init', array('DG_Admin', 'registerSettings'));
65 }
66 } else {
67 // styling for gallery
68 if (empty($dg_options['css']['text'])) {
69 add_action('wp_enqueue_scripts', array('DocumentGallery', 'enqueueGalleryStyle'));
70 } else {
71 add_action('template_redirect', array('DocumentGallery', 'buildCustomCss'));
72 add_action('wp_enqueue_scripts', array('DocumentGallery', 'enqueueCustomStyle'));
73 add_filter('query_vars', array('DocumentGallery', 'addCustomStyleQueryVar'));
74 }
75 }
76
77 // adds 'dg' shortcode
78 add_shortcode('dg', array('DocumentGallery', 'doShortcode'));
79
80 /**
81 * DocumentGallery wraps basic functionality to setup the plugin.
82 *
83 * @author drossiter
84 */
85 class DocumentGallery {
86
87 /**
88 * @var str Name of the query var used to check whether we should print custom CSS.
89 */
90 private static $query_var = 'document-gallery-css';
91
92 /*==========================================================================
93 * THE SHORTCODE
94 *=========================================================================*/
95
96 /**
97 * Takes values passed from attributes and returns sutable HTML to represent
98 * all valid attachments requested.
99 *
100 * @param multitype:string $atts Arguments from the user.
101 * @return string HTML for the Document Gallery.
102 */
103 public static function doShortcode($atts) {
104 include_once 'inc/class-gallery.php';
105
106 $start = microtime(true);
107 $gallery = (string)new DG_Gallery($atts);
108 DG_Logger::writeLog(DG_LogLevel::Detail, 'Generation Time: ' . sprintf('%.2f', (microtime(true) - $start)) . ' s');
109
110 return $gallery;
111 }
112
113 /**
114 * Enqueue standard DG CSS.
115 */
116 public static function enqueueGalleryStyle() {
117 wp_enqueue_style('document-gallery', DG_URL . 'assets/css/style.css', null, DG_VERSION);
118 }
119
120 /**
121 * Enqueue user's custom DG CSS.
122 */
123 public static function enqueueCustomStyle() {
124 global $dg_options;
125 wp_register_style('document-gallery', add_query_arg(self::$query_var, 1, home_url('/')),
126 null, DG_VERSION . ':' . $dg_options['css']['version']);
127 wp_enqueue_style('document-gallery');
128 }
129
130 /**
131 * Add query custom CSS query string.
132 * Taken from here: http://ottopress.com/2010/dont-include-wp-load-please/
133 * @param multitype:string $vars Variables to be added.
134 * @return multitype:string All variables to be included in query string.
135 */
136 public static function addCustomStyleQueryVar($vars) {
137 $vars[] = self::$query_var;
138 return $vars;
139 }
140
141 /**
142 * Constructs user's custom CSS dynamically, then instructs
143 * browser to cache for a year. Cache is busted by versioning
144 * CSS any time the user makes a change.
145 */
146 public static function buildCustomCss() {
147 if (1 == intval(get_query_var(self::$query_var))) {
148 global $dg_options;
149
150 header('Content-type: text/css');
151 header('Cache-Control: no-transform,public,maxage=' . 31536000);
152 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 31536000) . ' GMT');
153 header('Last-Modified: ' . $dg_options['css']['last-modified']);
154 header('ETag: ' . $dg_options['css']['etag']);
155
156 echo $dg_options['css']['minified'];
157 exit;
158 }
159 }
160
161 /*==========================================================================
162 * I18n
163 *=========================================================================*/
164
165 /**
166 * Loads language files into WP core.
167 */
168 public static function loadTextDomain() {
169 load_plugin_textdomain('document-gallery', false, dirname(DG_BASENAME) . '/languages/');
170 }
171
172 /*==========================================================================
173 * HELPER FUNCTIONS
174 *=========================================================================*/
175
176 /**
177 * @param int $blog ID of the blog to be retrieved in multisite env.
178 * @return multitype:unknown Options for the blog.
179 */
180 public static function getOptions($blog = null) {
181 global $dg_options;
182 return is_null($blog)
183 ? $dg_options
184 : get_blog_option($blog, DG_OPTION_NAME, null);
185 }
186
187 /**
188 * @param multitype:unknown $options
189 * @param int $blog ID of the blog to be set in multisite env.
190 */
191 public static function setOptions($options, $blog = null) {
192 if (is_null($blog)) {
193 global $dg_options;
194 update_option(DG_OPTION_NAME, $options);
195 $dg_options = $options;
196 } else {
197 update_blog_option($blog, DG_OPTION_NAME, $options);
198 }
199 }
200
201 /**
202 * @param int $blog ID of the blog to be deleted in multisite env.
203 */
204 public static function deleteOptions($blog = null) {
205 if (is_null($blog)) {
206 delete_option(DG_OPTION_NAME);
207 } else {
208 delete_blog_option($blog, DG_OPTION_NAME);
209 }
210 }
211
212 /**
213 * Checks whether the given options match the option schema.
214 * @param multivar $new The new options to be validated.
215 * @param multivar $old The old options.
216 * @return array The options to be saved.
217 */
218 public static function validateOptionsStructure($new, $old) {
219 if (self::isValidOptionsStructure($new)) {
220 $ret = $new;
221 } else {
222 $ret = $old;
223 DG_Logger::writeLog(DG_LogLevel::Error, 'Attempted to save invalid options.' . PHP_EOL . print_r($new, true), true, true);
224 }
225
226 return $ret;
227 }
228
229 /**
230 * @param multivar|unknown $o The options structure to validate.
231 * @param multivar $schema The schema to validate against (note that only keys matter -- non-array values are ignored).
232 * @return bool Whether the given options structure matches the schema.
233 */
234 private static function isValidOptionsStructure($o, $schema = null) {
235 if (is_null($schema)) {
236 include_once DG_PATH . 'inc/class-setup.php';
237 $schema = DG_Setup::getDefaultOptions(true);
238 }
239
240 // simple checks first
241 $valid = is_array($o) && (count($schema) === count($o));
242
243 if ($valid) {
244 foreach ($schema as $sk => $sv) {
245 $valid = array_key_exists($sk, $o);
246 if (is_array($sv) && !empty($sv)) {
247 $valid = $valid && self::isValidOptionsStructure($o[$sk], $sv);
248 }
249
250 if (!$valid) {
251 break;
252 }
253 }
254 }
255
256 return $valid;
257 }
258
259 /**
260 * Function takes a GMT timestamp and returns a date/time string in the
261 * current timezone and WP format.
262 * @param int $timestamp The GMT timestamp to translate.
263 * @return string The local time in the WP date/time format.
264 */
265 public static function localDateTimeFromTimestamp($timestamp) {
266 static $gmt_offet = null;
267 static $wp_format = null;
268 if (is_null($gmt_offet)) {
269 $gmt_offet = get_option('gmt_offset');
270 $wp_format = get_option('date_format').' '.get_option('time_format');
271 }
272
273 return date($wp_format, $timestamp + $gmt_offet * 3600);
274 }
275
276 /**
277 * Compiles any custom CSS plus the default CSS together,
278 * minifying in the process.
279 * @param string $custom The custom CSS to compile.
280 * @return string Compiled CSS, including both standard and any custom.
281 */
282 public static function compileCustomCss($custom) {
283 $css = file_get_contents(DG_PATH . 'assets/css/style.css');
284 $css .= str_replace('&gt;', '>', esc_html($custom));
285
286 return $css;
287 }
288
289 /**
290 * Removes all comments & space from CSS string.
291 * Source: http://stackoverflow.com/a/15195752/866618
292 */
293 private static function minifyCss($css) {
294 # remove comments first (simplifies the other regex)
295 $re1 = <<<EOS
296 (?sx)
297 # quotes
298 (
299 "(?:[^"\\]++|\\.)*+"
300 | '(?:[^'\\]++|\\.)*+'
301 )
302 |
303 # comments
304 /\* (?> .*? \*/ )
305 EOS;
306
307 $re2 = <<<EOS
308 (?six)
309 # quotes
310 (
311 "(?:[^"\\]++|\\.)*+"
312 | '(?:[^'\\]++|\\.)*+'
313 )
314 |
315 # ; before } (and the spaces after it while we're here)
316 \s*+ ; \s*+ ( } ) \s*+
317 |
318 # all spaces around meta chars/operators
319 \s*+ ( [*$~^|]?+= | [{};,>~+-] | !important\b ) \s*+
320 |
321 # spaces right of ( [ :
322 ( [[(:] ) \s++
323 |
324 # spaces left of ) ]
325 \s++ ( [])] )
326 |
327 # spaces left (and right) of :
328 \s++ ( : ) \s*+
329 # but not in selectors: not followed by a {
330 (?!
331 (?>
332 [^{}"']++
333 | "(?:[^"\\]++|\\.)*+"
334 | '(?:[^'\\]++|\\.)*+'
335 )*+
336 {
337 )
338 |
339 # spaces at beginning/end of string
340 ^ \s++ | \s++ \z
341 |
342 # double spaces to single
343 (\s)\s+
344 EOS;
345
346 $css = preg_replace("%$re1%", '$1', $css);
347 return preg_replace("%$re2%", '$1$2$3$4$5$6$7', $css);
348 }
349
350 /**
351 * Blocks instantiation. All functions are static.
352 */
353 private function __construct() {
354
355 }
356 }
357
358 ?>