721 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			721 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						||
 | 
						||
/*
 | 
						||
 * This file is part of the package thucke/th-rating.
 | 
						||
 *
 | 
						||
 * For the full copyright and license information, please read the
 | 
						||
 * LICENSE file that was distributed with this source code.
 | 
						||
 */
 | 
						||
 | 
						||
/** @noinspection PhpFullyQualifiedNameUsageInspection */
 | 
						||
namespace WapplerSystems\BookmarksLikesRatings\Service;
 | 
						||
 | 
						||
use Psr\Http\Message\ServerRequestInterface;
 | 
						||
use WapplerSystems\BookmarksLikesRatings\Domain\Model\Rating;
 | 
						||
use WapplerSystems\BookmarksLikesRatings\Domain\Model\RatingImage;
 | 
						||
use WapplerSystems\BookmarksLikesRatings\Domain\Model\Ratingobject;
 | 
						||
use WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepconf;
 | 
						||
use WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepname;
 | 
						||
use WapplerSystems\BookmarksLikesRatings\Domain\Model\Vote;
 | 
						||
use WapplerSystems\BookmarksLikesRatings\Domain\Repository\RatingobjectRepository;
 | 
						||
use WapplerSystems\BookmarksLikesRatings\Domain\Repository\RatingRepository;
 | 
						||
use WapplerSystems\BookmarksLikesRatings\Domain\Repository\StepnameRepository;
 | 
						||
use WapplerSystems\BookmarksLikesRatings\Domain\Repository\VoteRepository;
 | 
						||
use WapplerSystems\BookmarksLikesRatings\Domain\Validator\RatingobjectValidator;
 | 
						||
use WapplerSystems\BookmarksLikesRatings\Domain\Validator\RatingValidator;
 | 
						||
use WapplerSystems\BookmarksLikesRatings\Domain\Validator\StepconfValidator;
 | 
						||
use WapplerSystems\BookmarksLikesRatings\Domain\Validator\VoteValidator;
 | 
						||
use WapplerSystems\BookmarksLikesRatings\Evaluation\DynamicCssEvaluator;
 | 
						||
use WapplerSystems\BookmarksLikesRatings\Exception\LanguageNotFoundException;
 | 
						||
use TYPO3\CMS\Core\Core\Environment;
 | 
						||
use TYPO3\CMS\Core\Log\Logger;
 | 
						||
use TYPO3\CMS\Core\Log\LogLevel;
 | 
						||
use TYPO3\CMS\Core\Site\Entity\Site;
 | 
						||
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
 | 
						||
use TYPO3\CMS\Core\Site\SiteFinder;
 | 
						||
use TYPO3\CMS\Core\Utility\ArrayUtility;
 | 
						||
use TYPO3\CMS\Core\Utility\GeneralUtility;
 | 
						||
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
 | 
						||
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
 | 
						||
use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager;
 | 
						||
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
 | 
						||
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
 | 
						||
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
 | 
						||
 | 
						||
/**
 | 
						||
 * Factory for model objects
 | 
						||
 *
 | 
						||
 * @version $Id:$
 | 
						||
 * @license http://opensource.org/licenses/gpl-license.php GNU protected License, version 2
 | 
						||
 */
 | 
						||
class ExtensionHelperService extends AbstractExtensionService
 | 
						||
{
 | 
						||
    protected const DYN_CSS_FILENAME = 'typo3temp/thratingDyn.css';
 | 
						||
 | 
						||
    /**
 | 
						||
     * The current request.
 | 
						||
     *
 | 
						||
     * @var \TYPO3\CMS\Extbase\Mvc\Request
 | 
						||
     */
 | 
						||
    protected $request;
 | 
						||
 | 
						||
    /**
 | 
						||
     * @var \WapplerSystems\BookmarksLikesRatings\Domain\Repository\RatingobjectRepository
 | 
						||
     */
 | 
						||
    protected $ratingobjectRepository;
 | 
						||
 | 
						||
    /**
 | 
						||
     * @param \WapplerSystems\BookmarksLikesRatings\Domain\Repository\RatingobjectRepository $ratingobjectRepository
 | 
						||
     */
 | 
						||
    public function injectRatingobjectRepository(RatingobjectRepository $ratingobjectRepository): void
 | 
						||
    {
 | 
						||
        $this->ratingobjectRepository = $ratingobjectRepository;
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * @var \WapplerSystems\BookmarksLikesRatings\Domain\Repository\RatingRepository
 | 
						||
     */
 | 
						||
    protected $ratingRepository;
 | 
						||
    /**
 | 
						||
     * @param \WapplerSystems\BookmarksLikesRatings\Domain\Repository\RatingRepository $ratingRepository
 | 
						||
     */
 | 
						||
    public function injectRatingRepository(RatingRepository $ratingRepository): void
 | 
						||
    {
 | 
						||
        $this->ratingRepository = $ratingRepository;
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * @var \WapplerSystems\BookmarksLikesRatings\Domain\Repository\StepnameRepository
 | 
						||
     */
 | 
						||
    protected $stepnameRepository;
 | 
						||
    /**
 | 
						||
     * @param \WapplerSystems\BookmarksLikesRatings\Domain\Repository\StepnameRepository $stepnameRepository
 | 
						||
     */
 | 
						||
    public function injectStepnameRepository(StepnameRepository $stepnameRepository): void
 | 
						||
    {
 | 
						||
        $this->stepnameRepository = $stepnameRepository;
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * @var \WapplerSystems\BookmarksLikesRatings\Domain\Repository\VoteRepository
 | 
						||
     */
 | 
						||
    protected $voteRepository;
 | 
						||
    /**
 | 
						||
     * @param \WapplerSystems\BookmarksLikesRatings\Domain\Repository\VoteRepository $voteRepository
 | 
						||
     */
 | 
						||
    public function injectVoteRepository(VoteRepository $voteRepository): void
 | 
						||
    {
 | 
						||
        $this->voteRepository = $voteRepository;
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * @var \WapplerSystems\BookmarksLikesRatings\Service\AccessControlService
 | 
						||
     */
 | 
						||
    protected $accessControllService;
 | 
						||
    /**
 | 
						||
     * @param AccessControlService $accessControllService
 | 
						||
     */
 | 
						||
    public function injectAccessControlService(AccessControlService $accessControllService): void
 | 
						||
    {
 | 
						||
        $this->accessControllService = $accessControllService;
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * @var \WapplerSystems\BookmarksLikesRatings\Domain\Validator\StepconfValidator
 | 
						||
     */
 | 
						||
    protected $stepconfValidator;
 | 
						||
    /**
 | 
						||
     * @param \WapplerSystems\BookmarksLikesRatings\Domain\Validator\StepconfValidator $stepconfValidator
 | 
						||
     */
 | 
						||
    public function injectStepconfValidator(StepconfValidator $stepconfValidator): void
 | 
						||
    {
 | 
						||
        $this->stepconfValidator = $stepconfValidator;
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * @var \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface
 | 
						||
     */
 | 
						||
    protected $configurationManager;
 | 
						||
    /**
 | 
						||
     * @param \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface $configurationManager
 | 
						||
     */
 | 
						||
    public function injectConfigurationManager(ConfigurationManagerInterface $configurationManager): void
 | 
						||
    {
 | 
						||
        $this->configurationManager = $configurationManager;
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * Contains the settings of the current extension
 | 
						||
     *
 | 
						||
     * @var array
 | 
						||
     */
 | 
						||
    protected $settings;
 | 
						||
    /**
 | 
						||
     * @var \WapplerSystems\BookmarksLikesRatings\Domain\Model\RatingImage
 | 
						||
     */
 | 
						||
    protected $ratingImage;
 | 
						||
 | 
						||
    /**
 | 
						||
     * @var \TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface
 | 
						||
     */
 | 
						||
    protected $extDefaultQuerySettings;
 | 
						||
 | 
						||
    /**
 | 
						||
     * Constructor
 | 
						||
     */
 | 
						||
    public function initializeObject(): void
 | 
						||
    {
 | 
						||
        $this->settings = $this->configurationManager->getConfiguration(
 | 
						||
            ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS,
 | 
						||
            'thrating',
 | 
						||
            'pi1'
 | 
						||
        );
 | 
						||
 | 
						||
        $frameworkConfiguration = $this->configurationManager->getConfiguration(
 | 
						||
            ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK,
 | 
						||
            'thrating',
 | 
						||
            'pi1'
 | 
						||
        );
 | 
						||
        if (!empty($frameworkConfiguration['ratings'])) {
 | 
						||
            //Merge extension ratingConfigurations with customer added ones
 | 
						||
            ArrayUtility::mergeRecursiveWithOverrule(
 | 
						||
                $this->settings['ratingConfigurations'],
 | 
						||
                $frameworkConfiguration['ratings']
 | 
						||
            );
 | 
						||
        }
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * @return \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController
 | 
						||
     */
 | 
						||
    protected function getTypoScriptFrontendController(): TypoScriptFrontendController
 | 
						||
    {
 | 
						||
        global $TSFE;
 | 
						||
 | 
						||
        return $TSFE;
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * Returns the completed settings array
 | 
						||
     *
 | 
						||
     * @param array $settings
 | 
						||
     * @return array
 | 
						||
     */
 | 
						||
    private function completeConfigurationSettings(array $settings): array
 | 
						||
    {
 | 
						||
        $cObj = $this->configurationManager->getContentObject();
 | 
						||
 | 
						||
        if (!empty($cObj->currentRecord)) {
 | 
						||
            /* build array [0=>cObj tablename, 1=> cObj uid] - initialize with content information
 | 
						||
             (usage as normal content) */
 | 
						||
            $currentRecord = explode(':', $cObj->currentRecord);
 | 
						||
        } else {
 | 
						||
            //build array [0=>cObj tablename, 1=> cObj uid] - initialize with page info if used by typoscript
 | 
						||
            $currentRecord = ['pages', $GLOBALS['TSFE']->page['uid']];
 | 
						||
        }
 | 
						||
 | 
						||
        if (empty($settings['ratetable'])) {
 | 
						||
            $settings['ratetable'] = $currentRecord[0];
 | 
						||
        }
 | 
						||
        if (empty($settings['ratefield'])) {
 | 
						||
            $settings['ratefield'] = 'uid';
 | 
						||
        }
 | 
						||
        if (empty($settings['ratedobjectuid'])) {
 | 
						||
            $settings['ratedobjectuid'] = $currentRecord[1];
 | 
						||
        }
 | 
						||
        return $settings;
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * Returns a new or existing ratingobject
 | 
						||
     *
 | 
						||
     * @param array $settings
 | 
						||
     * @throws \WapplerSystems\BookmarksLikesRatings\Exception\RecordNotFoundException
 | 
						||
     * @throws \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException
 | 
						||
     * @return \WapplerSystems\BookmarksLikesRatings\Domain\Model\Ratingobject
 | 
						||
     */
 | 
						||
    public function getRatingobject(array $settings): Ratingobject
 | 
						||
    {
 | 
						||
        $ratingobject = null;
 | 
						||
 | 
						||
        //check whether a dedicated ratingobject is configured
 | 
						||
        if (!empty($settings['ratingobject'])) {
 | 
						||
            $ratingobject = $this->ratingobjectRepository->findByUid($settings['ratingobject']);
 | 
						||
        } else {
 | 
						||
            if (empty($settings['ratetable']) || empty($settings['ratefield'])) {
 | 
						||
                //fallback to default configuration
 | 
						||
                $settings = $settings['defaultObject'] + $settings;
 | 
						||
            }
 | 
						||
            $settings = $this->completeConfigurationSettings($settings);
 | 
						||
            $ratingobject = $this->ratingobjectRepository->findMatchingTableAndField(
 | 
						||
                $settings['ratetable'],
 | 
						||
                $settings['ratefield'],
 | 
						||
                RatingobjectRepository::ADD_IF_NOT_FOUND
 | 
						||
            );
 | 
						||
        }
 | 
						||
        return $ratingobject;
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * Returns a new or existing ratingobject
 | 
						||
     *
 | 
						||
     * @param array $stepconfArray
 | 
						||
     * @return \WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepconf
 | 
						||
     */
 | 
						||
    public function createStepconf(array $stepconfArray): Stepconf
 | 
						||
    {
 | 
						||
        /** @var \WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepconf $stepconf */
 | 
						||
        $stepconf = $this->objectManager->get(Stepconf::class);
 | 
						||
        $stepconf->setRatingobject($stepconfArray['ratingobject']);
 | 
						||
        $stepconf->setSteporder($stepconfArray['steporder']);
 | 
						||
        $stepconf->setStepweight($stepconfArray['stepweight']);
 | 
						||
 | 
						||
        return $stepconf;
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * Returns a new or existing ratingobject
 | 
						||
     *
 | 
						||
     * @param Stepconf $stepconf
 | 
						||
     * @param array $stepnameArray
 | 
						||
     * @return  \WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepname
 | 
						||
     * @throws LanguageNotFoundException
 | 
						||
     * @throws \TYPO3\CMS\Core\Exception\SiteNotFoundException
 | 
						||
     * @throws \TYPO3\CMS\Extbase\Persistence\Exception\InvalidQueryException
 | 
						||
     */
 | 
						||
    public function createStepname(Stepconf $stepconf, array $stepnameArray): Stepname
 | 
						||
    {
 | 
						||
        /** @var \WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepname $stepname */
 | 
						||
        $stepname = $this->objectManager->get(Stepname::class);
 | 
						||
        $stepname->setStepconf($stepconf);
 | 
						||
        $stepname->setStepname($stepnameArray['stepname']);
 | 
						||
        $stepname->setPid($stepnameArray['pid']);
 | 
						||
        $stepname->setSysLanguageUid(
 | 
						||
            $this->getStaticLanguageByIsoCode(
 | 
						||
                $stepname->getPid(),
 | 
						||
                $stepnameArray['twoLetterIsoCode'] ?: null
 | 
						||
            )->getLanguageId()
 | 
						||
        );
 | 
						||
 | 
						||
        $defaultStepname = $this->stepnameRepository->findDefaultStepname($stepname);
 | 
						||
        $l18nParent = is_null($defaultStepname) ? 0 : $defaultStepname->getUid();
 | 
						||
        $stepname->setL18nParent($l18nParent);
 | 
						||
        return $stepname;
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * Returns a new or existing rating
 | 
						||
     *
 | 
						||
     * @param array $settings
 | 
						||
     * @param \WapplerSystems\BookmarksLikesRatings\Domain\Model\Ratingobject|null $ratingobject
 | 
						||
     * @return \WapplerSystems\BookmarksLikesRatings\Domain\Model\Rating
 | 
						||
     * @throws \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException
 | 
						||
     * @throws \WapplerSystems\BookmarksLikesRatings\Service\Exception
 | 
						||
     */
 | 
						||
    public function getRating(array $settings, ?Ratingobject $ratingobject): Rating
 | 
						||
    {
 | 
						||
        $settings = $this->completeConfigurationSettings($settings);
 | 
						||
        if (!empty($settings['rating'])) {
 | 
						||
            //fetch rating when it is configured
 | 
						||
            $rating = $this->ratingRepository->findByUid($settings['rating']);
 | 
						||
        } elseif ($settings['ratedobjectuid'] && !$this->objectManager->get(RatingobjectValidator::class)
 | 
						||
                ->validate($ratingobject)->hasErrors()) {
 | 
						||
            //get rating according to given row
 | 
						||
            /** @noinspection NullPointerExceptionInspection */
 | 
						||
            $rating = $this->ratingRepository->findMatchingObjectAndUid(
 | 
						||
                $ratingobject,
 | 
						||
                $settings['ratedobjectuid'],
 | 
						||
                RatingRepository::ADD_IF_NOT_FOUND
 | 
						||
            );
 | 
						||
        } else {
 | 
						||
            throw new \WapplerSystems\BookmarksLikesRatings\Service\Exception(
 | 
						||
                'Incomplete configuration setting. Either \'rating\' or \'ratedobjectuid\' are missing.',
 | 
						||
                1398351336
 | 
						||
            );
 | 
						||
        }
 | 
						||
        return $rating;
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * Returns a new or existing vote
 | 
						||
     *
 | 
						||
     * @param string $prefixId
 | 
						||
     * @param array $settings
 | 
						||
     * @param \WapplerSystems\BookmarksLikesRatings\Domain\Model\Rating $rating
 | 
						||
     * @return \WapplerSystems\BookmarksLikesRatings\Domain\Model\Vote
 | 
						||
     * @throws \WapplerSystems\BookmarksLikesRatings\Exception\FeUserNotFoundException
 | 
						||
     */
 | 
						||
    public function getVote(string $prefixId, array $settings, Rating $rating): Vote
 | 
						||
    {
 | 
						||
        // initialize variables
 | 
						||
        /** @var \WapplerSystems\BookmarksLikesRatings\Domain\Model\Vote $vote */
 | 
						||
        $vote = null;
 | 
						||
        /** @var \WapplerSystems\BookmarksLikesRatings\Domain\Model\Voter $voter */
 | 
						||
        $voter = null;
 | 
						||
 | 
						||
        //first fetch real voter or anonymous
 | 
						||
        /** @var int $frontendUserUid */
 | 
						||
        $frontendUserUid = $this->accessControllService->getFrontendUserUid();
 | 
						||
        if (!$frontendUserUid && !empty($settings['mapAnonymous'])) {
 | 
						||
            //set anonymous vote
 | 
						||
            $voter = $this->accessControllService->getFrontendVoter($settings['mapAnonymous']);
 | 
						||
            $anonymousRating = GeneralUtility::makeInstance(\WapplerSystems\BookmarksLikesRatings\Service\JsonService::class)
 | 
						||
                ->decodeJsonToArray($_COOKIE[$prefixId . '_AnonymousRating_' . $rating->getUid()]);
 | 
						||
            if (!empty($anonymousRating['voteUid'])) {
 | 
						||
                $vote = $this->voteRepository->findByUid($anonymousRating['voteUid']);
 | 
						||
            }
 | 
						||
        } elseif ($frontendUserUid) {
 | 
						||
            //set FEUser if one is logged on
 | 
						||
            $voter = $this->accessControllService->getFrontendVoter($frontendUserUid);
 | 
						||
            if ($voter instanceof \WapplerSystems\BookmarksLikesRatings\Domain\Model\Voter) {
 | 
						||
                $vote = $this->voteRepository->findMatchingRatingAndVoter($rating, $voter);
 | 
						||
            }
 | 
						||
        }
 | 
						||
        //voting not found in database or anonymous vote? - create new one
 | 
						||
        $voteValidator = $this->objectManager->get(VoteValidator::class);
 | 
						||
        if ($voteValidator->validate($vote)->hasErrors()) {
 | 
						||
            $vote = $this->objectManager->get(Vote::class);
 | 
						||
            $ratingValidator = $this->objectManager->get(RatingValidator::class);
 | 
						||
            if (!$ratingValidator->validate($rating)->hasErrors()) {
 | 
						||
                $vote->setRating($rating);
 | 
						||
            }
 | 
						||
            if ($voter instanceof \WapplerSystems\BookmarksLikesRatings\Domain\Model\Voter) {
 | 
						||
                $vote->setVoter($voter);
 | 
						||
            }
 | 
						||
        }
 | 
						||
 | 
						||
        return $vote;
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * Get a logger instance
 | 
						||
     * The configuration of the logger is modified by extension typoscript config
 | 
						||
     *
 | 
						||
     * @param string|null $name the class name which this logger is for
 | 
						||
     * @return  \TYPO3\CMS\Core\Log\Logger
 | 
						||
     */
 | 
						||
    public function getLogger(?string $name): Logger
 | 
						||
    {
 | 
						||
        if (empty($name)) {
 | 
						||
            return $this->loggingService->getLogger(__CLASS__);
 | 
						||
        }
 | 
						||
 | 
						||
        return $this->loggingService->getLogger($name);
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * Update and persist attached objects to the repository
 | 
						||
     *
 | 
						||
     * @param string $repository
 | 
						||
     * @param \TYPO3\CMS\Extbase\DomainObject\AbstractEntity $objectToPersist
 | 
						||
     */
 | 
						||
    public function persistRepository(string $repository, AbstractEntity $objectToPersist): void
 | 
						||
    {
 | 
						||
        $objectUid = $objectToPersist->getUid();
 | 
						||
        if (!is_int($objectUid)) {
 | 
						||
            $this->objectManager->get($repository)->add($objectToPersist);
 | 
						||
        } else {
 | 
						||
            $this->objectManager->get($repository)->update($objectToPersist);
 | 
						||
        }
 | 
						||
        $this->objectManager->get(PersistenceManager::class)->persistAll();
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * Clear the dynamic CSS file for recreation
 | 
						||
     */
 | 
						||
    public function clearDynamicCssFile(): void
 | 
						||
    {
 | 
						||
        $this->objectManager->get(DynamicCssEvaluator::class)->clearCachePostProc([]);
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * Render CSS-styles for ratings and ratingsteps
 | 
						||
     * Only called by singeltonAction to render styles once per page.
 | 
						||
     * The file self::DYN_CSS_FILENAME will be created if it doesn<73>t exist
 | 
						||
     *
 | 
						||
     * @return array
 | 
						||
     */
 | 
						||
    public function renderDynCSS(): array
 | 
						||
    {
 | 
						||
        $messageArray = [];
 | 
						||
        $cssFile = '';
 | 
						||
 | 
						||
        //create file if it does not exist
 | 
						||
        if (file_exists(Environment::getPublicPath() . '/' . self::DYN_CSS_FILENAME)) {
 | 
						||
            $fstat = stat(Environment::getPublicPath() . '/' . self::DYN_CSS_FILENAME);
 | 
						||
            //do not recreate file if it has greater than zero length
 | 
						||
            if ($fstat[7] !== 0) {
 | 
						||
                $this->logger->log(LogLevel::DEBUG, 'Dynamic CSS file exists - exiting');
 | 
						||
                return $messageArray;
 | 
						||
            }
 | 
						||
        }
 | 
						||
 | 
						||
        //now walk through all ratingobjects to calculate stepwidths
 | 
						||
        $allRatingobjects = $this->ratingobjectRepository->findAll(true);
 | 
						||
 | 
						||
        foreach ($allRatingobjects as $ratingobject) {
 | 
						||
            $ratingobjectUid = $ratingobject->getUid();
 | 
						||
            /** @var ObjectStorage<\WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepconf> $stepconfObjects */
 | 
						||
            $stepconfObjects = $ratingobject->getStepconfs();
 | 
						||
            $stepcount = count($stepconfObjects);
 | 
						||
            if (!$stepcount) {
 | 
						||
                if ($this->settings['showMissingStepconfError']) {
 | 
						||
                    //show error message in GUI
 | 
						||
                    $messageArray[] = [
 | 
						||
                        'messageText' => LocalizationUtility::translate(
 | 
						||
                            'flash.renderCSS.noStepconf',
 | 
						||
                            'ThRating',
 | 
						||
                            [
 | 
						||
                                1 => $ratingobject->getUid(),
 | 
						||
                                2 => $ratingobject->getPid()
 | 
						||
                            ]
 | 
						||
                        ),
 | 
						||
                        'messageTitle' => LocalizationUtility::translate(
 | 
						||
                            'flash.configuration.error',
 | 
						||
                            'ThRating'
 | 
						||
                        ),
 | 
						||
                        'severity' => 'ERROR',
 | 
						||
                        'additionalInfo' => [
 | 
						||
                            'errorCode' => 1384705470,
 | 
						||
                            'ratingobject UID' => $ratingobject->getUid(),
 | 
						||
                            'ratingobject PID' => $ratingobject->getPid(),
 | 
						||
                        ],
 | 
						||
                    ];
 | 
						||
                } else {
 | 
						||
                    //only log message
 | 
						||
                    $this->logger->log(
 | 
						||
                        LogLevel::ERROR,
 | 
						||
                        LocalizationUtility::translate(
 | 
						||
                            'flash.renderCSS.noStepconf',
 | 
						||
                            'ThRating',
 | 
						||
                            [
 | 
						||
                                1 => $ratingobject->getUid(),
 | 
						||
                                2 => $ratingobject->getPid()
 | 
						||
                            ]
 | 
						||
                        ),
 | 
						||
                        [
 | 
						||
                            'errorCode' => 1384705470,
 | 
						||
                            'ratingobject UID' => $ratingobject->getUid(),
 | 
						||
                            'ratingobject PID' => $ratingobject->getPid(),
 | 
						||
                        ]
 | 
						||
                    );
 | 
						||
                }
 | 
						||
            }
 | 
						||
 | 
						||
            $stepWeights = [];
 | 
						||
            $sumStepWeights = 0;
 | 
						||
 | 
						||
            $stepconfs = $stepconfObjects->toArray();
 | 
						||
            foreach ($stepconfs as $stepconf) { //stepconfs are already sorted by steporder
 | 
						||
                //just do checks here that all steps are OK
 | 
						||
                if (!$this->stepconfValidator->validate($stepconf)->hasErrors()) {
 | 
						||
                    /** @var \WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepconf $stepconf */
 | 
						||
                    $stepWeights[] = $stepconf->getStepweight();
 | 
						||
                    $sumStepWeights += $stepconf->getStepweight();
 | 
						||
                } else {
 | 
						||
                    foreach ($this->stepconfValidator->validate($stepconf)->getErrors() as $errorMessage) {
 | 
						||
                        $messageArray[] = [
 | 
						||
                            'messageText' => $errorMessage->getMessage(),
 | 
						||
                            'messageTitle' => LocalizationUtility::translate('flash.configuration.error', 'ThRating'),
 | 
						||
                            'severity' => 'ERROR',
 | 
						||
                            'additionalInfo' => ['errorCode' => $errorMessage->getCode(),
 | 
						||
                                                      'errorMessage' => $errorMessage->getMessage(), ], ];
 | 
						||
                    }
 | 
						||
                }
 | 
						||
            }
 | 
						||
            $this->logger->log(
 | 
						||
                LogLevel::INFO,
 | 
						||
                'Ratingobject data',
 | 
						||
                [
 | 
						||
                    'ratingobject UID' => $ratingobject->getUid(),
 | 
						||
                    'ratingobject PID' => $ratingobject->getPid(),
 | 
						||
                    'stepcount' => $stepcount,
 | 
						||
                    'stepWeights' => $stepWeights,
 | 
						||
                    'sumStepWeights' => $sumStepWeights,
 | 
						||
                    'messageCount' => count($messageArray)
 | 
						||
                ]
 | 
						||
            );
 | 
						||
 | 
						||
            //generate CSS for all ratings out of TSConfig
 | 
						||
            foreach ($this->settings['ratingConfigurations'] as $ratingName => $ratingConfig) {
 | 
						||
                if ($ratingName === 'default') {
 | 
						||
                    continue;
 | 
						||
                }
 | 
						||
                $subURI = substr(Environment::getPublicPath() . '/', strlen($_SERVER['DOCUMENT_ROOT']) + 1);
 | 
						||
                $basePath = $this->getTypoScriptFrontendController()->baseUrl ?: '//' .
 | 
						||
                    $_SERVER['HTTP_HOST'] . '/' . $subURI;
 | 
						||
 | 
						||
                $this->ratingImage = $this->objectManager->get(RatingImage::class);
 | 
						||
                $this->ratingImage->setConf($ratingConfig['imagefile']);
 | 
						||
                $filename = $this->ratingImage->getImageFile();
 | 
						||
                if (empty($filename)) {
 | 
						||
                    $messageArray[] = [
 | 
						||
                        'messageText' => LocalizationUtility::translate(
 | 
						||
                            'flash.vote.renderCSS.defaultImage',
 | 
						||
                            'ThRating'
 | 
						||
                        ),
 | 
						||
                        'messageTitle' => LocalizationUtility::translate(
 | 
						||
                            'flash.heading.warning',
 | 
						||
                            'ThRating'
 | 
						||
                        ),
 | 
						||
                        'severity' => 'WARNING',
 | 
						||
                        'additionalInfo' => ['errorCode' => 1403192702,
 | 
						||
                                    'ratingName' => $ratingName,
 | 
						||
                                    'ratingConfig' => $ratingConfig, ], ];
 | 
						||
                    $defaultRatingName = $this->settings['ratingConfigurations']['default'];
 | 
						||
                    $ratingConfig = $this->settings['ratingConfigurations'][$defaultRatingName];
 | 
						||
                    $this->ratingImage->setConf($ratingConfig['imagefile']);
 | 
						||
                    $filename = $this->ratingImage->getImageFile();
 | 
						||
                }
 | 
						||
                $filenameUri = $basePath . '/' . $filename;  //prepend host basepath if no URL is given
 | 
						||
 | 
						||
                $imageDimensions = $this->ratingImage->getImageDimensions();
 | 
						||
                $height = $imageDimensions['height'];
 | 
						||
                $width = $imageDimensions['width'];
 | 
						||
                $mainId = '.thRating-RObj' . $ratingobjectUid . '-' . $ratingName;
 | 
						||
                $this->logger->log(
 | 
						||
                    LogLevel::DEBUG,
 | 
						||
                    'Main CSS info',
 | 
						||
                    [
 | 
						||
                                'mainId' => $mainId,
 | 
						||
                                'filenameUri' => $filenameUri,
 | 
						||
                                'image width' => $width,
 | 
						||
                                'image height' => $height, ]
 | 
						||
                );
 | 
						||
 | 
						||
                //calculate overall rating size depending on rating direction
 | 
						||
                if ($ratingConfig['tilt']) {
 | 
						||
                    $width = round($width / 3, 1);
 | 
						||
                    if (!$ratingConfig['barimage']) {
 | 
						||
                        $height *= $sumStepWeights;
 | 
						||
                    }
 | 
						||
                    $cssFile .= $mainId . ' { width:' . $width . 'px; height:' . $height . 'px; }' . chr(10);
 | 
						||
                    $cssFile .= $mainId . ', ' . $mainId . ' span:hover, ' . $mainId . ' span:active, ' . $mainId .
 | 
						||
                        ' span:focus, ' . $mainId . ' .current-rating { background:url(' . $filenameUri .
 | 
						||
                        ') right bottom repeat-y; }' . chr(10);
 | 
						||
                    $cssFile .= $mainId . ' span, ' . $mainId . ' .current-rating { width:' . $width . 'px; }' .
 | 
						||
                        chr(10);
 | 
						||
                } else {
 | 
						||
                    $height = round($height / 3, 1);
 | 
						||
                    if (!$ratingConfig['barimage']) {
 | 
						||
                        $width *= $sumStepWeights;
 | 
						||
                    }
 | 
						||
                    $cssFile .= $mainId . ' { width:' . $width . 'px; height:' . $height . 'px; }' . chr(10);
 | 
						||
                    $cssFile .= $mainId . ', ' . $mainId . ' span:hover, ' . $mainId . ' span:active, ' . $mainId .
 | 
						||
                        ' span:focus, ' . $mainId . ' .current-rating { background:url(' . $filenameUri .
 | 
						||
                        ') 0 0 repeat-x; }' . chr(10);
 | 
						||
                    $cssFile .= $mainId . ' span, ' . $mainId . ' .current-rating { height:' . $height .
 | 
						||
                        'px; line-height:' . $height . 'px; }' . chr(10);
 | 
						||
                    //calculate widths/heights related to stepweights
 | 
						||
                }
 | 
						||
                $cssFile .= $mainId . ' .current-poll { background:url(' . $filenameUri . '); }' . chr(10);
 | 
						||
            }
 | 
						||
 | 
						||
            //calculate widths/heights related to stepweights
 | 
						||
            $i = 1;
 | 
						||
            $stepPart = 0;
 | 
						||
            $sumWeights = 0;
 | 
						||
            foreach ($stepWeights as $stepWeight) {
 | 
						||
                $sumWeights += $stepWeight;
 | 
						||
                $zIndex = $stepcount - $i + 2;  //add 2 to override .current-poll and .currentPollText
 | 
						||
                //configure rating and polling styles for steps
 | 
						||
                $oneStepPart = round($stepWeight * 100 / $sumStepWeights, 1); //calculate single width of ratingstep
 | 
						||
                $cssFile .= 'span.RObj' . $ratingobjectUid . '-StpOdr' . $i . '-ratingpoll-normal { width:' .
 | 
						||
                    $oneStepPart . '%; z-index:' . $zIndex . '; margin-left:' . $stepPart . '%;}' . chr(10);
 | 
						||
                $cssFile .= 'span.RObj' . $ratingobjectUid . '-StpOdr' . $i . '-ratingpoll-tilt { height:' .
 | 
						||
                    $oneStepPart . '%; z-index:' . $zIndex . '; margin-bottom:' . $stepPart . '%; }' . chr(10);
 | 
						||
                $cssFile .= 'li.RObj' . $ratingobjectUid . '-StpOdr' . $i . '-currentpoll-normal { width:' .
 | 
						||
                    $oneStepPart . '%; margin-left:' . $stepPart . '%; }' . chr(10);
 | 
						||
                $cssFile .= 'li.RObj' . $ratingobjectUid . '-StpOdr' . $i . '-currentpoll-normal span { width:100%; }' .
 | 
						||
                    chr(10);
 | 
						||
                $cssFile .= 'li.RObj' . $ratingobjectUid . '-StpOdr' . $i . '-currentpoll-tilt { height:' .
 | 
						||
                    $oneStepPart . '%; margin-bottom:' . $stepPart . '%; }' . chr(10);
 | 
						||
                $cssFile .= 'li.RObj' . $ratingobjectUid . '-StpOdr' . $i . '-currentpoll-tilt span { height:100%; }' .
 | 
						||
                    chr(10);
 | 
						||
                $stepPart = round($sumWeights * 100 / $sumStepWeights, 1); //calculate sum of widths to this ratingstep
 | 
						||
                $cssFile .= 'span.RObj' . $ratingobjectUid . '-StpOdr' . $i . '-ratingstep-normal { width:' .
 | 
						||
                    $stepPart . '%; z-index:' . $zIndex . '; }' . chr(10);
 | 
						||
                $cssFile .= 'span.RObj' . $ratingobjectUid . '-StpOdr' . $i . '-ratingstep-tilt { height:' .
 | 
						||
                    $stepPart . '%; z-index:' . $zIndex . '; }' . chr(10);
 | 
						||
                $i++;
 | 
						||
            }
 | 
						||
            //reset variables for next iteration
 | 
						||
            unset($stepWeights, $sumWeights, $sumStepWeights);
 | 
						||
            $this->logger->log(LogLevel::DEBUG, 'CSS finished for ratingobject');
 | 
						||
        }
 | 
						||
 | 
						||
        $this->logger->log(LogLevel::DEBUG, 'Saving CSS file', ['cssFile' => $cssFile]);
 | 
						||
        $fp = fopen(Environment::getPublicPath() . '/' . self::DYN_CSS_FILENAME, 'wb');
 | 
						||
        fwrite($fp, $cssFile);
 | 
						||
        fclose($fp);
 | 
						||
 | 
						||
        return $messageArray;
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * Returns the language object
 | 
						||
     * If not ISO code is provided the default language is returned
 | 
						||
     *
 | 
						||
     * @param int $pid page id to which is part of the site
 | 
						||
     * @param string|null $twoLetterIsoCode iso-639-1 string (e.g. en, de, us)
 | 
						||
     * @return \TYPO3\CMS\Core\Site\Entity\SiteLanguage
 | 
						||
     * @throws LanguageNotFoundException
 | 
						||
     */
 | 
						||
    public function getStaticLanguageByIsoCode(int $pid, string $twoLetterIsoCode = null): SiteLanguage
 | 
						||
    {
 | 
						||
        /** @var Site $site */
 | 
						||
        $site = GeneralUtility::makeInstance(SiteFinder::class)->getSiteByPageId($pid);
 | 
						||
 | 
						||
        if (!is_null($twoLetterIsoCode)) {
 | 
						||
            foreach ($site->getAllLanguages() as $language) {
 | 
						||
                if ($language->getTwoLetterIsoCode() === $twoLetterIsoCode) {
 | 
						||
                    return $language;
 | 
						||
                }
 | 
						||
            }
 | 
						||
            throw new LanguageNotFoundException(LocalizationUtility::translate(
 | 
						||
                'flash.general.languageNotFound',
 | 
						||
                'ThRating'
 | 
						||
            ), 1582980369);
 | 
						||
        }
 | 
						||
        return $site->getDefaultLanguage();
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * Returns the language object
 | 
						||
     * If not ISO code is provided the default language is returned
 | 
						||
     *
 | 
						||
     * @param int $pid page id to which is part of the site
 | 
						||
     * @param int|null $languageId iso-639-1 string (e.g. en, de, us)
 | 
						||
     * @return \TYPO3\CMS\Core\Site\Entity\SiteLanguage
 | 
						||
     * @throws \TYPO3\CMS\Core\Exception\SiteNotFoundException
 | 
						||
     */
 | 
						||
    public function getStaticLanguageById(int $pid, int $languageId = null): ?SiteLanguage
 | 
						||
    {
 | 
						||
        /** @var Site $site */
 | 
						||
        $site = GeneralUtility::makeInstance(SiteFinder::class)->getSiteByPageId($pid);
 | 
						||
 | 
						||
        if ($languageId) {
 | 
						||
            return $site->getLanguageById($languageId);
 | 
						||
        }
 | 
						||
        return $site->getDefaultLanguage();
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * @return ServerRequestInterface
 | 
						||
     */
 | 
						||
    public function getRequest(): ServerRequestInterface
 | 
						||
    {
 | 
						||
        return $GLOBALS['TYPO3_REQUEST'];
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * Sets the current request object
 | 
						||
     *
 | 
						||
     * @param \TYPO3\CMS\Extbase\Mvc\Request $request
 | 
						||
     */
 | 
						||
    public function setRequest(\TYPO3\CMS\Extbase\Mvc\Request $request): void
 | 
						||
    {
 | 
						||
        $this->request = $request;
 | 
						||
    }
 | 
						||
}
 |