Skip to content

Commit 7bfa0e4

Browse files
committed
Fix PDO::inTransaction() for SQLite on PHP < 8.4
1 parent 2413c95 commit 7bfa0e4

1 file changed

Lines changed: 30 additions & 1 deletion

File tree

wp-includes/sqlite-ast/class-wp-pdo-mysql-on-sqlite.php

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,19 @@ class WP_PDO_MySQL_On_SQLite {
504504
*/
505505
private $wrapper_transaction_type = null;
506506

507+
/**
508+
* Whether an SQLite transaction is active in the current session.
509+
*
510+
* This is a polyfill of the "PDO::inTransaction()" method for PHP < 8.4,
511+
* where the "PDO::inTransaction()" method is not reliable with SQLite.
512+
*
513+
* @see https://bugs.php.net/bug.php?id=81227
514+
* @see https://github.com/php/php-src/pull/14268
515+
*
516+
* @var bool
517+
*/
518+
private $in_transaction = false;
519+
507520
/**
508521
* Whether a MySQL table lock is active.
509522
*
@@ -719,6 +732,15 @@ public function rollBack(): bool {
719732
*/
720733
// phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid
721734
public function inTransaction(): bool {
735+
if ( PHP_VERSION_ID < 80400 ) {
736+
/*
737+
* On PHP < 8.4, the "PDO::inTransaction()" method is not reliable.
738+
*
739+
* @see https://bugs.php.net/bug.php?id=81227
740+
* @see https://github.com/php/php-src/pull/14268
741+
*/
742+
return $this->in_transaction;
743+
}
722744
return $this->connection->get_pdo()->inTransaction();
723745
}
724746

@@ -1335,6 +1357,7 @@ private function begin_wrapper_transaction(): void {
13351357
throw $this->new_driver_exception( 'Failed to begin wrapper transaction.' );
13361358
}
13371359
$this->wrapper_transaction_type = $wrapper_transaction_type;
1360+
$this->in_transaction = true;
13381361
}
13391362

13401363
/**
@@ -1345,17 +1368,20 @@ private function commit_wrapper_transaction(): void {
13451368
return;
13461369
}
13471370

1371+
$in_transaction = $this->in_transaction;
13481372
if ( 'savepoint' === $this->wrapper_transaction_type ) {
13491373
$savepoint_name = $this->get_internal_savepoint_name( 'wrapper' );
13501374
$stmt = $this->connection->prepare( sprintf( 'RELEASE SAVEPOINT %s', $savepoint_name ) );
13511375
} else {
1352-
$stmt = $this->connection->prepare( 'COMMIT' );
1376+
$stmt = $this->connection->prepare( 'COMMIT' );
1377+
$in_transaction = false;
13531378
}
13541379

13551380
if ( ! $stmt->execute() ) {
13561381
throw $this->new_driver_exception( 'Failed to commit wrapper transaction.' );
13571382
}
13581383
$this->wrapper_transaction_type = null;
1384+
$this->in_transaction = $in_transaction;
13591385
}
13601386

13611387
/**
@@ -1378,6 +1404,7 @@ private function begin_user_transaction(): void {
13781404
* @see self::begin_wrapper_transaction()
13791405
*/
13801406
$this->connection->query( 'BEGIN IMMEDIATE' );
1407+
$this->in_transaction = true;
13811408
}
13821409

13831410
/**
@@ -1389,6 +1416,7 @@ private function commit_user_transaction(): void {
13891416
return;
13901417
}
13911418
$this->connection->query( 'COMMIT' );
1419+
$this->in_transaction = false;
13921420
}
13931421

13941422
/**
@@ -1400,6 +1428,7 @@ private function rollback_user_transaction(): void {
14001428
return;
14011429
}
14021430
$this->connection->query( 'ROLLBACK' );
1431+
$this->in_transaction = false;
14031432
}
14041433

14051434
/**

0 commit comments

Comments
 (0)