From 208e02c47d086b67f1431a9e09c76a8129ac8939 Mon Sep 17 00:00:00 2001
From: Andrew Dolgov <noreply@fakecake.org>
Date: Tue, 10 Mar 2020 08:14:00 +0300
Subject: [PATCH] PluginHost/save_data: use separate PDO connection to prevent
 issues with nested transactions

---
 classes/pluginhost.php | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/classes/pluginhost.php b/classes/pluginhost.php
index 6158880f2..cb3e0f833 100755
--- a/classes/pluginhost.php
+++ b/classes/pluginhost.php
@@ -1,6 +1,9 @@
 <?php
 class PluginHost {
 	private $pdo;
+	/* separate handle for plugin data so transaction while saving wouldn't clash with possible main
+		tt-rss code transactions; only initialized when first needed */
+	private $pdo_data;
 	private $hooks = array();
 	private $plugins = array();
 	private $handlers = array();
@@ -73,7 +76,6 @@ class PluginHost {
 
 	function __construct() {
 		$this->pdo = Db::pdo();
-
 		$this->storage = array();
 	}
 
@@ -361,9 +363,13 @@ class PluginHost {
 
 	private function save_data($plugin) {
 		if ($this->owner_uid) {
-			$this->pdo->beginTransaction();
 
-			$sth = $this->pdo->prepare("SELECT id FROM ttrss_plugin_storage WHERE
+			if (!$this->pdo_data)
+				$this->pdo_data = Db::instance()->pdo_connect();
+
+			$this->pdo_data->beginTransaction();
+
+			$sth = $this->pdo_data->prepare("SELECT id FROM ttrss_plugin_storage WHERE
 				owner_uid= ? AND name = ?");
 			$sth->execute([$this->owner_uid, $plugin]);
 
@@ -373,18 +379,18 @@ class PluginHost {
 			$content = serialize($this->storage[$plugin]);
 
 			if ($sth->fetch()) {
-				$sth = $this->pdo->prepare("UPDATE ttrss_plugin_storage SET content = ?
+				$sth = $this->pdo_data->prepare("UPDATE ttrss_plugin_storage SET content = ?
 					WHERE owner_uid= ? AND name = ?");
 				$sth->execute([(string)$content, $this->owner_uid, $plugin]);
 
 			} else {
-				$sth = $this->pdo->prepare("INSERT INTO ttrss_plugin_storage
+				$sth = $this->pdo_data->prepare("INSERT INTO ttrss_plugin_storage
 					(name,owner_uid,content) VALUES
 					(?, ?, ?)");
 				$sth->execute([$plugin, $this->owner_uid, (string)$content]);
 			}
 
-			$this->pdo->commit();
+			$this->pdo_data->commit();
 		}
 	}
 
-- 
GitLab