query( 'START TRANSACTION' ) ) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Transaction control on the database connection; nothing to cache. return new \WP_Error( 'transaction_start_failed', __( 'The database transaction could not be started. No changes were applied.', 'glovario' ) ); } ++self::$depth; try { $result = call_user_func( $callback ); } catch ( \Throwable $error ) { --self::$depth; if ( $outermost ) { self::rollback(); } throw $error; } --self::$depth; if ( ! $outermost ) { return $result; } if ( is_wp_error( $result ) ) { self::rollback(); return $result; } if ( false === $wpdb->query( 'COMMIT' ) ) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Transaction control on the database connection; nothing to cache. self::rollback(); return new \WP_Error( 'transaction_commit_failed', __( 'The database transaction could not be completed. No changes were applied.', 'glovario' ) ); } return $result; } private static function rollback() { global $wpdb; $wpdb->query( 'ROLLBACK' ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Transaction control on the database connection; nothing to cache. The caches the rollback may have made stale are flushed below. // What a rolled-back import or reference rewrite may have cached: Glovario's data, // posts, and widgets (options). Every other group (users, sessions, other // plugins' data) is kept; caches that cannot flush a group are flushed whole. if ( function_exists( 'wp_cache_supports' ) && wp_cache_supports( 'flush_group' ) ) { foreach ( array( 'glovario_variables', 'glovario_rules', 'glovario_categories', 'posts', 'post_meta', 'options' ) as $group ) { wp_cache_flush_group( $group ); } } else { wp_cache_flush(); } do_action( 'glovario_transaction_rolled_back' ); } }