Add abstract event listeners for user merge/rename
authorMatthias Schmidt <gravatronics@live.com>
Sat, 27 Feb 2016 14:28:53 +0000 (15:28 +0100)
committerMatthias Schmidt <gravatronics@live.com>
Sat, 27 Feb 2016 14:28:53 +0000 (15:28 +0100)
CHANGELOG.md
wcfsetup/install/files/lib/system/event/listener/AbstractUserActionRenameListener.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/event/listener/AbstractUserMergeListener.class.php [new file with mode: 0644]

index de8656e303c2938f06a6debdf148e7b3bb144309..e04d30361f23dc9fb090bb5ec731664166750c84 100644 (file)
@@ -24,6 +24,8 @@
 * `parentObjectID` column added to `modification_log` and `wcf\system\log\modification\AbstractModificationLogHandler` introduced as a replacement for `wcf\system\log\modification\ModificationLogHandler`.
 * Add sort support for `useroptions` option type.
 * Make user options shown in sidebar sortable.
+* `wcf\system\event\listener\AbstractUserActionRenameListener` added.
+* `wcf\system\event\listener\AbstractUserMergeListener` added.
 
 #### New Traits
 
diff --git a/wcfsetup/install/files/lib/system/event/listener/AbstractUserActionRenameListener.class.php b/wcfsetup/install/files/lib/system/event/listener/AbstractUserActionRenameListener.class.php
new file mode 100644 (file)
index 0000000..34ac360
--- /dev/null
@@ -0,0 +1,54 @@
+<?php
+namespace wcf\system\event\listener;
+use wcf\system\WCF;
+
+/**
+ * Abstract implementation of an event listener updating database tables during
+ * a user rename.
+ * 
+ * @author     Matthias Schmidt
+ * @copyright  2001-2016 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    com.woltlab.wcf
+ * @subpackage system.event.listener
+ * @category   Community Framework
+ */
+abstract class AbstractUserActionRenameListener implements IParameterizedEventListener {
+       /**
+        * data of the updated database tables
+        * can either contain the database table as value if `userID` and `username`
+        * are the names of the database columns or an array with values `name`
+        * (database table name), `userID` and `username` (names of the database
+        * table columns containing the id and name of the user)
+        * `{WCF_N}` will be automatically replaced with the number of the WCF installation
+        * (only with PHP 5.6 string concatenation is possible in property declarations) 
+        * @var array
+        */
+       protected $databaseTables = [];
+       
+       /**
+        * @inheritDoc
+        */
+       public function execute($eventObj, $className, $eventName, array &$parameters) {
+               $userID = $eventObj->getObjects()[0]->userID;
+               $username = $eventObj->getParameters()['data']['username'];
+               
+               WCF::getDB()->beginTransaction();
+               
+               foreach ($this->databaseTables as $databaseTable) {
+                       if (!is_array($databaseTable)) {
+                               $databaseTable = ['name' => $databaseTable];
+                       }
+                       if (!isset($databaseTable['userID'])) $databaseTable['userID'] = 'userID';
+                       if (!isset($databaseTable['username'])) $databaseTable['username'] = 'username';
+                       
+                       $sql = "UPDATE  ".str_replace('{WCF_N}', WCF_N, $databaseTable['name'])."
+                               SET     ".$databaseTable['username']." = ?
+                               WHERE   ".$databaseTable['userID']." = ?";
+                       $statement = WCF::getDB()->prepareStatement($sql);
+                       $statement->execute([$username, $userID]);
+               }
+               
+               WCF::getDB()->commitTransaction();
+       }
+}
diff --git a/wcfsetup/install/files/lib/system/event/listener/AbstractUserMergeListener.class.php b/wcfsetup/install/files/lib/system/event/listener/AbstractUserMergeListener.class.php
new file mode 100644 (file)
index 0000000..acefe16
--- /dev/null
@@ -0,0 +1,51 @@
+<?php
+namespace wcf\system\event\listener;
+use wcf\system\database\util\PreparedStatementConditionBuilder;
+use wcf\system\WCF;
+
+/**
+ * Abstract implementation of an event listener updating database tables during
+ * a user merge.
+ *
+ * @author     Matthias Schmidt
+ * @copyright  2001-2016 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    com.woltlab.wcf
+ * @subpackage system.event.listener
+ * @category   Community Framework
+ */
+abstract class AbstractUserMergeListener implements IParameterizedEventListener {
+       /**
+        * data of the updated database tables
+        * can either contain the database table as value if `userID` is the name
+        * of the database column and no ignore is needed or an array with values
+        * `name` (database table name), `userID`(name of the database table column
+        * containing the id of the user) and `ignore` (optional) if an UPDATE IGNORE
+        * query should be used.
+        * `{WCF_N}` will be automatically replaced with the number of the WCF installation
+        * (only with PHP 5.6 string concatenation is possible in property declarations)
+        * @var array
+        */
+       protected $databaseTables = [];
+       
+       /**
+        * @inheritDoc
+        */
+       public function execute($eventObj, $className, $eventName, array &$parameters) {
+               foreach ($this->databaseTables as $databaseTable) {
+                       if (!is_array($databaseTable)) {
+                               $databaseTable = ['name' => $databaseTable];
+                       }
+                       if (!isset($databaseTable['userID'])) $databaseTable['userID'] = 'userID';
+                       
+                       $conditionBuilder = new PreparedStatementConditionBuilder();
+                       $conditionBuilder->add($databaseTable['userID']." IN (?)", [$eventObj->mergedUserIDs]);
+                       
+                       $sql = "UPDATE".(!empty($databaseTable['ignore']) ? " IGNORE" : "")."   ".str_replace('{WCF_N}', WCF_N, $databaseTable['name'])."
+                               SET     ".$databaseTable['userID']." = ?
+                               ".$conditionBuilder;
+                       $statement = WCF::getDB()->prepareStatement($sql);
+                       $statement->execute(array_merge([$eventObj->destinationUserID], $conditionBuilder->getParameters()));
+               }
+       }
+}