358 lines
6.9 KiB
PHP
358 lines
6.9 KiB
PHP
<?php
|
|
/**
|
|
* DB Updater module
|
|
*
|
|
* Version: 1.0.0
|
|
*/
|
|
|
|
// If this file is called directly, abort.
|
|
if ( ! defined( 'WPINC' ) ) {
|
|
die;
|
|
}
|
|
|
|
if ( ! class_exists( 'CX_DB_Updater' ) ) {
|
|
|
|
/**
|
|
* Class CX_DB_Updater.
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
class CX_DB_Updater {
|
|
|
|
/**
|
|
* Module arguments.
|
|
*
|
|
* @since 1.0.0
|
|
* @var array
|
|
*/
|
|
private $args = array(
|
|
'path' => '',
|
|
'url' => '',
|
|
'callbacks' => array(),
|
|
'slug' => null,
|
|
'version' => null,
|
|
'labels' => array(
|
|
'start_update' => 'Start Update',
|
|
'data_update' => 'Data Update',
|
|
'messages' => array(
|
|
'error' => 'Module DB Updater init error in %s - version and slug is required arguments',
|
|
'update' => 'We need to update your database to the latest version.',
|
|
'updated' => 'Update complete, thank you for updating to the latest version!',
|
|
),
|
|
),
|
|
);
|
|
|
|
/**
|
|
* Option key for DB version.
|
|
*
|
|
* @since 1.0.0
|
|
* @var string
|
|
*/
|
|
protected $version_key = '%s-db-version';
|
|
|
|
/**
|
|
* Nonce format.
|
|
*
|
|
* @since 1.0.0
|
|
* @var string
|
|
*/
|
|
protected $nonce = '_%s-db-update-nonce';
|
|
|
|
/**
|
|
* Messages array.
|
|
*
|
|
* @since 1.0.0
|
|
* @var array
|
|
*/
|
|
protected $messages = array();
|
|
|
|
/**
|
|
* Update done trigger.
|
|
*
|
|
* @since 1.0.0
|
|
* @var bool
|
|
*/
|
|
protected $updated = false;
|
|
|
|
/**
|
|
* Cherry_Db_Updater constructor.
|
|
*
|
|
* @since 1.0.0
|
|
* @param array $args Module arguments.
|
|
* @return void
|
|
*/
|
|
public function __construct( $args = array() ) {
|
|
|
|
$this->args = wp_parse_args( $args, $this->args );
|
|
|
|
if ( ! is_admin() || ! current_user_can( 'update_plugins' ) ) {
|
|
return;
|
|
}
|
|
|
|
add_action( 'admin_notices', array( $this, 'init_notices' ) );
|
|
add_action( 'admin_init', array( $this, 'do_update' ) );
|
|
|
|
$this->messages = $this->args['labels']['messages'];
|
|
}
|
|
|
|
/**
|
|
* Process DB update.
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function do_update() {
|
|
|
|
if ( ! $this->is_current_update() ) {
|
|
return;
|
|
}
|
|
|
|
$callbacks = $this->prepare_callbacks();
|
|
|
|
if ( ! empty( $callbacks ) ) {
|
|
foreach ( $callbacks as $callback ) {
|
|
if ( is_callable( $callback ) ) {
|
|
call_user_func( $callback );
|
|
}
|
|
}
|
|
}
|
|
|
|
$this->set_updated();
|
|
}
|
|
|
|
/**
|
|
* Finalize update.
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function set_updated() {
|
|
$this->updated = true;
|
|
$option = sprintf( $this->version_key, esc_attr( $this->args['slug'] ) );
|
|
update_option( $option, esc_attr( $this->args['version'] ) );
|
|
}
|
|
|
|
/**
|
|
* Prepare callbacks array.
|
|
*
|
|
* @since 1.0.0
|
|
* @return array
|
|
*/
|
|
private function prepare_callbacks() {
|
|
|
|
$callbacks = array();
|
|
|
|
if ( empty( $this->args['callbacks'] ) ) {
|
|
return $callbacks;
|
|
}
|
|
|
|
ksort( $this->args['callbacks'] );
|
|
|
|
foreach ( $this->args['callbacks'] as $ver => $ver_cb ) {
|
|
if ( version_compare( $this->get_current_version(), $ver, '<' ) ) {
|
|
$callbacks = array_merge( $callbacks, $ver_cb );
|
|
}
|
|
}
|
|
|
|
return $callbacks;
|
|
}
|
|
|
|
/**
|
|
* Check if we processed update for plugin passed in arguments.
|
|
*
|
|
* @since 1.0.0
|
|
* @return bool
|
|
*/
|
|
private function is_current_update() {
|
|
|
|
if ( empty( $_GET['cherry_x_db_update'] ) || empty( $_GET['slug'] ) || empty( $_GET['_nonce'] ) ) {
|
|
return false;
|
|
}
|
|
|
|
if ( $_GET['slug'] !== $this->args['slug'] ) {
|
|
return false;
|
|
}
|
|
|
|
$nonce_action = sprintf( $this->nonce, esc_attr( $this->args['slug'] ) );
|
|
|
|
if ( ! wp_verify_nonce( $_GET['_nonce'], $nonce_action ) ) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Init admin notices.
|
|
*
|
|
* @since 1.0.0
|
|
* @return void
|
|
*/
|
|
public function init_notices() {
|
|
|
|
$enabled = $this->validate_module_args();
|
|
|
|
if ( ! $enabled ) {
|
|
return;
|
|
}
|
|
|
|
$slug = esc_attr( $this->args['slug'] );
|
|
|
|
if ( $this->is_update_required() ) {
|
|
$this->show_notice( $slug );
|
|
}
|
|
|
|
if ( $this->is_updated() ) {
|
|
$this->show_updated_notice();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns current DB version.
|
|
*
|
|
* @since 1.0.0
|
|
* @return string
|
|
*/
|
|
private function get_current_version() {
|
|
$option = sprintf( $this->version_key, esc_attr( $this->args['slug'] ) );
|
|
|
|
return get_option( $option, '1.0.0' );
|
|
}
|
|
|
|
/**
|
|
* Check if database requires update.
|
|
*
|
|
* @since 1.0.0
|
|
* @return bool
|
|
*/
|
|
private function is_update_required() {
|
|
$current = $this->get_current_version();
|
|
|
|
return version_compare( $current, esc_attr( $this->args['version'] ), '<' );
|
|
}
|
|
|
|
/**
|
|
* Check if update was successfully done.
|
|
*
|
|
* @since 1.0.0
|
|
* @return bool
|
|
*/
|
|
private function is_updated() {
|
|
|
|
if ( ! $this->is_current_update() ) {
|
|
return false;
|
|
}
|
|
|
|
return (bool) $this->updated;
|
|
}
|
|
|
|
/**
|
|
* Validate module arguments.
|
|
*
|
|
* @since 1.0.0
|
|
* @return bool
|
|
*/
|
|
private function validate_module_args() {
|
|
|
|
if ( empty( $this->args['slug'] ) || empty( $this->args['version'] ) ) {
|
|
echo '<div class="error"><p>';
|
|
printf(
|
|
$this->messages['error'],
|
|
'<b>' . str_replace( untrailingslashit( ABSPATH ), '', $this->args['path'] ) . '</b>'
|
|
);
|
|
echo '</p></div>';
|
|
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Show notice.
|
|
*
|
|
* @since 1.0.0
|
|
* @param string $slug Plugin slug.
|
|
* @return void
|
|
*/
|
|
private function show_notice( $slug ) {
|
|
|
|
echo '<div class="notice notice-info">';
|
|
echo '<p>';
|
|
$this->notice_title( $slug );
|
|
echo $this->messages['update'];
|
|
echo '</p>';
|
|
echo '<p>';
|
|
$this->notice_submit( $slug );
|
|
echo '</p>';
|
|
echo '</div>';
|
|
}
|
|
|
|
/**
|
|
* Show update notice.
|
|
*
|
|
* @since 1.0.0
|
|
* @return void
|
|
*/
|
|
private function show_updated_notice() {
|
|
|
|
$slug = esc_attr( $this->args['slug'] );
|
|
|
|
echo '<div class="notice notice-success is-dismissible">';
|
|
echo '<p>';
|
|
$this->notice_title( $slug );
|
|
echo $this->messages['updated'];
|
|
echo '</p>';
|
|
echo '</div>';
|
|
}
|
|
|
|
/**
|
|
* Show plugin notice submit button.
|
|
*
|
|
* @since 1.0.0
|
|
* @param string $slug Plugin slug.
|
|
* @return void
|
|
*/
|
|
private function notice_submit( $slug = '' ) {
|
|
|
|
$format = '<a href="%1s" class="button button-primary">%2$s</a>';
|
|
$label = $this->args['labels']['start_update'];
|
|
$url = add_query_arg(
|
|
array(
|
|
'cherry_x_db_update' => true,
|
|
'slug' => $slug,
|
|
'_nonce' => $this->create_nonce( $slug ),
|
|
),
|
|
esc_url( admin_url( 'index.php' ) )
|
|
);
|
|
|
|
printf( $format, $url, $label );
|
|
|
|
}
|
|
|
|
/**
|
|
* Create DB update nonce.
|
|
*
|
|
* @since 1.0.0
|
|
* @param string $slug Plugin slug.
|
|
* @return string
|
|
*/
|
|
private function create_nonce( $slug ) {
|
|
return wp_create_nonce( sprintf( $this->nonce, $slug ) );
|
|
}
|
|
|
|
/**
|
|
* Show plugin notice title.
|
|
*
|
|
* @since 1.0.0
|
|
* @param string $slug Plugin slug.
|
|
* @return void
|
|
*/
|
|
private function notice_title( $slug ) {
|
|
|
|
$name = str_replace( '-', ' ', $slug );
|
|
$name = ucwords( $name );
|
|
|
|
printf( '<strong>%1$s %2$s</strong> – ', $name, $this->args['labels']['data_update'] );
|
|
}
|
|
}
|
|
}
|