Experimental fix for table name and alias resolution
authorAlexander Ebert <ebert@woltlab.com>
Fri, 16 Feb 2018 23:42:29 +0000 (00:42 +0100)
committerAlexander Ebert <ebert@woltlab.com>
Fri, 16 Feb 2018 23:42:29 +0000 (00:42 +0100)
Relying on a local static variable is dangerous, because it is bound to
the implementing class, but once set, it becomes fixed for all derived
classes too.

This is similar to the `wcf\system\SingletonFactory` work-around that
uses a lookup table rather than LSB fields for the same reasons.

wcfsetup/install/files/lib/data/DatabaseObject.class.php

index d073c2ed8e987faa6c0dae0ffc8483aed36b1259..54b7f2e7fee6bc5da7995f8960608ebcd5041cd0 100644 (file)
@@ -41,6 +41,24 @@ abstract class DatabaseObject implements IStorableObject {
         */
        protected static $sortOrder = null;
        
+       /**
+        * The list of derived database table names based on the class name.
+        * 
+        * WARNING: This is strictly an internal lookup table. DO NOT USE IT.
+        * 
+        * @var string[] 
+        */
+       protected static $_derivedDatabaseTableName = [];
+       
+       /**
+        * The list of derived database table aliases based on the class name.
+        * 
+        * WARNING: This is strictly an internal lookup table. DO NOT USE IT.
+        * 
+        * @var string[]
+        */
+       protected static $_derivedDatabaseTableAlias = [];
+       
        /**
         * object data
         * @var array
@@ -134,12 +152,11 @@ abstract class DatabaseObject implements IStorableObject {
                        return $classParts[0].WCF_N.'_'.static::$databaseTableName;
                }
                
-               static $databaseTableName = null;
-               if ($databaseTableName === null) {
-                       $databaseTableName = $classParts[0].WCF_N.'_'.strtolower(implode('_', preg_split('~(?=[A-Z](?=[a-z]))~', array_pop($classParts), -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY)));
+               if (!isset(self::$_derivedDatabaseTableName[$className])) {
+                       self::$_derivedDatabaseTableName[$className] = $classParts[0].WCF_N.'_'.strtolower(implode('_', preg_split('~(?=[A-Z](?=[a-z]))~', array_pop($classParts), -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY)));
                }
                
-               return $databaseTableName;
+               return self::$_derivedDatabaseTableName[$className];
        }
        
        /**
@@ -150,13 +167,13 @@ abstract class DatabaseObject implements IStorableObject {
                        return static::$databaseTableName;
                }
                
-               static $databaseTableNameAlias = null;
-               if ($databaseTableNameAlias === null) {
-                       $classParts = explode('\\', get_called_class());
-                       $databaseTableNameAlias = strtolower(implode('_', preg_split('~(?=[A-Z](?=[a-z]))~', array_pop($classParts), -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY)));
+               $className = get_called_class();
+               if (!isset(self::$_derivedDatabaseTableAlias[$className])) {
+                       $classParts = explode('\\', $className);
+                       self::$_derivedDatabaseTableAlias[$className] = strtolower(implode('_', preg_split('~(?=[A-Z](?=[a-z]))~', array_pop($classParts), -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY)));
                }
                
-               return $databaseTableNameAlias;
+               return self::$_derivedDatabaseTableAlias[$className];
        }
        
        /**