Add `Database::prepare()` which replaces `app1_` with `app{WCF_N}_` (#4223)
authorMatthias Schmidt <gravatronics@live.com>
Wed, 19 May 2021 05:08:01 +0000 (07:08 +0200)
committerGitHub <noreply@github.com>
Wed, 19 May 2021 05:08:01 +0000 (07:08 +0200)
Close #2911

wcfsetup/install/files/lib/system/database/Database.class.php

index 27d4b444cb75a2ee314093d01acacd843466f8de..8ab5bab8f659b543590335e0c3d1cdb25390d37d 100644 (file)
@@ -2,6 +2,8 @@
 
 namespace wcf\system\database;
 
+use wcf\data\application\Application;
+use wcf\system\application\ApplicationHandler;
 use wcf\system\benchmark\Benchmark;
 use wcf\system\database\editor\DatabaseEditor;
 use wcf\system\database\exception\DatabaseException as GenericDatabaseException;
@@ -332,6 +334,37 @@ abstract class Database
         }
     }
 
+    /**
+     * Prepares a statement for execution and returns a statement object.
+     *
+     * In contrast to `prepareStatement()`, for all installed apps, `app1_` is replaced with
+     * `app{WCF_N}_`.
+     *
+     * @since   5.4
+     */
+    public function prepare(string $statement, int $limit = 0, int $offset = 0): PreparedStatement
+    {
+        static $regex = null;
+        if ($regex === null) {
+            $abbreviations = \implode(
+                '|',
+                \array_map(static function (Application $app): string {
+                    return \preg_quote($app->getAbbreviation(), '~');
+                }, ApplicationHandler::getInstance()->getApplications())
+            );
+
+            $regex = "~(\\b(?:{$abbreviations}))1_~";
+        }
+
+        $statement = \preg_replace(
+            $regex,
+            '${1}' . WCF_N . '_',
+            $statement
+        );
+
+        return $this->prepareStatement($statement, $limit, $offset);
+    }
+
     /**
      * Handles the limit and offset parameter in SELECT queries.
      * This is a default implementation compatible to MySQL and PostgreSQL.