| @@ -8,65 +8,237 @@ | ||
| 8 | 8 | */ |
| 9 | 9 | class DG_Setup { |
| 10 | 10 | |
| 11 | 11 | /** |
| 12 | + * The default DG options to be used on install and when validating structure of options. | |
| 13 | + * @param $skeleton bool When true, expensive values are not calculated. Only keys may be trusted when returning skeleton. | |
| 12 | 14 | * @return array Contains default options for DG. |
| 13 | 15 | */ |
| 14 | - public static function getDefaultOptions() { | |
| 16 | + public static function getDefaultOptions($skeleton = false) { | |
| 15 | 17 | include_once DG_PATH . 'inc/class-thumber.php'; |
| 18 | + | |
| 19 | + $date = $etag = $gs = null; | |
| 20 | + if (!$skeleton) { | |
| 21 | + $date = gmdate('D, d M Y H:i:s'); | |
| 22 | + $etag = md5($date); | |
| 23 | + $gs = DG_Thumber::getGhostscriptExecutable(); | |
| 24 | + } | |
| 25 | + | |
| 16 | 26 | return array( |
| 17 | 27 | 'thumber' => array( |
| 18 | - 'thumbs' => array(), | |
| 19 | - 'gs' => DG_Thumber::getGhostscriptExecutable(), | |
| 20 | - 'active' => DG_Thumber::getDefaultThumbers(), | |
| 21 | - 'width' => 200, | |
| 22 | - 'height' => 200 | |
| 28 | + // cached thumbnails, keyed by post ID | |
| 29 | + 'thumbs' => array(), | |
| 30 | + | |
| 31 | + // Ghostscript path | |
| 32 | + 'gs' => $gs, | |
| 33 | + | |
| 34 | + // which thumbnail generation methods are available | |
| 35 | + 'active' => DG_Thumber::getDefaultThumbers($skeleton), | |
| 36 | + | |
| 37 | + // max width to generate thumbnails | |
| 38 | + 'width' => 200, | |
| 39 | + | |
| 40 | + // max height to generate thumbnails | |
| 41 | + 'height' => 200, | |
| 42 | + | |
| 43 | + // time after which to quite trying to generate new thumbanils for gallery | |
| 44 | + 'timeout' => 30 | |
| 23 | 45 | ), |
| 24 | 46 | 'gallery' => array( |
| 25 | - 'defaults' => array( | |
| 26 | - // default: link directly to file (true to link to attachment pg) | |
| 27 | - 'attachment_pg' => false, | |
| 28 | - 'descriptions' => false, | |
| 29 | - // include thumbnail of actual document in gallery display | |
| 30 | - 'fancy' => true, | |
| 31 | - // comma-separated list of attachment ids | |
| 32 | - 'ids' => false, | |
| 33 | - // if true, all images attached to current page will be included also | |
| 34 | - 'images' => false, | |
| 35 | - 'localpost' => true, | |
| 36 | - 'order' => 'ASC', | |
| 37 | - 'orderby' => 'menu_order', | |
| 38 | - // only relevant if tax_query used (WP >= 3.1) | |
| 39 | - 'relation' => 'AND' | |
| 40 | - ) | |
| 47 | + // default: link directly to file (true to link to attachment pg) | |
| 48 | + 'attachment_pg' => false, | |
| 49 | + | |
| 50 | + // include the attachment description in output | |
| 51 | + 'descriptions' => false, | |
| 52 | + | |
| 53 | + // include thumbnail of actual document in gallery display | |
| 54 | + 'fancy' => true, | |
| 55 | + | |
| 56 | + // comma-separated list of attachment ids | |
| 57 | + 'ids' => false, | |
| 58 | + | |
| 59 | + // if true, all images attached to current page will be included also | |
| 60 | + 'images' => false, | |
| 61 | + | |
| 62 | + // include just attached to the post using shortcode | |
| 63 | + 'localpost' => true, | |
| 64 | + | |
| 65 | + // ascending/descending order for included documents | |
| 66 | + 'order' => 'ASC', | |
| 67 | + | |
| 68 | + // which property to order by | |
| 69 | + 'orderby' => 'menu_order', | |
| 70 | + | |
| 71 | + // AND or OR | |
| 72 | + 'relation' => 'AND' | |
| 41 | 73 | ), |
| 42 | - 'css' => array('version' => 0, 'text' => ''), | |
| 43 | - 'version' => DG_VERSION | |
| 74 | + 'css' => array( | |
| 75 | + // plain text of CSS to be edited by user | |
| 76 | + 'text' => '', | |
| 77 | + | |
| 78 | + // "minified" text to be rendered on pages | |
| 79 | + 'minified' => '', | |
| 80 | + | |
| 81 | + // date/time last modified | |
| 82 | + 'last-modified' => $date, | |
| 83 | + | |
| 84 | + // used when telling browser whether to load from cache | |
| 85 | + 'etag' => $etag, | |
| 86 | + | |
| 87 | + // used in cache busting after user modifies CSS | |
| 88 | + 'version' => 0 | |
| 89 | + ), | |
| 90 | + | |
| 91 | + // current DG version | |
| 92 | + 'version' => DG_VERSION, | |
| 93 | + | |
| 94 | + // whether to validate DG option structure on save | |
| 95 | + 'validation' => false, | |
| 96 | + | |
| 97 | + // whether to logging DG activity | |
| 98 | + 'logging' => false | |
| 44 | 99 | ); |
| 45 | 100 | } |
| 46 | 101 | |
| 47 | 102 | /** |
| 48 | - * Runs every page load, updates when needed. | |
| 103 | + * Runs every page load, updates as needed. | |
| 49 | 104 | */ |
| 50 | 105 | public static function maybeUpdate() { |
| 51 | 106 | global $dg_options; |
| 52 | 107 | |
| 53 | - // first installation | |
| 54 | - if (is_null($dg_options)) { | |
| 55 | - $options = self::getDefaultOptions(); | |
| 56 | - add_option(DG_OPTION_NAME, $options); | |
| 108 | + // do update | |
| 109 | + if (null != $dg_options && DG_VERSION !== $dg_options['version']) { | |
| 110 | + $blogs = array(null); | |
| 111 | + | |
| 112 | + if (is_multisite()) { | |
| 113 | + global $wpdb; | |
| 114 | + $blogs = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs"); | |
| 115 | + } | |
| 116 | + | |
| 117 | + foreach ($blogs as $blog) { | |
| 118 | + self::_update($blog); | |
| 119 | + } | |
| 57 | 120 | } |
| 121 | + } | |
| 122 | + | |
| 123 | + /** | |
| 124 | + * Runs when update is needed, updating the given blog. If blog is null, | |
| 125 | + * active blog is updated. | |
| 126 | + * @param int $blog Blog to update or null if updating current blog. | |
| 127 | + */ | |
| 128 | + private static function _update($blog) { | |
| 129 | + $options = DocumentGallery::getOptions($blog); | |
| 130 | + if (is_null($options)) return; | |
| 58 | 131 | |
| 59 | - // do update | |
| 60 | - elseif (DG_VERSION !== $dg_options['version']) { | |
| 61 | - $dg_options['version'] = DG_VERSION; | |
| 62 | - update_option(DG_OPTION_NAME, $dg_options); | |
| 132 | + // version-specific updates | |
| 133 | + self::twoPointTwo($options); | |
| 134 | + | |
| 135 | + // update plugin version | |
| 136 | + $options['version'] = DG_VERSION; | |
| 63 | 137 | |
| 64 | - if ('' !== $dg_options['css']['text']) { | |
| 65 | - DocumentGallery::updateUserGalleryStyle($dg_options['css']['text']); | |
| 138 | + // setup CSS | |
| 139 | + $options['css']['minified'] = isset($options['css']['text']) | |
| 140 | + ? DocumentGallery::compileCustomCss($options['css']['text']) | |
| 141 | + : ''; | |
| 142 | + $options['css']['last-modified'] = gmdate('D, d M Y H:i:s'); | |
| 143 | + $options['css']['etag'] = md5($options['css']['last-modified']); | |
| 144 | + | |
| 145 | + // remove previously-failed thumbs | |
| 146 | + $thumbs = $options['thumber']['thumbs']; | |
| 147 | + foreach ($thumbs as $k => $v) { | |
| 148 | + if (empty($v['thumber'])) { | |
| 149 | + unset($options['thumber']['thumbs'][$k]); | |
| 66 | 150 | } |
| 67 | 151 | } |
| 152 | + | |
| 153 | + DocumentGallery::setOptions($options, $blog); | |
| 68 | 154 | } |
| 155 | + | |
| 156 | + /** | |
| 157 | + * The 'created_timestamp' key in each thumb record is being moved | |
| 158 | + * to 'timestamp' as part of a move to store timestamp for failed | |
| 159 | + * thumbnails in addition to successful ones. | |
| 160 | + * | |
| 161 | + * The defaults sub-branch in the gallery branch is being flattened into its parent. | |
| 162 | + * | |
| 163 | + * @param array $options The options to be modified. | |
| 164 | + */ | |
| 165 | + private static function twoPointTwo(&$options) { | |
| 166 | + if (version_compare($options['version'], '2.2', '<')) { | |
| 167 | + $thumbs = array(); | |
| 168 | + | |
| 169 | + // "created_timestamp" moving to just "timestamp" | |
| 170 | + foreach ($options['thumber']['thumbs'] as $id => $thumb) { | |
| 171 | + if (false === $thumb) continue; | |
| 172 | + | |
| 173 | + $thumbs[$id] = array( | |
| 174 | + 'timestamp' => $thumb['created_timestamp'], | |
| 175 | + 'thumb_url' => $thumb['thumb_url'], | |
| 176 | + 'thumb_path' => $thumb['thumb_path'], | |
| 177 | + 'thumber' => $thumb['thumber'] | |
| 178 | + ); | |
| 179 | + } | |
| 180 | + | |
| 181 | + $options['thumber']['thumbs'] = $thumbs; | |
| 182 | + | |
| 183 | + // adding default thumbnail generation timeout | |
| 184 | + $options['thumber']['timeout'] = 30; | |
| 185 | + | |
| 186 | + // flatten out "defaults" level | |
| 187 | + $options['gallery'] = $options['gallery']['defaults']; | |
| 188 | + | |
| 189 | + // adding "validation" branch | |
| 190 | + $options['validation'] = false; | |
| 191 | + | |
| 192 | + // adding "logging" branch | |
| 193 | + $options['logging'] = false; | |
| 194 | + } | |
| 195 | + } | |
| 196 | + | |
| 197 | + /** | |
| 198 | + * Sets up Document Gallery on all blog(s) activated. | |
| 199 | + * @param bool $networkwide Whether this is a network-wide update (multisite only). | |
| 200 | + */ | |
| 201 | + public static function activate($networkwide) { | |
| 202 | + $blogs = array(null); | |
| 203 | + | |
| 204 | + if (is_multisite()) { | |
| 205 | + // check if it is a network activation | |
| 206 | + if ($networkwide) { | |
| 207 | + global $wpdb; | |
| 208 | + $blogs = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs"); | |
| 209 | + } | |
| 210 | + } | |
| 211 | + | |
| 212 | + foreach ($blogs as $blog) { | |
| 213 | + self::_activate($blog); | |
| 214 | + } | |
| 215 | + } | |
| 216 | + | |
| 217 | + /** | |
| 218 | + * Hooked into wpmu_new_blog to handle activating a new blog when plugin | |
| 219 | + * is already network activated. | |
| 220 | + * See discussion: https://core.trac.wordpress.org/ticket/14170 | |
| 221 | + * @param int $blog Blog ID. | |
| 222 | + */ | |
| 223 | + public static function activateNewBlog($blog) { | |
| 224 | + if (is_plugin_active_for_network(DG_BASENAME)) { | |
| 225 | + self::_activate($blog); | |
| 226 | + } | |
| 227 | + } | |
| 228 | + | |
| 229 | + /** | |
| 230 | + * Runs activation setup for Document Gallery on all blog(s) it is activated on. | |
| 231 | + * @param int $blog Blog to update or null if updating current blog. | |
| 232 | + */ | |
| 233 | + private static function _activate($blog) { | |
| 234 | + $options = DocumentGallery::getOptions($blog); | |
| 235 | + | |
| 236 | + // first activation | |
| 237 | + if (is_null($options)) { | |
| 238 | + DocumentGallery::setOptions(self::getDefaultOptions(), $blog); | |
| 239 | + } | |
| 240 | + } | |
| 69 | 241 | |
| 70 | 242 | /** |
| 71 | 243 | * Runs when DG is uninstalled. |
| 72 | 244 | */ |
| @@ -72,18 +244,34 @@ | ||
| 72 | 244 | */ |
| 73 | 245 | public static function uninstall() { |
| 74 | 246 | if (!current_user_can('activate_plugins')) return; |
| 75 | 247 | check_admin_referer('bulk-plugins'); |
| 248 | + | |
| 249 | + $blogs = array(null); | |
| 250 | + | |
| 251 | + if (is_multisite()) { | |
| 252 | + global $wpdb; | |
| 253 | + $blogs = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs"); | |
| 254 | + } | |
| 255 | + | |
| 256 | + foreach ($blogs as $blog) { | |
| 257 | + self::_uninstall($blog); | |
| 258 | + } | |
| 259 | + } | |
| 260 | + /** | |
| 261 | + * Runs when DG is uninstalled for an individual blog. | |
| 262 | + */ | |
| 263 | + private static function _uninstall($blog) { | |
| 264 | + $options = DG_Thumber::getOptions($blog); | |
| 265 | + if (is_null($options)) return; | |
| 76 | 266 | |
| 77 | - $options = DG_Thumber::getOptions(); | |
| 78 | - | |
| 79 | 267 | foreach ($options['thumbs'] as $val) { |
| 80 | - if (false !== $val) { | |
| 268 | + if (isset($val['thumber'])) { | |
| 81 | 269 | @unlink($val['thumb_path']); |
| 82 | 270 | } |
| 83 | 271 | } |
| 84 | 272 | |
| 85 | - delete_option(DG_OPTION_NAME); | |
| 273 | + DocumentGallery::deleteOptions($blog); | |
| 86 | 274 | } |
| 87 | 275 | |
| 88 | 276 | /** |
| 89 | 277 | * Blocks instantiation. All functions are static. |