db_server_info();
$maria = stripos( $info, 'MariaDB' ) !== false;
$parsed = array();
preg_match( '/(?:5\.5\.5-)?(\d+\.\d+\.\d+)/', $info, $parsed );
$required = $maria ? ( $minimum['mariadb'] ?? self::MARIA_MIN ) : ( $minimum['mysql'] ?? self::MYSQL_MIN );
$valid_minimum = is_string( $required ) && preg_match( '/^\d+\.\d+\.\d+$/D', $required );
$supported = $valid_minimum && isset( $parsed[1] ) && version_compare( $parsed[1], $required, '>=' );
// A MySQL compatibility string is not proof that a distributed SQL fork has atomic InnoDB DDL.
if ( preg_match( '/TiDB|OceanBase|Vitess/i', $info ) ) {
$supported = false;
}
return array(
'server' => $info,
'vendor' => $maria ? 'MariaDB' : 'MySQL',
'version' => $parsed[1] ?? '',
'supported' => (bool) $supported,
'rename_under_write_locks' => ! $maria && isset( $parsed[1] ) && version_compare( $parsed[1], '8.0.13', '>=' ),
);
}
/** @param object $wpdb Database connection. @param bool $translate Whether init has run. @return string */
public static function message( $wpdb, $translate = true ) {
$detected = self::inspect( $wpdb );
/* translators: %s: actual database server version detected from the live connection. */
$format = $translate ? __( 'Detected database server: %s. ABeCe Booking 1.1.3 requires MySQL 8.0 or MariaDB 10.6.1 or newer with InnoDB. Please contact your hosting provider to upgrade the database server. No application data has been changed.', 'abece-booking' ) : 'Detected database server: %s. ABeCe Booking 1.1.3 requires MySQL 8.0 or MariaDB 10.6.1 or newer with InnoDB. Please contact your hosting provider to upgrade the database server. No application data has been changed.';
return sprintf( $format, $detected['vendor'] . ' ' . $detected['server'] );
}
/** @param string $file Plugin entry point. @return void */
public static function register_failure( $file ) {
// Core may retain the official SDK callback registered by an older version.
// During deletion only, make that callable available without activating the app.
// No SDK bootstrap/identity is created during ordinary rejected activation.
foreach ( debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS, 12 ) as $frame ) {
if ( ( $frame['function'] ?? '' ) === 'uninstall_plugin' && ! class_exists( 'Freemius', false ) ) {
$sdk = dirname( $file ) . '/vendor/freemius/wordpress-sdk/start.php';
if ( is_readable( $sdk ) ) {
require_once $sdk;
}
break;
}
}
$translations = static function () use ( $file ) {
global $wp_textdomain_registry;
if ( isset( $wp_textdomain_registry ) && method_exists( $wp_textdomain_registry, 'set_custom_path' ) ) {
$wp_textdomain_registry->set_custom_path( 'abece-booking', dirname( $file ) . '/languages' );
}
};
add_action( 'init', $translations, 0 );
$render = static function () {
global $wpdb;
if ( current_user_can( 'activate_plugins' ) ) {
echo '
' . esc_html( self::message( $wpdb ) ) . '
';
}
};
add_action( 'admin_notices', $render );
add_action(
'admin_menu',
static function () use ( $render ) {
add_menu_page( 'ABeCe Booking', 'ABeCe Booking', 'activate_plugins', 'abece-booking', $render );
}
);
register_activation_hook(
$file,
static function () use ( $translations ) {
global $wpdb;
$translations();
wp_die( esc_html( self::message( $wpdb ) ), 'ABeCe Booking', array( 'back_link' => true ) );
}
);
}
/** @param string $file Current plugin entry point. @return void */
public static function register( $file ) {
$basename = plugin_basename( $file );
// Validate the real downloaded package before core's deactivation callback.
// Core performs both download and extraction; the returned bytes are unchanged.
$checking = false;
add_filter(
'upgrader_pre_download',
static function ( $reply, $package, $upgrader, $extra ) use ( $basename, &$checking ) {
if ( $checking || is_wp_error( $reply ) || ( $extra['plugin'] ?? '' ) !== $basename ) {
return $reply;
}
$checking = true;
$working = null;
$download = null;
try {
$download = is_string( $reply ) ? $reply : $upgrader->download_package( $package, false, $extra );
if ( is_wp_error( $download ) ) {
return $download;
}
$working = $upgrader->unpack_package( $download, false );
if ( is_wp_error( $working ) ) {
return $working;
}
global $wp_filesystem;
$entries = $wp_filesystem->dirlist( $working );
$source = $working;
if ( is_array( $entries ) && count( $entries ) === 1 ) {
$entry = reset( $entries );
if ( ( $entry['type'] ?? '' ) === 'd' ) {
$source = trailingslashit( $working ) . $entry['name'];
}
}
$error = self::source_error( $source, true );
if ( $error ) {
if ( $download !== $package ) {
wp_delete_file( $download );
}
return $error;
}
return $download;
} finally {
if ( is_string( $working ) ) {
global $wp_filesystem;
$wp_filesystem->delete( $working, true );
}
$checking = false;
}
},
100,
4
);
add_filter(
'upgrader_pre_install',
static function ( $reply, $extra ) use ( $basename ) {
if ( is_wp_error( $reply ) || ( $extra['plugin'] ?? '' ) !== $basename ) {
return $reply;
}
global $wpdb;
if ( ! self::inspect( $wpdb )['supported'] ) {
return new \WP_Error( 'abece_booking_database_server_unsupported', self::message( $wpdb ) );
}
$updates = get_site_transient( 'update_plugins' );
$offer = is_object( $updates ) ? ( $updates->response[ $basename ] ?? null ) : null;
if ( is_object( $offer ) && isset( $offer->new_version ) && version_compare( $offer->new_version, '1.1.2', '<' ) && (int) get_option( 'abece_booking_db_version', 0 ) >= 13 ) {
return new \WP_Error( 'abece_booking_unsafe_database_downgrade', __( 'An older ABeCe Booking package cannot use this database schema. Restore the matching database backup and plugin files during maintenance instead.', 'abece-booking' ) );
}
if ( is_object( $offer ) && isset( $offer->abece_booking_database_requirements ) && ! self::inspect( $wpdb, (array) $offer->abece_booking_database_requirements )['supported'] ) {
return new \WP_Error( 'abece_booking_future_database_server_unsupported', __( 'This update requires a newer database server. Please contact your hosting provider before updating ABeCe Booking.', 'abece-booking' ) );
}
return $reply;
},
-100,
2
);
add_filter(
'upgrader_source_selection',
static function ( $source, $remote, $upgrader, $extra ) use ( $basename ) {
if ( is_wp_error( $source ) || ( isset( $extra['plugin'] ) && $extra['plugin'] !== $basename ) ) {
return $source;
}
return self::source_error( $source ) ?: $source;
},
-100,
4
);
}
/** Inspect an unpacked package without executing any target PHP. @return \WP_Error|null */
private static function source_error( $source, $require_identity = false ) {
global $wp_filesystem, $wpdb;
$main = $wp_filesystem->get_contents( trailingslashit( $source ) . 'abece-booking.php' );
if ( ! is_string( $main ) || ! preg_match( '/^\s*\*\s*Text Domain:\s*abece-booking\s*$/m', $main ) ) {
return $require_identity ? new \WP_Error( 'abece_booking_package_identity_invalid', __( 'The plugin package is incomplete. Install the complete ABeCe Booking release ZIP.', 'abece-booking' ) ) : null;
}
if ( ! self::inspect( $wpdb )['supported'] ) {
return new \WP_Error( 'abece_booking_database_server_unsupported', self::message( $wpdb ) );
}
if ( preg_match( '/^\s*\*\s*Version:\s*([0-9.]+)/m', $main, $version ) && version_compare( $version[1], '1.1.2', '<' ) && (int) get_option( 'abece_booking_db_version', 0 ) >= 13 ) {
return new \WP_Error( 'abece_booking_unsafe_database_downgrade', __( 'An older ABeCe Booking package cannot use this database schema. Restore the matching database backup and plugin files during maintenance instead.', 'abece-booking' ) );
}
$raw = $wp_filesystem->get_contents( trailingslashit( $source ) . 'assets/build/release.json' );
$manifest = is_string( $raw ) && strlen( $raw ) < 65536 ? json_decode( $raw, true ) : null;
if ( ! is_array( $manifest ) || ! isset( $manifest['requires_database']['mysql'], $manifest['requires_database']['mariadb'] ) ) {
return new \WP_Error( 'abece_booking_database_requirements_invalid', __( 'The plugin package is incomplete. Install the complete ABeCe Booking release ZIP.', 'abece-booking' ) );
}
if ( is_array( $manifest ) && isset( $manifest['requires_database'] ) && ( ! is_array( $manifest['requires_database'] ) || ! self::inspect( $wpdb, $manifest['requires_database'] )['supported'] ) ) {
return new \WP_Error( 'abece_booking_future_database_server_unsupported', __( 'This update requires a newer database server. Please contact your hosting provider before updating ABeCe Booking.', 'abece-booking' ) );
}
return null;
}
}