Skip to content

Commit fa92fb1

Browse files
committed
Avoid race conditions when saving reactions and reaction objects
1 parent 026b20a commit fa92fb1

File tree

1 file changed

+42
-25
lines changed

1 file changed

+42
-25
lines changed

wcfsetup/install/files/lib/system/reaction/ReactionHandler.class.php

Lines changed: 42 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -337,19 +337,26 @@ public function react(ILikeObject $likeable, User $user, $reactionTypeID, $time
337337

338338
if (!$like->likeID) {
339339
// save like
340-
$returnValues = (new ReactionAction([], 'create', [
341-
'data' => [
342-
'objectID' => $likeable->getObjectID(),
343-
'objectTypeID' => $likeable->getObjectType()->objectTypeID,
344-
'objectUserID' => $likeable->getUserID() ?: null,
345-
'userID' => $user->userID,
346-
'time' => $time,
347-
'likeValue' => 1,
348-
'reactionTypeID' => $reactionTypeID,
349-
],
350-
]))->executeAction();
351-
352-
$like = $returnValues['returnValues'];
340+
$sql = "INSERT INTO wcf1_like
341+
(objectID, objectTypeID, objectUserID, userID, time, likeValue, reactionTypeID)
342+
VALUES (?, ?, ?, ?, ?, ?, ?)
343+
ON DUPLICATE KEY UPDATE time = ?,
344+
likeValue = ?,
345+
reactionTypeID = ?";
346+
$statement = WCF::getDB()->prepare($sql);
347+
$statement->execute([
348+
$likeable->getObjectID(),
349+
$likeable->getObjectType()->objectTypeID,
350+
$likeable->getUserID() ?: null,
351+
$user->userID,
352+
$time,
353+
1,
354+
$reactionTypeID,
355+
$time,
356+
1,
357+
$reactionTypeID,
358+
]);
359+
$like = new Like(WCF::getDB()->getInsertID("wcf1_like", "likeID"));
353360

354361
if ($likeable->getUserID()) {
355362
UserActivityPointHandler::getInstance()->fireEvent(
@@ -503,18 +510,28 @@ private function updateLikeObject(
503510
];
504511

505512
// create cache
506-
$likeObjectActionReturnValues = (new LikeObjectAction([], 'create', [
507-
'data' => [
508-
'objectTypeID' => $likeable->getObjectType()->objectTypeID,
509-
'objectID' => $likeable->getObjectID(),
510-
'objectUserID' => $likeable->getUserID() ?: null,
511-
'likes' => $cumulativeLikes,
512-
'dislikes' => 0,
513-
'cumulativeLikes' => $cumulativeLikes,
514-
'cachedReactions' => \serialize($cachedReactions),
515-
],
516-
]))->executeAction();
517-
$likeObject = $likeObjectActionReturnValues['returnValues'];
513+
$sql = "INSERT INTO wcf1_like_object
514+
(objectTypeID, objectID, objectUserID, likes, dislikes, cumulativeLikes, cachedReactions)
515+
VALUES (?, ?, ?, ?, ?, ?, ?)
516+
ON DUPLICATE KEY UPDATE likes = ?,
517+
dislikes = ?,
518+
cumulativeLikes = ?,
519+
cachedReactions = ?";
520+
$statement = WCF::getDB()->prepare($sql);
521+
$statement->execute([
522+
$likeable->getObjectType()->objectTypeID,
523+
$likeable->getObjectID(),
524+
$likeable->getUserID() ?: null,
525+
$cumulativeLikes,
526+
0,
527+
$cumulativeLikes,
528+
\serialize($cachedReactions),
529+
$cumulativeLikes,
530+
0,
531+
$cumulativeLikes,
532+
\serialize($cachedReactions),
533+
]);
534+
$likeObject = new LikeObject(WCF::getDB()->getInsertID("wcf1_like_object", "likeObjectID"));
518535
}
519536

520537
return [

0 commit comments

Comments
 (0)