get(\TYPO3\CMS\Extbase\Configuration\ConfigurationManager::class); + $this->settings = $configurationManager->getConfiguration( \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS, 'karma' ); } /** * @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 * * @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 immutable cache. * @return int Immutable Karma Total */ public function getImmutableKarmaForUser(ExtbaseFrontendUser $frontendUser, $ignoreCache = false, $updateCacheEntry = true) { $frontendUser = $this->ensureCorrectFrontendUserSubclass($frontendUser); if (!$ignoreCache) { return $frontendUser->getKarmaImmutableValueCache(); } $immutableKarma = $this->ledgerEntryRepository->calculateImmutableKarmaTotalForUser($frontendUser); if ($updateCacheEntry) { $mutableKarma = $this->getMutableKarmaForUser($frontendUser, true, false); $frontendUser->setKarmaImmutableValueCache($immutableKarma); $frontendUser->setKarmaMutableValueCache($mutableKarma); $frontendUser->setKarmaCacheTimestamp(time()); $frontendUser->setKarmaSourceTotalCacheDecoded([]); $this->frontendUserRepository->update($frontendUser); } return $immutableKarma; } /** * Get the mutable karma total from the user * * @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 getMutableKarmaForUser(ExtbaseFrontendUser $frontendUser, $ignoreCache = false, $updateCacheEntry = true) { $frontendUser = $this->ensureCorrectFrontendUserSubclass($frontendUser); if (!$ignoreCache) { return $frontendUser->getKarmaMutableValueCache(); } $mutableKarma = $this->ledgerEntryRepository->calculateMutableKarmaTotalForUser($frontendUser); if ($updateCacheEntry) { $immutableKarma = $this->getImmutableKarmaForUser($frontendUser, true, false); $frontendUser->setKarmaMutableValueCache($mutableKarma); $frontendUser->setKarmaImmutableValueCache($immutableKarma); $frontendUser->setKarmaCacheTimestamp(time()); $frontendUser->setKarmaSourceTotalCacheDecoded([]); $this->frontendUserRepository->update($frontendUser); } return $mutableKarma; } /** * 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; } /** * Add karma to a user * * @param int $karmaValue to add to the user * @param ExtbaseFrontendUser $frontendUser to add the value to * @param string $karmaSource for the karma value * @param string $karmaIssuer code * @param string $karmaIssuerAction code */ public function addKarmaToUser(int $karmaValue, ExtbaseFrontendUser $frontendUser, string $karmaSource, string $karmaIssuer, string $karmaIssuerAction) { $frontendUser = $this->ensureCorrectFrontendUserSubclass($frontendUser); $ledgerEntry = new LedgerEntry(); $ledgerEntry->setImmutableValue($karmaValue); $ledgerEntry->setMutableValue($karmaValue); $ledgerEntry->setUser($frontendUser); $ledgerEntry->setKarmaSource($karmaSource); $ledgerEntry->setIssuer($karmaIssuer); $ledgerEntry->setIssuerAction($karmaIssuerAction); $this->ledgerEntryRepository->add($ledgerEntry); $frontendUser->setKarmaImmutableValueCache($frontendUser->getKarmaImmutableValueCache() + $karmaValue); $frontendUser->setKarmaMutableValueCache($frontendUser->getKarmaMutableValueCache() + $karmaValue); $frontendUser->setKarmaCacheTimestamp(time()); $this->frontendUserRepository->update($frontendUser); } /** * Trigger a karma-earning action for a user * * @param string $issuerCode The issuer code for the karma * @param string $issuerActionCode The issuer action code for the karma * @param ExtbaseFrontendUser $frontendUser The frontend user earning the karma * @throws \Exception If the $issuerCode, $issuerActionCode, or karma source code is not defined in TypoScript. */ public function triggerKarmaIssuerActionForUser($issuerCode, $issuerActionCode, ExtbaseFrontendUser $frontendUser) { if (!array_key_exists($issuerCode, $this->settings['issuers'])) { throw new \Exception('Issuer code "' . $issuerCode . '" does not exist.', 1549968187); } if (!array_key_exists($issuerActionCode, $this->settings['issuers'][$issuerCode])) { throw new \Exception('Issuer action code "' . $issuerActionCode . '" does not exist.', 1549968249); } $issuerActionSettings = $this->settings['issuers'][$issuerCode][$issuerActionCode]; $karmaSourceCode = $issuerActionSettings['sourceCode']; if ($karmaSourceCode === '') { throw new \Exception('Empty karma source code supplied. Please configure it in TypoScript.', 1541508560); } if (!array_key_exists($karmaSourceCode, $this->settings['sourceCodes'])) { throw new \Exception('Karma source code "' . $karmaSourceCode . '" does not exist.', 1549968362); } $this->addKarmaToUser( $issuerActionSettings['valueEarned'], $frontendUser, $karmaSourceCode, $issuerCode, $issuerActionCode ); } /** * Will take any FrontendUser object and return a karma extension FrontendUser subclass with the data we need * * @param ExtbaseFrontendUser $frontendUser * @return FrontendUser * @internal */ public function ensureCorrectFrontendUserSubclass(ExtbaseFrontendUser $frontendUser) { //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; } }