KarmaService.php 7.6 KB
Newer Older
1
2
3
4
5
<?php

namespace T3o\Karma\Service;

use T3o\Karma\Domain\Model\FrontendUser;
6
use T3o\Karma\Domain\Model\LedgerEntry;
7
8
use T3o\Karma\Domain\Repository\FrontendUserRepository;
use T3o\Karma\Domain\Repository\LedgerEntryRepository;
9
use TYPO3\CMS\Extbase\Domain\Model\FrontendUser as ExtbaseFrontendUser;
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

/***************************************************************
 *  Copyright notice
 *
 *  (c) 2018
 *  All rights reserved
 *
 *  This script is part of the TYPO3 project. The TYPO3 project is
 *  free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  The GNU General Public License can be found at
 *  http://www.gnu.org/copyleft/gpl.html.
 *
 *  This script is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  This copyright notice MUST APPEAR in all copies of the script!
 ***************************************************************/

class KarmaService implements \TYPO3\CMS\Core\SingletonInterface
{
    /**
     * @var LedgerEntryRepository
     */
    protected $ledgerEntryRepository;

    /**
     * @var FrontendUserRepository
     */
    protected $frontendUserRepository;

    /**
     * @param LedgerEntryRepository $ledgerEntryRepository
     */
    public function injectLedgerEntryRepository(LedgerEntryRepository $ledgerEntryRepository)
    {
        $this->ledgerEntryRepository = $ledgerEntryRepository;
    }

    /**
     * @param FrontendUserRepository $frontendUserRepository
     */
    public function injectFrontendUserRepository(FrontendUserRepository $frontendUserRepository)
    {
        $this->frontendUserRepository = $frontendUserRepository;
    }

    /**
     * Get the imimmutable karma total from the user
     *
65
     * @param ExtbaseFrontendUser $frontendUser
66
67
68
69
     * @param bool $ignoreCache Fetch value directly from ledger
     * @param bool $updateCacheEntry Update the user's cache entry if we're ignoring cache. Will also update immutable cache.
     * @return int Immutable Karma Total
     */
70
    public function getImmutableKarmaForUser(ExtbaseFrontendUser $frontendUser, $ignoreCache = false, $updateCacheEntry = true)
71
72
73
74
    {
        $frontendUser = $this->ensureCorrectFrontendUserSubclass($frontendUser);

        if (!$ignoreCache) {
75
            return $frontendUser->getKarmaImmutableValueCache();
76
77
78
79
        }

        $immutableKarma = $this->ledgerEntryRepository->calculateImmutableKarmaTotalForUser($frontendUser);

mabolek's avatar
mabolek committed
80
        if ($updateCacheEntry) {
81
            $mutableKarma = $this->getMutableKarmaForUser($frontendUser, true, false);
82

83
            $frontendUser->setKarmaImmutableValueCache($immutableKarma);
84
            $frontendUser->setKarmaMutableValueCache($mutableKarma);
85
            $frontendUser->setKarmaCacheTimestamp(time());
86
            $frontendUser->setKarmaSourceTotalCacheDecoded([]);
87
88
89
90
91
92
93
94
95
96

            $this->frontendUserRepository->update($frontendUser);
        }

        return $immutableKarma;
    }

    /**
     * Get the mutable karma total from the user
     *
97
     * @param ExtbaseFrontendUser $frontendUser
98
99
100
101
     * @param bool $ignoreCache Fetch value directly from ledger
     * @param bool $updateCacheEntry Update the user's cache entry if we're ignoring cache. Will also update mutable cache.
     * @return int Mutable Karma Total
     */
102
    public function getMutableKarmaForUser(ExtbaseFrontendUser $frontendUser, $ignoreCache = false, $updateCacheEntry = true)
103
104
105
106
    {
        $frontendUser = $this->ensureCorrectFrontendUserSubclass($frontendUser);

        if (!$ignoreCache) {
107
            return $frontendUser->getKarmaMutableValueCache();
108
109
110
111
        }

        $mutableKarma = $this->ledgerEntryRepository->calculateMutableKarmaTotalForUser($frontendUser);

mabolek's avatar
mabolek committed
112
        if ($updateCacheEntry) {
113
            $immutableKarma = $this->getImmutableKarmaForUser($frontendUser, true, false);
114

115
            $frontendUser->setKarmaMutableValueCache($mutableKarma);
116
            $frontendUser->setKarmaImmutableValueCache($immutableKarma);
117
            $frontendUser->setKarmaCacheTimestamp(time());
118
            $frontendUser->setKarmaSourceTotalCacheDecoded([]);
119
120
121
122
123
124
125

            $this->frontendUserRepository->update($frontendUser);
        }

        return $mutableKarma;
    }

126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
    /**
     * Get the immutable karma total for a specific karma source code from the user
     *
     * @param string $karmaSourceCode The source code to fetch the total for
     * @param ExtbaseFrontendUser $frontendUser
     * @param bool $ignoreCache Fetch value directly from ledger
     * @param bool $updateCacheEntry Update the user's cache entry if we're ignoring cache. Will also update mutable cache.
     * @return int Mutable Karma Total
     */
    public function getImmutableKarmaSourceTotalForUser($karmaSourceCode, ExtbaseFrontendUser $frontendUser, $ignoreCache = false, $updateCacheEntry = true)
    {
        $frontendUser = $this->ensureCorrectFrontendUserSubclass($frontendUser);

        $totals = $frontendUser->getKarmaSourceTotalCacheDecoded();
        if (!$ignoreCache) {
            if (isset($totals[$karmaSourceCode])) {
                return $totals[$karmaSourceCode];
            }
        }

        $sourceTotal = $this->ledgerEntryRepository->calculateImmutableKarmaSourceTotalForUser($karmaSourceCode, $frontendUser);

        if ($updateCacheEntry) {
            $totals[$karmaSourceCode] = $sourceTotal;
            $frontendUser->setKarmaSourceTotalCacheDecoded($totals);

            $this->frontendUserRepository->update($frontendUser);
        }

        return $sourceTotal;
    }

158
159
160
161
162
    /**
     * Add karma to a user
     *
     * @param int $karmaValue to add to the user
     * @param ExtbaseFrontendUser $frontendUser to add the value to
163
     * @param string $karmaSource for the karma value
164
165
     * @param string $karmaIssuer code
     * @param string $karmaIssuerAction code
166
     */
167
    public function addKarmaToUser(int $karmaValue, ExtbaseFrontendUser $frontendUser, string $karmaSource, string $karmaIssuer, string $karmaIssuerAction)
168
169
170
171
172
173
174
175
176
    {
        $frontendUser = $this->ensureCorrectFrontendUserSubclass($frontendUser);

        $ledgerEntry = new LedgerEntry();

        $ledgerEntry->setImmutableValue($karmaValue);
        $ledgerEntry->setMutableValue($karmaValue);
        $ledgerEntry->setUser($frontendUser);
        $ledgerEntry->setKarmaSource($karmaSource);
177
178
        $ledgerEntry->setIssuer($karmaIssuer);
        $ledgerEntry->setIssuerAction($karmaIssuerAction);
179
180
181
182
183
184
185
186
187

        $this->ledgerEntryRepository->add($ledgerEntry);

        $frontendUser->setKarmaImmutableValueCache($frontendUser->getKarmaImmutableValueCache() + $karmaValue);
        $frontendUser->setKarmaMutableValueCache($frontendUser->getKarmaMutableValueCache() + $karmaValue);
        $frontendUser->setKarmaCacheTimestamp(time());
        $this->frontendUserRepository->update($frontendUser);
    }

188
189
190
    /**
     * Will take any FrontendUser object and return a karma extension FrontendUser subclass with the data we need
     *
191
     * @param ExtbaseFrontendUser $frontendUser
192
193
194
     * @return FrontendUser
     * @internal
     */
195
    public function ensureCorrectFrontendUserSubclass(ExtbaseFrontendUser $frontendUser)
mabolek's avatar
mabolek committed
196
    {
197
198
199
200
201
202
203
204
        //If user is not an instance of our own frontend user class we have to fetch it again
        if (!($frontendUser instanceof FrontendUser)) {
            $frontendUser = $this->frontendUserRepository->findByUid($frontendUser->getUid());
        }

        return $frontendUser;
    }
}