PluginProbe
Document Gallery / 4.2
Document Gallery v4.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 / inc / class-setup.php

class-setup.php in Document Gallery 4.2, at inc/class-setup.php

547 lines 16.9 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 * Holds functions that handle DG setup / uninstallation.
6 *
7 * @author drossiter
8 */
9 class DG_Setup {
10
11 /**
12 * The default DG options to be used on install and when validating structure of options.
13 *
14 * @param $skeleton bool When true, expensive values are not calculated. Only keys may be trusted when returning skeleton.
15 *
16 * @return mixed[][] Contains default options for DG.
17 */
18 public static function getDefaultOptions( $skeleton = false ) {
19 include_once DG_PATH . 'inc/class-thumber.php';
20
21 $gs = $donate_link = null;
22 if ( ! $skeleton ) {
23 $gs = DG_GhostscriptThumber::getGhostscriptExecutable();
24 $donate_link = self::getDonateLink();
25 }
26
27 return array(
28 'thumber' => array(
29 // Ghostscript path
30 'gs' => $gs,
31 // which thumbnail generation methods are available
32 'active' => DG_Thumber::getDefaultThumbers( $skeleton ),
33 // max width to generate thumbnails
34 'width' => 200,
35 // max height to generate thumbnails
36 'height' => 200
37 ),
38 'thumber-co' => array(
39 'uid' => null,
40 'secret' => null,
41 'subscription' => array(),
42 'direct_upload' => false,
43 'mime_types' => array()
44 ),
45 'gallery' => array(
46 // default: link directly to file (true to link to attachment pg)
47 'attachment_pg' => false,
48 // # of columns to be used in gallery
49 'columns' => 4,
50 // include the attachment description in output
51 'descriptions' => false,
52 // include thumbnail of actual document in gallery display
53 'fancy' => true,
54 // the max number of thumbnails to return
55 'limit' => -1,
56 // comma-delimited list of all mime types to be included
57 'mime_types' => implode( ',', self::getDefaultMimeTypes() ),
58 // whether to open documents in new window
59 'new_window' => false,
60 // ascending/descending order for included documents
61 'order' => 'ASC',
62 // which property to order by
63 'orderby' => 'menu_order',
64 // whether to paginate galleries with a "limit"
65 'paginate' => true,
66 // the status the post must be in when returned by DG
67 'post_status' => 'any',
68 // the type of post to be returned
69 'post_type' => 'attachment',
70 // AND or OR
71 'relation' => 'AND',
72 // how many documents to skip
73 'skip' => 0
74 ),
75 'css' => array(
76 // plain text of CSS to be edited by user
77 'text' => ''
78 ),
79 'meta' => array(
80 // current DG version
81 'version' => DG_VERSION,
82 // items per page at Thumbnail Management tab
83 'items_per_page' => 10,
84 // URL to donate to plugin development
85 'donate_link' => $donate_link
86 ),
87 // logging options
88 'logging' => array(
89 // TODO: more granular -- log_level instead of blanket enable/disable
90 'enabled' => defined( 'WP_DEBUG' ) && WP_DEBUG,
91 // max age of log entry (days)
92 'purge_interval' => 7
93 )
94 );
95 }
96
97 /**
98 * @return string[] The default MIME types to include in gallery.
99 */
100 public static function getDefaultMimeTypes() {
101 return array( 'application', 'video', 'text', 'audio', 'image' );
102 }
103
104 /**
105 * Runs every page load, updates as needed.
106 */
107 public static function maybeUpdate() {
108 global $dg_options;
109 if ( is_null( $dg_options ) ) {
110 return;
111 }
112
113 // version has historically been in two locations -- must check both to continue supporting upgrading from those old versions
114 $old_version = isset( $dg_options['version'] ) ? $dg_options['version'] : $dg_options['meta']['version'];
115 if ( ! is_null( $dg_options ) && DG_VERSION !== $old_version ) {
116 DG_Logger::writeLog( DG_LogLevel::Detail, "Upgrading Document Gallery from version $old_version to " . DG_VERSION );
117
118 $blogs = array( null );
119
120 if ( is_multisite() ) {
121 $blogs = DG_Util::getBlogIds();
122 }
123
124 foreach ( $blogs as $blog ) {
125 self::_update( $blog );
126 }
127 }
128 }
129
130 /**
131 * Runs when update is needed, updating the given blog. If $blog is null,
132 * active blog is updated.
133 *
134 * @param int $blog Blog to update or null if updating current blog.
135 */
136 private static function _update( $blog ) {
137 $options = DocumentGallery::getOptions( $blog );
138 if ( is_null( $options ) ) {
139 return;
140 }
141
142 // version-specific updates
143 self::twoPointTwo( $options );
144 self::twoPointThree( $options );
145 self::threePointZeroBeta( $options );
146 self::threePointOne( $options );
147 self::threePointTwo( $options );
148 self::threePointThree( $options );
149 self::threePointFour( $options );
150 self::threePointFive( $options );
151 self::fourPointZero( $options );
152 self::fourPointOne( $options );
153 self::fourPointOnePointFive( $options );
154
155 // update plugin meta data
156 $options['meta']['version'] = DG_VERSION;
157 $options['meta']['donate_link'] = self::getDonateLink();
158
159 // remove previously-failed thumbs
160 DG_Thumb::purgeFailedThumbs();
161
162 DocumentGallery::setOptions( $options, $blog );
163 }
164
165 /**
166 * The 'created_timestamp' key in each thumb record is being moved
167 * to 'timestamp' as part of a move to store timestamp for failed
168 * thumbnails in addition to successful ones.
169 *
170 * The defaults sub-branch in the gallery branch is being flattened into its parent.
171 *
172 * @param mixed[][] $options The options to be modified.
173 */
174 private static function twoPointTwo( &$options ) {
175 if ( isset( $options['version'] ) && version_compare( $options['version'], '2.2', '<' ) ) {
176 $thumbs = array();
177
178 // "created_timestamp" moving to just "timestamp"
179 foreach ( $options['thumber']['thumbs'] as $id => $thumb ) {
180 if ( false === $thumb ) {
181 continue;
182 }
183
184 $thumbs[ $id ] = array(
185 'timestamp' => $thumb['created_timestamp'],
186 'thumb_url' => $thumb['thumb_url'],
187 'thumb_path' => $thumb['thumb_path'],
188 'thumber' => $thumb['thumber']
189 );
190 }
191
192 $options['thumber']['thumbs'] = $thumbs;
193
194 // adding default thumbnail generation timeout
195 $options['thumber']['timeout'] = 30;
196
197 // flatten out "defaults" level
198 $options['gallery'] = $options['gallery']['defaults'];
199
200 // adding "validation" branch
201 $options['validation'] = false;
202
203 // adding "logging" branch
204 $options['logging'] = false;
205 }
206 }
207
208 /**
209 * Some of the data previously stored along with custom CSS is no longer needed.
210 *
211 * @param mixed[][] $options The options to be modified.
212 */
213 private static function twoPointThree( &$options ) {
214 if ( isset( $options['version'] ) && version_compare( $options['version'], '2.3', '<' ) ) {
215 include_once DG_PATH . 'inc/class-thumber.php';
216
217 unset( $options['css']['last-modified'] );
218 unset( $options['css']['etag'] );
219 unset( $options['css']['version'] );
220
221 // need to recalculate minified, excluding static CSS which was previously included
222 //$options['css']['minified'] = DocumentGallery::compileCustomCss($options['css']['text']);
223
224 // if user inadvertantly enabled google drive viewer on system where it's not supported
225 // then avoid locking it in the on state
226 if ( $options['thumber']['active']['google'] ) {
227 $options['thumber']['active']['google'] = false /* DG_Thumber::isGoogleDriveAvailable() */
228 ;
229 }
230
231 $options['gallery']['post_status'] = 'any';
232 $options['gallery']['post_type'] = 'attachment';
233 $options['gallery']['limit'] = - 1;
234 }
235 }
236
237 /**
238 * Creating new meta branch in options to store plugin meta information.
239 *
240 * "Localpost" no longer supported. Replaced by "id" attribute.
241 * "Images" no longer supported. Replaced by "mime_types" attribute.
242 * "Ids" still supported, but not stored in DB.
243 *
244 * Google thumber no longer supported.
245 *
246 * Added "columns" attribute.
247 * Added "mime_types" attribute.
248 *
249 * @param mixed[][] $options The options to be modified.
250 */
251 private static function threePointZeroBeta( &$options ) {
252 if ( isset( $options['version'] ) /*&& version_compare($options['version'], '3.0.0-beta', '<')*/ ) {
253 $options['meta'] = array( 'version' => $options['version'] );
254 unset( $options['version'] );
255
256 $images = $options['gallery']['images'];
257
258 unset( $options['gallery']['localpost'] );
259 unset( $options['gallery']['ids'] );
260 unset( $options['gallery']['images'] );
261
262 unset( $options['thumber']['active']['google'] );
263
264 $defaults = self::getDefaultOptions();
265 $options['gallery']['columns'] = $defaults['gallery']['columns'];
266 $options['gallery']['mime_types'] = $defaults['gallery']['mime_types'];
267 if ( $images ) {
268 $options['gallery']['mime_types'] .= ',image';
269 }
270 }
271 }
272
273 /**
274 * Flat logging option split out into multiple options in a nested array.
275 *
276 * Added scheduled log purge event to handle rollovers.
277 *
278 * @param mixed[][] $options The options to be modified.
279 */
280 private static function threePointOne( &$options ) {
281 if ( version_compare( $options['meta']['version'], '3.1', '<' ) ) {
282 $logging_enabled = $options['logging'];
283 $options['logging'] = array(
284 'enabled' => $logging_enabled,
285 'purge_interval' => 7
286 );
287
288 // purge log entries regularly
289 wp_schedule_event( time(), 'daily', DG_Logger::PurgeLogsAction );
290 }
291 }
292
293 /**
294 * Adds 'new_window' under gallery options.
295 *
296 * @param mixed[][] $options The options to be modified.
297 */
298 private static function threePointTwo( &$options ) {
299 if ( version_compare( $options['meta']['version'], '3.2', '<' ) ) {
300 $options['gallery']['new_window'] = false;
301 }
302 }
303
304 /**
305 * Removes minified CSS. Fixing corrupt data for boolean fields that may have gotten strings.
306 *
307 * @param mixed[][] $options The options to be modified.
308 */
309 private static function threePointThree( &$options ) {
310 if ( version_compare( $options['meta']['version'], '3.3', '<' ) ) {
311 unset( $options['css']['minified'] );
312
313 $defaults = self::getDefaultOptions();
314 foreach ( $defaults as $class => $block ) {
315 if ( is_array($block) ) {
316 foreach ( $block as $prop => $value ) {
317 if ( is_bool( $value ) && isset( $options[$class][$prop] ) && ! is_bool( $options[$class][$prop] ) ) {
318 $options[$class][$prop] = DG_Util::toBool( $options[$class][$prop], $value );
319 }
320 }
321 } elseif ( is_bool( $block ) && isset( $options[$class] ) && ! is_bool( $options[$class] ) ) {
322 $options[$class] = DG_Util::toBool( $options[$class], $block );
323 }
324 }
325 }
326 }
327
328 /**
329 * Removes the validation option. Validation is now non-optional.
330 *
331 * @param mixed[][] $options The options to be modified.
332 */
333 private static function threePointFour( &$options ) {
334 if ( version_compare( $options['meta']['version'], '3.4', '<' ) ) {
335 unset( $options['validation'] );
336
337 if ( ! DocumentGallery::isValidOptionsStructure( $options ) ) {
338 DG_Logger::writeLog(
339 DG_LogLevel::Error,
340 'Found invalid options structure. Reverting to default options.',
341 false,
342 true );
343 $options = self::getDefaultOptions();
344 }
345 }
346 }
347
348 /**
349 * There is no longer a concept of gallery load timeout. Missing thumbnails are asynchronously generated after
350 * a gallery is first rendered via AJAX requests.
351 *
352 * @param mixed[][] $options The options to be modified.
353 */
354 private static function threePointFive( &$options ) {
355 if ( version_compare( $options['meta']['version'], '3.5', '<' ) ) {
356 unset( $options['thumber']['timeout'] );
357 }
358 }
359
360 /**
361 * Adds the meta items_per_page default value.
362 * Paginate & skip options were added.
363 * Moving cached thumbs into postmeta table.
364 *
365 * @param mixed[][] $options The options to be modified.
366 */
367 private static function fourPointZero( &$options ) {
368 if ( version_compare( $options['meta']['version'], '4.0', '<' ) ) {
369 $options['gallery']['paginate'] = true;
370 $options['gallery']['skip'] = 0;
371 $options['meta']['items_per_page'] = 10;
372
373 $upload_dir = wp_upload_dir();
374 $upload_len = strlen( $upload_dir['basedir'] );
375 $dimensions = $options['thumber']['width'] . 'x' . $options['thumber']['height'];
376 foreach ( $options['thumber']['thumbs'] as $id => $thumb ) {
377 $thumb_obj = new DG_Thumb();
378 $thumb_obj->setPostId( $id );
379 $thumb_obj->setTimestamp( $thumb['timestamp'] );
380 $thumb_obj->setDimensions( $dimensions );
381 if ( isset( $thumb['thumb_path'] ) ) {
382 $thumb_obj->setRelativePath( substr( $thumb['thumb_path'], $upload_len + 1 ) );
383 $thumb_obj->setGenerator( DG_Util::callableToString( $thumb['thumber'] ) );
384 }
385
386 $thumb_obj->save();
387 }
388
389 unset( $options['thumber']['thumbs'] );
390 }
391 }
392
393 /**
394 * Adds integration w/ Thumber.co service.
395 * Update existing thumbs to match new thumbnail generation architecture.
396 *
397 * @param mixed[][] $options The options to be modified.
398 */
399 private static function fourPointOne( &$options ) {
400 if ( version_compare( $options['meta']['version'], '4.1', '<' ) ) {
401 $options['thumber']['active']['thumber-co'] = false;
402 $options['thumber-co'] = array(
403 'uid' => null,
404 'secret' => null,
405 'subscription' => array(),
406 'direct_upload' => false,
407 'mime_types' => array()
408 );
409
410 $old_thumbs = DG_Thumb::getThumbs( $options['thumber']['width'] . 'x' . $options['thumber']['height'] );
411 DG_Thumb::purgeThumbs( null, null, false );
412 foreach ( $old_thumbs as $thumb ) {
413 if ( $thumb->isSuccess() ) {
414 $generator = $thumb->getGenerator();
415 if ( $generator == 'DG_Thumber::getGhostscriptThumbnail' ) {
416 $thumb->setGenerator( 'DG_GhostscriptThumber' );
417 } elseif ( $generator == 'DG_Thumber::getImagickThumbnail' ) {
418 $thumb->setGenerator( 'DG_ImagickThumber' );
419 } elseif ( $generator == 'DG_Thumber::getAudioVideoThumbnail' ) {
420 $thumb->setGenerator( 'DG_AudioVideoThumber' );
421 }
422
423 $thumb->save();
424 }
425 }
426 }
427 }
428
429 /**
430 * Cleans up the mess created in the fourPointOne upgrade script. The
431 * thumbnail files were removed, while the thumbnail DB entries were left.
432 *
433 * @param mixed[][] $options The options to be modified.
434 */
435 private static function fourPointOnePointFive( &$options ) {
436 if ( version_compare( $options['meta']['version'], '4.1.5', '<' ) ) {
437 $thumbs = DG_Thumb::getThumbs( $options['thumber']['width'] . 'x' . $options['thumber']['height'] );
438 $ids = array();
439 foreach ( $thumbs as $thumb ) {
440 if ( $thumb->isSuccess() && !@file_exists( $thumb->getPath() ) ) {
441 $ids[] = $thumb->getPostId();
442 }
443 }
444
445 DG_Thumb::purgeThumbs( $ids );
446 }
447 }
448
449 /**
450 * Sets up Document Gallery on all blog(s) activated.
451 *
452 * @param bool $networkwide Whether this is a network-wide update (multisite only).
453 */
454 public static function activate( $networkwide ) {
455 $blogs = array( null );
456
457 if ( is_multisite() ) {
458 // check if it is a network activation
459 if ( $networkwide ) {
460 $blogs = DG_Util::getBlogIds();
461 }
462 }
463
464 foreach ( $blogs as $blog ) {
465 self::_activate( $blog );
466 }
467
468 // handle purging log entries regularly
469 wp_schedule_event( time(), 'daily', DG_Logger::PurgeLogsAction );
470 }
471
472 /**
473 * Hooked into wpmu_new_blog to handle activating a new blog when plugin
474 * is already network activated.
475 * See discussion: https://core.trac.wordpress.org/ticket/14170
476 *
477 * @param int $blog Blog ID.
478 */
479 public static function activateNewBlog( $blog ) {
480 if ( is_plugin_active_for_network( DG_BASENAME ) ) {
481 self::_activate( $blog );
482 }
483 }
484
485 /**
486 * Runs activation setup for Document Gallery on all blog(s) it is activated on.
487 *
488 * @param int $blog Blog to update or null if updating current blog.
489 */
490 private static function _activate( $blog ) {
491 $options = DocumentGallery::getOptions( $blog );
492
493 // first activation
494 if ( is_null( $options ) ) {
495 DocumentGallery::setOptions( self::getDefaultOptions(), $blog );
496 }
497 }
498
499 /**
500 * Runs when DG is uninstalled.
501 */
502 public static function uninstall() {
503 if ( ! current_user_can( 'activate_plugins' ) ) {
504 return;
505 }
506 check_admin_referer( 'bulk-plugins' );
507
508 $blogs = array( null );
509
510 if ( is_multisite() ) {
511 $blogs = DG_Util::getBlogIds();
512 }
513
514 foreach ( $blogs as $blog ) {
515 self::_uninstall( $blog );
516 }
517
518 wp_clear_scheduled_hook( DG_Logger::PurgeLogsAction );
519 }
520
521 /**
522 * Runs when DG is uninstalled for an individual blog.
523 */
524 private static function _uninstall( $blog ) {
525 DG_Thumb::purgeThumbs( null, $blog );
526 DocumentGallery::deleteOptions( $blog );
527 }
528
529 /**
530 * NOTE: This is expensive as is involves file I/O reading the README. Only use when
531 * the equivalent value in options array is not viable.
532 * @return string URL where users can donate to plugin.
533 */
534 private static function getDonateLink() {
535 $data = get_file_data( DG_PATH . 'README.txt', array( 'donate' => 'Donate link' ) );
536
537 return $data['donate'];
538 }
539
540 /**
541 * Blocks instantiation. All functions are static.
542 */
543 private function __construct() {
544
545 }
546 }
547