XF 2.1 MySQL query error [1062]: Duplicate entry

I'm trying to provide the user with a specific upgrade and it does work in giving the upgrade but upon execution of the following code, it will also give the duplicate entry error.

PHP:
        $upgradeFinder = \XF::finder('XF:UserUpgrade');
        $userUpgrade = $upgradeFinder->where('user_upgrade_id', '2')->fetchOne();

        $upgradeService = $this->app()->service('XF:User\Upgrade', $userUpgrade, $user);
        $upgradeService->setEndDate(0);
        $upgradeService->ignoreUnpurchasable(true);
        $upgradeService->upgrade();

PHP:
Server error log:
XF\Db\DuplicateKeyException: MySQL query error [1062]: Duplicate entry '1-2' for key 'user_id_upgrade_id'
src/XF/Db/AbstractStatement.php:228

PHP:
Stack trace:

INSERT  INTO `xf_user_upgrade_active` (`user_upgrade_id`, `user_id`, `start_date`, `extra`, `end_date`, `user_upgrade_record_id`, `purchase_request_key`, `notified_date`, `is_gift`, `pay_user_id`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
------------

#0 src/XF/Db/Mysqli/Statement.php(196): XF\Db\AbstractStatement->getException('MySQL query err...', 1062, '23000')
#1 src/XF/Db/Mysqli/Statement.php(77): XF\Db\Mysqli\Statement->getException('MySQL query err...', 1062, '23000')
#2 src/XF/Db/AbstractAdapter.php(94): XF\Db\Mysqli\Statement->execute()
#3 src/XF/Db/AbstractAdapter.php(218): XF\Db\AbstractAdapter->query('INSERT INTO `x...', Array)
#4 src/XF/Mvc/Entity/Entity.php(1463): XF\Db\AbstractAdapter->insert('xf_user_upgrade...', Array, false)
#5 src/XF/Mvc/Entity/Entity.php(1195): XF\Mvc\Entity\Entity->_saveToSource()
#6 src/XF/Service/User/Upgrade.php(170): XF\Mvc\Entity\Entity->save(true, false)
 
Not sure if thar upgrade service handles existing upgrades. Could be that the user you're trying to upgrade simply has that upgrade already (active or expired).


Small tip on the side:
Code:
$upgradeFinder = \XF::finder('XF:UserUpgrade');
$userUpgrade = $upgradeFinder->where('user_upgrade_id', '2')->fetchOne();

can be shortened to
Code:
$userUpgrade = \XF::em()->find('XF:UserUpgrade', 2);
 
Thank you Lukas! I was able to add a check if the user already has the upgrade and it all works just fine now. Will be leaving it below in case someone wanted something similar :)

PHP:
        $rewardId = 33;
        $userId = $user->user_id;
        $hasUpgrade = false;

        $userUpgradeActiveFinder = \XF::finder('XF:UserUpgradeActive');
        $activeUserUpgrades = $userUpgradeActiveFinder->where('user_id', $userId)->fetch();

        foreach ($activeUserUpgrades as &$activeUserUpgrade) {
            $upgradeId = $activeUserUpgrade->user_upgrade_id;
            if ($upgradeId == $rewardId)
                $hasUpgrade = true;
        }
    
        if ($hasUpgrade == true)
            return;
There is probably a smaller version for the above code but this has worked out for me.
 
Top Bottom