- Affected App
- WoltLab Suite Core
Hallo,
ich habe ein Gewinnspiel-Plugin entwickelt, das per Cronjob mit ausgewählten Personen eine Konversationen eröffnet. Teilnehmer dieser Konversationen ist neben dem Gewinner und dem Konversationsstarter i. d. R. auch immer ein dritter User, der sich um das Versenden der Preise kümmert. Um diesem Teammitglied das Abnicken von X neu gestarteten Konversationen abzunehmen, ließ ich den Cronjob die jeweils neu eröffneten Konversationen für ebenjene Person als gelesen markieren:
$conversationAction = new ConversationAction([$conversation], 'markAsRead', ['userID' => $teammember]);
$conversationAction->executeAction();
So erhält er nur Benachrichtigungen über Antworten zu den Konversationen, was ganz praktisch ist.
Ich meine auch, dass dies mal einwandfrei ging, aber ich möchte meine Hand dafür nicht ins Feuer legen.
Derzeit ist es aber so, dass keiner mehr, also auch der Gewinner, keine Benachrichtigung mehr erhält. Die dazu gehörige Fehlermeldung, die ich im ACP finden konnte, ist folgende:
QuoteDisplay MoreFehlermeldung
Could not execute statement 'INSERT INTO wcf1_user_storage
(userID, field, fieldValue)
VALUES (?, ?, ?)'
Art
wcf\system\database\exception\DatabaseQueryExecutionException
Datei (Zeile)
/var/www/wcf/lib/system/database/statement/PreparedStatement.class.php (105)
Stacktrace
- /var/www/wcf/lib/system/user/storage/UserStorageHandler.class.php (295): wcf\system\database\statement\PreparedStatement->execute(…)
- /var/www/wcf/lib/system/WCF.class.php (211): wcf\system\user\storage\UserStorageHandler->shutdown(…)
- [internal function] (?): wcf\system\WCF::destruct(…)
Fehlermeldung
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails ("wsc5"."wcf1_user_storage", CONSTRAINT "dc6746bd1a1f4629ad6fcac43f4b24c1_fk" FOREIGN KEY ("userID") REFERENCES "wcf1_user" ("userID") ON DELETE CASCADE)
Nach einem bisschen Forschen habe ich herausgefunden, dass der Fehler nur mit dem oben zitierten Code-Schnipsel in Verbindung steht. Denn in der Funktion ConversationAction::markAsRead wird der User, für den die Konversation als gelesen markiert werden soll, nicht beim folgenden Funktionsaufruf übergeben:
$returnValues = [
'totalCount' => ConversationHandler::getInstance()->getUnreadConversationCount(null, true)
];
Dadurch wird die Anzahl nicht gelesener Konversationen des aktuellen Users (beim Cronjob also der User mit der ID 0) ermittelt:
public function getUnreadConversationCount($userID = null, $skipCache = false) {
if ($userID === null) $userID = WCF::getUser()->userID;
Dies führt dazu, dass weiter unten die Anzahl in den UserStorage aufgenommen wird. Später versucht das WCF den Storage in der Datenbank zu persistieren, schlägt aber fehlt, da es ja keinen User mit der ID 0 gibt.
Daher schlage ich vor, das null in Zeile 328 in ConversationAction.class.php zu $this->parameters['userID'] zu ändern. Dies behob den Fehler bei mir und führt meiner Einschätzung nach zu keinen unerwarteten Auswirkungen, da im Regelfall $this->parameters['userID'] == WCF::getUser()->userID gilt (Z. 252-254).
Viele Grüße