LLMS_DB_Upgrader
Manage database updates and migrations
Contents
Source Source
File: includes/class-llms-db-ugrader.php
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 | class LLMS_DB_Upgrader { /** * DB Version that's being upgraded from. * * @var string */ protected $db_version = '' ; /** * Instance of the bg updater class * * @var LLMS_Background_Updater */ protected $updater = null; /** * Update list * * @var array */ protected $updates = array (); /** * Constructor * * @since 5.2.0 * * @see includes/schemas/llms-db-updates.php For an example updates schema. * * @param string $db_version The DB version that is being upgraded from. * @param null|array[] $updates A list of database updates conforming to the database updates schema * or null to load the LifterLMS core schema. */ public function __construct( $db_version , $updates = null ) { $this ->updater = LLMS_Install:: $background_updater ; // Background updates may trigger a notice during a cron and notices might not be available. require_once LLMS_PLUGIN_DIR . 'includes/admin/class.llms.admin.notices.php' ; if ( is_null ( $updates ) ) { $updates = require LLMS_PLUGIN_DIR . 'includes/schemas/llms-db-updates.php' ; } $this ->db_version = $db_version ; $this ->updates = $updates ; } /** * Determine if an auto-update is possible from the specified DB version * * Auto updating is possible as long as none of the required updates are marked as "manual". * * @since 5.2.0 * * @return boolean Returns `true` when an auto-update is possible and `false` if manual updating * is required. */ public function can_auto_update() { $autoupdate = true; foreach ( $this ->get_required_updates( $this ->db_version ) as $update ) { // If we find a manual update we cannot auto-update. if ( 'manual' === $update [ 'type' ] ) { $autoupdate = false; break ; } } /** * Filters the list of database updates. * * @since 5.2.0 * * @param boolean $autoupdate Whether or not an automatic update can be run. * @param string $db_version The specified DB that's being upgraded from. * @param LLMS_DB_Upgrader $upgrader Instance of the database upgrader. */ return apply_filters( 'llms_can_auto_update_db' , $autoupdate , $this ->db_version, $this ); } /** * Retrieve the callback's prefix string based on the schema's namespace declaration. * * If `$info['namespace']` is empty, no prefix will be added. * If `$info['namespace']` is `true`, the namespace is assumed to be `LLMS\Updates`. * If `$info['namespace']` is a string, that string will be used. * * If a namespace is found, `\Version_X_X_X` will automatically be appended to the namespace. The * string `X_X_X` is the database version for the upgrade substituting underscores for dots. * * @since 5.6.0 * * @param array $info Upgrade schema array. * @param string $version Version string for the upgrade. * @return string */ protected function get_callback_prefix( $info , $version ) { if ( ! empty ( $info [ 'namespace' ] ) ) { $ver = explode ( '-' , $version ); // Drop prerelease data. $ver = str_replace ( '.' , '_' , $ver [0] ); $ns = true === $info [ 'namespace' ] ? 'LLMS\Updates' : $info [ 'namespace' ]; return sprintf( '%1$s\\Version_%2$s\\' , $ns , $ver ); } return '' ; } /** * Enqueue and dispatch required updates * * Adds callbacks for all required updates to the LLMS_Background_Updater and dispatches * the updater in the background. * * If the update group cannot be auto-updated the following admin notices will be included: * + The "update started" notice will be immediately displayed/added. * + The "update complete" notice will be added to the end of the queue (and then displayed when the update is complete). * * @since 5.2.0 * @since 5.6.0 Add namespace prefix to qualifying callback functions. * * @return void */ public function enqueue_updates() { $queued = false; foreach ( $this ->get_required_updates() as $version => $info ) { $prefix = $this ->get_callback_prefix( $info , $version ); foreach ( $info [ 'updates' ] as $callback ) { $callback = $prefix . $callback ; $this ->updater->log( sprintf( 'Queuing %s - %s' , $version , $callback ) ); $this ->updater->push_to_queue( $callback ); $queued = true; } } // No updates to add, return early. if ( ! $queued ) { return ; } // Show a start and complete notice for manual updates. if ( ! $this ->can_auto_update() ) { $this ->show_notice_started(); $this ->updater->push_to_queue( array ( $this , 'show_notice_complete' ) ); } $this ->updater->save(); add_action( 'shutdown' , array ( 'LLMS_Install' , 'dispatch_db_updates' ) ); } /** * Retrieves the updates list * * @since 5.2.0 * * @return array */ public function get_updates() { /** * Filters the list of database updates. * * @since 5.2.0 * * @param array $updates List of updates to be run. * @param LLMS_DB_Upgrader $upgrader Instance of the database upgrader. */ return apply_filters( 'llms_db_updates_list' , $this ->updates, $this ); } /** * Retrieve a filtered list of updates as required by the specified DB version * * All updates greater than the specified version will be returned. * * @since 5.2.0 * * @return array[] */ public function get_required_updates() { $db_version = $this ->db_version; return array_filter ( $this ->get_updates(), function ( $update_version ) use ( $db_version ) { return version_compare( $db_version , $update_version , '<' ); }, ARRAY_FILTER_USE_KEY ); } /** * Determine whether or not there are required updates for a specified DB version. * * @since 5.2.0 * * @return boolean Returns `true` if there are updates to run, otherwise returns `false`. */ public function has_required_updates() { $required = $this ->get_required_updates( $this ->db_version ); return ! empty ( $required ); } /** * Show the db upgrade admin notice. * * Users can click this notice to start the database upgrade(s). * * @since 5.2.0 * * @return void */ protected function show_notice_pending() { $notice_id = 'bg-db-update' ; if ( LLMS_Admin_Notices::has_notice( $notice_id ) ) { LLMS_Admin_Notices::delete_notice( $notice_id ); } LLMS_Admin_Notices::add_notice( $notice_id , array ( 'dismissible' => false, 'template' => 'db-update.php' , 'default_path' => LLMS_PLUGIN_DIR . 'includes/admin/views/notices/' , ) ); } /** * Show a notice when a manual update is started. * * @since 5.2.0 * * @return void */ protected function show_notice_started() { LLMS_Admin_Notices::add_notice( 'bg-db-update-started' , __( 'Your database is being upgraded in the background. Feel free to leave this page. A notice like this will appear when the update is complete.' , 'lifterlms' ), array ( 'dismissible' => true, 'dismiss_for_days' => 0, ) ); } /** * Show a notice when the update is complete * * This will also delete the started notice. When short updates run quickly the started and completed notice * may show up on the same page load which is confusing to look at it. If we just started and it's already done * when the next page loads we only need to see that update is complete. * * @since 5.2.0 * * @return void */ public function show_notice_complete() { // If the update started notice exists, delete it to avoid confusing UX when the update finishes before the page loads. if ( LLMS_Admin_Notices::has_notice( 'bg-db-update-started' ) ) { LLMS_Admin_Notices::delete_notice( 'bg-db-update-started' ); } LLMS_Admin_Notices::add_notice( 'bg-db-update-complete' , __( 'The LifterLMS database update is complete.' , 'lifterlms' ), array ( 'dismissible' => true, 'dismiss_for_days' => 0, ) ); } /** * Start the update * * If autoupdating is possible, will enqueue and dispatch the bg updater. Otherwise * it will show the update pending notice which will prompt an admin to manually * start the update. * * @since 5.2.0 * * @return boolean Returns `false` if there are no updates to run and `true` otherwise. */ public function update() { if ( ! $this ->has_required_updates() ) { return false; } // Auto update if it can. if ( $this ->can_auto_update() ) { $this ->enqueue_updates(); } else { $this ->show_notice_pending(); } return true; } } |
Expand full source code Collapse full source code View on GitHub
Methods Methods
- __construct — Constructor
- can_auto_update — Determine if an auto-update is possible from the specified DB version
- enqueue_updates — Enqueue and dispatch required updates
- get_callback_prefix — Retrieve the callback's prefix string based on the schema's namespace declaration.
- get_required_updates — Retrieve a filtered list of updates as required by the specified DB version
- get_updates — Retrieves the updates list
- has_required_updates — Determine whether or not there are required updates for a specified DB version.
- show_notice_complete — Show a notice when the update is complete
- show_notice_pending — Show the db upgrade admin notice.
- show_notice_started — Show a notice when a manual update is started.
- update — Start the update
Changelog Changelog
Version | Description |
---|---|
5.2.0 | Introduced. |