Skip to content

Instantly share code, notes, and snippets.

@sybrew
Created January 6, 2018 01:12
Show Gist options
  • Save sybrew/ca1ac4e109a203b81a959fb2abd6ae1d to your computer and use it in GitHub Desktop.
Save sybrew/ca1ac4e109a203b81a959fb2abd6ae1d to your computer and use it in GitHub Desktop.
An upgrading class that was planned, but can't work in TSFEM.
<?php
/**
* @package TSF_Extension_Manager/Bootstrap
*/
namespace TSF_Extension_Manager;
defined( 'TSF_EXTENSION_MANAGER_DB_VERSION' ) or die;
/**
* The SEO Framework - Extension Manager plugin
* Copyright (C) 2018 Sybre Waaijer, CyberWire (https://cyberwire.nl/)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as published
* by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
//= This is safe unless we invoke autoloading.
new Upgrade_Handler;
/**
* Class TSF_Extension_Manager\Upgrade_Handler
*
* Upgrades plugin and extensions.
*
* @since 1.0.0
* @access private
*/
final class Upgrade_Handler {
private $o = 'tsfem_current_db_version';
protected $previous_db_version;
protected $current_db_version;
protected $upgrades;
private $active_callbacks;
public function __construct() {
$this->upgrades = new \stdClass;
$this->previous_db_version = \get_option( $this->o, '0' );
$this->current_db_version = $this->previous_db_version;
\add_action( 'plugins_loaded', [ $this, '_load_hooks' ], 10 );
\add_action( 'plugins_loaded', [ $this, '_go' ], 11 );
}
public function get( $what ) {
switch ( $what ) :
case 'previous_db_version' :
$val = $this->previous_db_version;
break;
case 'current_db_version' :
$val = $this->current_db_version;
break;
default :
$val = '';
endswitch;
return $val;
}
/**
* @param string $version.
* @param callable $callback
*/
public function _register_upgrade( $version, callable $callback ) {
$c = &$this->_upgrade_collector();
isset( $c->{$version} ) or $c->{$version} = [];
$c->{$version}[] = $callback;
}
private function &_upgrade_collector() {
return $this->upgrades;
}
public function _load_hooks() {
if ( $this->deferred( $this->previous_db_version ) )
return;
$ms = \is_multisite();
if ( \is_admin() ) {
$this->do_admin_upgrade();
$ms and $this->do_admin_upgrade();
}
$this->do_always_upgrade();
$ms and $this->do_network_always_upgrade();
}
private function do_admin_upgrade() {
\do_action_ref_array( 'tsfem_prepare_admin_upgrade', [ $this ] );
}
private function do_network_admin_upgrade() {
\do_action_ref_array( 'tsfem_prepare_network_admin_upgrade', [ $this ] );
}
private function do_always_upgrade() {
\do_action_ref_array( 'tsfem_prepare_always_upgrade', [ $this ] );
}
private function do_network_always_upgrade() {
\do_action_ref_array( 'tsfem_prepare_network_always_upgrade', [ $this ] );
}
public function _go() {
$this->upgrades = (array) $this->upgrades;
ksort( $this->upgrades );
// $this->upgrades = array_filter( $this->upgrades, [ $this, 'remove_old_upgrades' ] );
$success = true;
foreach ( $this->yield_runs( $this->upgrades ) as $version => $_upgraded ) {
if ( $this->deferred( $version ) ) {
$success = false;
break;
}
if ( $_upgraded ) {
$success = \update_option( $this->o, $version );
}
if ( $_upgraded && $success ) {
$this->current_db_version = $version;
} else {
// TODO set notice after 3 consecutive fails.
$success = false;
break;
}
}
$success and \update_option( $this->o, TSF_EXTENSION_MANAGER_DB_VERSION );
}
private function yield_runs( $upgrade ) {
$this->active_callbacks = [];
foreach ( $upgrade as $version => $callbacks ) {
$this->active_callbacks[ $version ] = $callbacks;
yield [ $version => $this->upgraded() ];
}
}
private function upgraded() {
foreach ( $this->run_upgrades() as $success ) {
if ( ! $success )
return false;
}
return true;
}
private function &run_upgrades() {
$version = key( $this->active_callbacks );
$count = count( $this->active_callbacks[ $version ] );
$i = 0;
while ( $i < $count ) {
if ( call_user_func_array( $this->active_callbacks[ $version ][ $i++ ], [ $version ] ) ) {
yield true;
} else {
yield false;
}
}
}
/**
* @param string $version
*/
private function deferred( $version ) {
/**
* Applies filters 'tsf_extension_manager_impede_upgrade'
* Allows users to defer upgrades. It's advisable not to use.
*
* @since 1.5.0
* @param bool $deferred
* @param string $version
*/
if ( \apply_filters_ref_array( 'tsf_extension_manager_defer_upgrade', [ false, $version ] ) )
return true;
return false;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment