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

namespace T3o\Karma\Service;

5
use T3o\Karma\Domain\Model\Campaign;
6
use T3o\Karma\Domain\Model\FrontendUser;
7
8
use T3o\Karma\Domain\Model\KarmaSource;
use T3o\Karma\Domain\Model\LedgerEntry;
9
use T3o\Karma\Domain\Repository\FrontendUserRepository;
10
use T3o\Karma\Domain\Repository\KarmaSourceRepository;
11
use T3o\Karma\Domain\Repository\LedgerEntryRepository;
12
use TYPO3\CMS\Extbase\Domain\Model\FrontendUser as ExtbaseFrontendUser;
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

/***************************************************************
 *  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;

49
50
51
52
53
    /**
     * @var \T3o\Karma\Domain\Repository\KarmaSourceRepository
     */
    protected $karmaSourceRepository;

54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
    /**
     * @param LedgerEntryRepository $ledgerEntryRepository
     */
    public function injectLedgerEntryRepository(LedgerEntryRepository $ledgerEntryRepository)
    {
        $this->ledgerEntryRepository = $ledgerEntryRepository;
    }

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

70
71
72
    /**
     * @param KarmaSourceRepository $karmaSourceRepository
     */
mabolek's avatar
mabolek committed
73
74
    public function injectKarmaSourceRepository(KarmaSourceRepository $karmaSourceRepository)
    {
75
76
77
        $this->karmaSourceRepository = $karmaSourceRepository;
    }

78
79
80
    /**
     * Get the imimmutable karma total from the user
     *
81
     * @param ExtbaseFrontendUser $frontendUser
82
83
84
85
     * @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
     */
86
    public function getImmutableKarmaForUser(ExtbaseFrontendUser $frontendUser, $ignoreCache = false, $updateCacheEntry = true)
87
88
89
90
    {
        $frontendUser = $this->ensureCorrectFrontendUserSubclass($frontendUser);

        if (!$ignoreCache) {
91
            return $frontendUser->getKarmaImmutableValueCache();
92
93
94
95
        }

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

mabolek's avatar
mabolek committed
96
        if ($updateCacheEntry) {
97
            $mutableKarma = $this->getMutableKarmaForUser($frontendUser, true, false);
98

99
            $frontendUser->setKarmaImmutableValueCache($immutableKarma);
100
            $frontendUser->setKarmaMutableValueCache($mutableKarma);
101
102
103
104
105
106
107
108
109
110
111
            $frontendUser->setKarmaCacheTimestamp(time());

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

        return $immutableKarma;
    }

    /**
     * Get the mutable karma total from the user
     *
112
     * @param ExtbaseFrontendUser $frontendUser
113
114
115
116
     * @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
     */
117
    public function getMutableKarmaForUser(ExtbaseFrontendUser $frontendUser, $ignoreCache = false, $updateCacheEntry = true)
118
119
120
121
    {
        $frontendUser = $this->ensureCorrectFrontendUserSubclass($frontendUser);

        if (!$ignoreCache) {
122
            return $frontendUser->getKarmaMutableValueCache();
123
124
125
126
        }

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

mabolek's avatar
mabolek committed
127
        if ($updateCacheEntry) {
128
            $immutableKarma = $this->getImmutableKarmaForUser($frontendUser, true, false);
129

130
            $frontendUser->setKarmaMutableValueCache($mutableKarma);
131
            $frontendUser->setKarmaImmutableValueCache($immutableKarma);
132
133
134
135
136
137
138
139
            $frontendUser->setKarmaCacheTimestamp(time());

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

        return $mutableKarma;
    }

140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
    /**
     * Add karma to a user
     *
     * @param int $karmaValue to add to the user
     * @param ExtbaseFrontendUser $frontendUser to add the value to
     * @param KarmaSource $karmaSource for the karma value
     * @param Campaign $campaign for the value (optional)
     */
    public function addKarmaToUser(int $karmaValue, ExtbaseFrontendUser $frontendUser, KarmaSource $karmaSource, Campaign $campaign = null)
    {
        $frontendUser = $this->ensureCorrectFrontendUserSubclass($frontendUser);

        $ledgerEntry = new LedgerEntry();

        $ledgerEntry->setImmutableValue($karmaValue);
        $ledgerEntry->setMutableValue($karmaValue);
        $ledgerEntry->setUser($frontendUser);
        $ledgerEntry->setKarmaSource($karmaSource);
        if ($campaign !== null) {
            $ledgerEntry->setCampaign($campaign);
        }

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

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

170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
    /**
     * Get a Karma Source object. Will generate a new object with code and label if none exists.
     *
     * @param string $sourceCode
     * @param string $defaultLabel
     * @return KarmaSource
     * @throws \Exception when $sourceCode is an empty string
     */
    public function getKarmaSourceByCode(string $sourceCode, $defaultLabel='[No Label Set]')
    {
        if ($sourceCode == '') {
            throw new \Exception('Empty karma source code supplied.', 1541508560);
        }

        $karmaSource = $this->karmaSourceRepository->findByCode($sourceCode)->getFirst();

        if ($karmaSource === null) {
            /** @var KarmaSource $karmaSource */
            $karmaSource = new KarmaSource();
            $karmaSource->setCode($karmaSourceCode);
            $karmaSource->setTitle($defaultLabel);

            $this->karmaSourceRepository->add($karmaSource);
        }

        return $karmaSource;
    }

198
199
200
    /**
     * Will take any FrontendUser object and return a karma extension FrontendUser subclass with the data we need
     *
201
     * @param ExtbaseFrontendUser $frontendUser
202
203
204
     * @return FrontendUser
     * @internal
     */
205
    public function ensureCorrectFrontendUserSubclass(ExtbaseFrontendUser $frontendUser)
mabolek's avatar
mabolek committed
206
    {
207
208
209
210
211
212
213
214
        //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;
    }
}