Zwischenstand

This commit is contained in:
Sven Wappler
2021-08-17 19:45:38 +02:00
parent fde2759722
commit ce6b9e38dc
71 changed files with 7886 additions and 809 deletions

View File

@@ -0,0 +1,237 @@
<?php
/*
* This file is part of the package buepro/bookmark_pages.
*
* For the full copyright and license information, please read the
* LICENSE file that was distributed with this source code.
*/
namespace WapplerSystems\BookmarksLikesRatings\Domain\Model;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
*
*/
class Bookmark
{
/**
* @var string
*/
protected $id;
/**
* @var string
*/
protected $title;
/**
* @var string
*/
protected $url;
/**
* @var int
*/
protected $pid;
/**
* @var string
*/
protected $parameter;
/**
* Bookmark constructor.
* Initialize the bookmark with data
*
* @param string|array $url Full url or bookmark data array (same as array from toArray())
* @param null $title
* @param null $pid page id
* @param null $parameter
*/
public function __construct($url, $title = null, $pid = null, $parameter = null)
{
if (is_array($url)) {
$this->id = $url['id'];
$this->title = $url['title'];
$this->url = $url['url'];
$this->pid = $url['pid'];
$this->parameter = $url['parameter'];
} else {
$this->id = md5($pid . ':' . $parameter);
$this->title = $title;
$this->url = $url;
$this->pid = $pid;
$this->parameter = $parameter;
}
}
/**
* Create bookmark from the current TSFE page
*
* @param string url to bookmark, if null TYPO3_REQUEST_URL will be used - which is wrong when we're in ajax context, then we use HTTP_REFERER
* @return Bookmark
*/
public static function createFromCurrent($url = null)
{
if ($url === null) {
if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest') {
//request is ajax
$url = GeneralUtility::getIndpEnv('HTTP_REFERER');
} else {
$url = GeneralUtility::getIndpEnv('TYPO3_REQUEST_URL');
}
}
$pid = self::getFrontend()->id;
$title = self::getCurrentPageTitle();
/*
The idea was to store get parameters to make bookmark handling more flexible.
Unfortunately that didn't worked out.
When we use ajax to trigger bookmarking the current page, we can pass the current url as parameter.
But the url doesn't have the parameters in it when you use speaking urls (realurl, simulatestatic, ...).
The problem is that there's no common api to decode urls and get the parameters.
One solution would be to make the parameters available to the ajax javascript during page rendering.
We skip all this and use a bit from the url for hashing and add the page id.
*/
$urlParts = parse_url($url);
$parameter = $urlParts['path'] . '?' . $urlParts['query'] . '#' . $urlParts['fragment'];
return new self($url, $title, $pid, $parameter);
/*
* So what is the idea of storing the pid and the get vars?
*
* This might makes sense if urls changed for the same page (realurl).
* With this information the new working url can be restored.
*
* Not sure which way is better ...
*/
// $parameter = (array)GeneralUtility::_GET();
// unset($parameter['id']);
// // @todo remove cHash?
// ksort($parameter);
// $parameter = $parameter ? GeneralUtility::implodeArrayForUrl(false, $parameter) : '';
//
// return new self($url, $title, $pid, $parameter);
}
/**
* @return string
*/
public function getId()
{
return $this->id;
}
/**
* @param string $id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* @return string
*/
public function getTitle()
{
return $this->title;
}
/**
* @param string $title
*/
public function setTitle($title)
{
$this->title = $title;
}
/**
* @return string
*/
public function getUrl()
{
return $this->url;
}
/**
* @param string $url
*/
public function setUrl($url)
{
$this->url = $url;
}
/**
* @return int
*/
public function getPid()
{
return $this->pid;
}
/**
* @param int $pid
*/
public function setPid($pid)
{
$this->pid = $pid;
}
/**
* @return string
*/
public function getParameter()
{
return $this->parameter;
}
/**
* @param string $parameter
*/
public function setParameter($parameter)
{
$this->parameter = $parameter;
}
/**
* Returns the bookmark data as array
*
* @return array
*/
public function toArray()
{
return [
'id' => $this->id,
'title' => $this->title,
'url' => $this->url,
'pid' => $this->pid,
'parameter' => $this->parameter,
];
}
/**
* Get the current page title
* @return string
*/
protected static function getCurrentPageTitle()
{
return self::getFrontend()->altPageTitle ? self::getFrontend()->altPageTitle : self::getFrontend()->page['title'];
}
/**
*
* @return \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController
*/
protected static function getFrontend()
{
return $GLOBALS['TSFE'];
}
}

View File

@@ -0,0 +1,241 @@
<?php
/*
* This file is part of the package buepro/bookmark_pages.
*
* For the full copyright and license information, please read the
* LICENSE file that was distributed with this source code.
*/
namespace WapplerSystems\BookmarksLikesRatings\Domain\Model;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
use TYPO3\CMS\Core\Database\Query\Restriction\FrontendRestrictionContainer;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* Provide access to a list of Bookmark
*/
class Bookmarks
{
/**
* column in db
*/
const BOOKMARKS_COLUMN = 'tx_bookmarks_pages';
/**
* @var array|Bookmark[]
*/
protected $bookmarks = [];
/**
* @var bool Flag if bookmarks has changed an need to be saved
*/
protected $changeFlag = false;
/**
* Initialize bookmarks
*/
public function __construct()
{
// is login user?
if (is_array($this->getUser()->user) && $this->getUser()->user[$this->getUser()->userid_column]) {
$bookmarks = $this->getUser()->user[self::BOOKMARKS_COLUMN];
$bookmarks = (array)GeneralUtility::xml2array($bookmarks);
foreach ($bookmarks as $bookmark) {
if (isset($bookmark['id'])) {
$this->bookmarks[$bookmark['id']] = new Bookmark($bookmark);
}
}
}
}
/**
* persist bookmarks if needed
*/
public function __destruct()
{
$this->persist();
}
/**
* Get all Bookmarks
*
* @return array|Bookmark[]
*/
public function getBookmarks()
{
return (array)$this->bookmarks;
}
/**
* clear all bookmarks
*/
public function clearBookmarks()
{
$this->bookmarks = [];
$this->changeFlag = true;
}
/**
* Add a bookmark
*
* @param Bookmark $bookmark
*/
public function addBookmark(Bookmark $bookmark)
{
$this->bookmarks[$bookmark->getId()] = $bookmark;
$this->changeFlag = true;
}
/**
* Get Bookmark by given id
*
* @param string $id
* @return Bookmark|mixed
*/
public function getBookmark($id)
{
return $this->bookmarks[$id];
}
/**
* Check if a given bookmark is stored already
*
* @param Bookmark $bookmark
* @return bool
*/
public function bookmarkExists(Bookmark $bookmark)
{
return isset($this->bookmarks[$bookmark->getId()]);
}
/**
* Remove bookmark by given id
*
* @param string $id
*/
public function removeBookmark($id)
{
unset($this->bookmarks[$id]);
$this->changeFlag = true;
}
/**
* persist bookmarks if needed
*/
public function persist()
{
if ($this->changeFlag && is_array($this->getUser()->user) && $this->getUser()->user[$this->getUser()->userid_column]) {
$bookmarks = [];
foreach ($this->bookmarks as $bookmark) {
$bookmarks[] = $bookmark->toArray();
}
/*
* Why xml?
*
* Why not! You can even process it in the db if you like
* (And dooon't tell me json would be a good idea, or serialized php ... haaahaaaaaa)
*/
$bookMarksXml = GeneralUtility::array2xml($bookmarks);
/** @var QueryBuilder $queryBuilder */
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable($this->getUser()->user_table);
$queryBuilder
->update($this->getUser()->user_table)
->where(
$queryBuilder->expr()->eq(
$this->getUser()->userid_column,
$queryBuilder->createNamedParameter((int)$this->getUser()->user[$this->getUser()->userid_column], \PDO::PARAM_INT)
)
)
->set(self::BOOKMARKS_COLUMN, $bookMarksXml)
->execute();
$this->changeFlag = false;
}
}
/**
* Get global frontend user
* @return \TYPO3\CMS\Frontend\Authentication\FrontendUserAuthentication
*/
protected function getUser()
{
return $GLOBALS['TSFE']->fe_user;
}
/**
* @return array
*/
private function getAccessibleBookmarks()
{
$bookmarks = $this->getBookmarks();
if (!$bookmarks) {
return [];
}
// Create an array association the page uid with the bookmark id (uid => id)
$pageMap = array_flip(array_map(static function ($bookmark) {
return (int) $bookmark->getPid();
}, $bookmarks));
// Get accessible pages
/** @var QueryBuilder $queryBuilder */
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('pages');
$queryBuilder->setRestrictions(GeneralUtility::makeInstance(FrontendRestrictionContainer::class));
$pages = $queryBuilder
->select('uid')
->from('pages')
->where($queryBuilder->expr()->in('uid', array_keys($pageMap)))
->execute()
->fetchAll();
// Collect accessible bookmarks
$accessibleBookmarks = [];
foreach ($pages as $page) {
if (isset($pageMap[$page['uid']])) {
$accessibleBookmarks[$pageMap[$page['uid']]] = $bookmarks[$pageMap[$page['uid']]];
}
}
// Order the bookmarks (same sequence as at the beginning)
return array_intersect_key($bookmarks, $accessibleBookmarks);
}
/**
* Merge bookmarks into the current ones.
*
* @param $bookmarks
* @return array|Bookmark[]
*/
public function merge($bookmarks)
{
$bookmarksChanged = false;
foreach ($bookmarks as $id => $bookmark) {
if (!isset($this->bookmarks[$id])) {
$bookmarksChanged = true;
$this->bookmarks[$id] = new Bookmark($bookmark);
}
}
if ($bookmarksChanged) {
$this->persist();
}
return $this->getBookmarks();
}
/**
* Get bookmarks for local storage in browser
*/
public function getBookmarksForLocalStorage(): array
{
$result = [];
foreach ($this->getAccessibleBookmarks() as $bookmark) {
$result[$bookmark->getId()] = $bookmark->toArray();
}
return $result;
}
}

View File

@@ -0,0 +1,410 @@
<?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.
*/
namespace WapplerSystems\BookmarksLikesRatings\Domain\Model;
use WapplerSystems\BookmarksLikesRatings\Domain\Repository\VoteRepository;
use WapplerSystems\BookmarksLikesRatings\Service\ExtensionHelperService;
use WapplerSystems\BookmarksLikesRatings\Service\JsonService;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Annotation as Extbase;
use TYPO3\CMS\Extbase\Configuration\ConfigurationManager;
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
use TYPO3\CMS\Extbase\Object\ObjectManager;
use TYPO3\CMS\Extbase\Object\ObjectManagerInterface;
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
/**
* Model for object rating
*
* @copyright Copyright belongs to the respective authors
* @license http://opensource.org/licenses/gpl-license.php GNU Public License, version 2
* @entity
*/
class Rating extends AbstractEntity
{
//TODO check deleted referenced records
/**
* @Extbase\Validate("\WapplerSystems\BookmarksLikesRatings\Domain\Validator\RatingobjectValidator")
* @Extbase\Validate("NotEmpty")
* @var \WapplerSystems\BookmarksLikesRatings\Domain\Model\Ratingobject
*/
protected $ratingobject;
/**
* The ratings uid of this object
*
* @Extbase\Validate("NumberRange", options={"minimum": 1})
* @Extbase\Validate("NotEmpty")
* @var int
*/
protected $ratedobjectuid;
/**
* The ratings of this object
*
* @Extbase\ORM\Lazy
* @Extbase\ORM\Cascade("remove")
* @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\WapplerSystems\BookmarksLikesRatings\Domain\Model\Vote>
*/
protected $votes;
/**
* @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
*/
protected $objectManager;
/**
* @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
*/
/** @noinspection PhpUnused */
public function injectObjectManager(ObjectManagerInterface $objectManager)
{
$this->objectManager = $objectManager;
}
/**
* @var \WapplerSystems\BookmarksLikesRatings\Service\JsonService
*/
protected $jsonService;
/**
* @param \WapplerSystems\BookmarksLikesRatings\Service\JsonService $jsonService
*/
public function injectJsonService(JsonService $jsonService)
{
$this->jsonService = $jsonService;
}
/**
* @var \WapplerSystems\BookmarksLikesRatings\Domain\Repository\VoteRepository
*/
protected $voteRepository;
/**
* @param \WapplerSystems\BookmarksLikesRatings\Domain\Repository\VoteRepository $voteRepository
*/
public function injectVoteRepository(VoteRepository $voteRepository)
{
$this->voteRepository = $voteRepository;
}
/**
* @var \WapplerSystems\BookmarksLikesRatings\Service\ExtensionHelperService
*/
protected $extensionHelperService;
/**
* @param \WapplerSystems\BookmarksLikesRatings\Service\ExtensionHelperService $extensionHelperService
*/
/** @noinspection PhpUnused */
public function injectExtensionHelperService(ExtensionHelperService $extensionHelperService)
{
$this->extensionHelperService = $extensionHelperService;
}
/**
* The current calculated rates
*
* Redundant information to enhance performance in displaying calculated information
* This is a JSON encoded string with the following keys
* - votecounts(1...n) vote counts of the specific ratingstep
* It be updated every time a vote is created, changed or deleted.
* Specific handling must be defined when ratingsteps are added or removed or stepweights are changed
* Calculation of ratings:
* currentrate = ( sum of all ( stepweight(n) * votecounts(n) ) ) / number of all votes
* currentwidth = round (currentrate * 100 / number of ratingsteps, 1)
*
* @var string
*/
protected $currentrates;
/**
* @var array
*/
protected $settings;
/**
* Constructs a new rating object
* @param \WapplerSystems\BookmarksLikesRatings\Domain\Model\Ratingobject|null $ratingobject
* @param int|null $ratedobjectuid
* @throws \TYPO3\CMS\Extbase\Configuration\Exception\InvalidConfigurationTypeException
*/
public function __construct(Ratingobject $ratingobject = null, $ratedobjectuid = null)
{
if ($ratingobject) {
$this->setRatingobject($ratingobject);
}
if ($ratedobjectuid) {
$this->setRatedobjectuid($ratedobjectuid);
}
$this->initializeObject();
}
/**
* Initializes a new rating object
* @throws \TYPO3\CMS\Extbase\Configuration\Exception\InvalidConfigurationTypeException
*/
public function initializeObject()
{
if (empty($this->objectManager)) {
$this->objectManager = GeneralUtility::makeInstance(ObjectManager::class);
}
$this->settings = $this->objectManager
->get(ConfigurationManager::class)
->getConfiguration('Settings', 'thRating', 'pi1');
//Initialize vote storage if rating is new
if (!is_object($this->votes)) {
$this->votes = new ObjectStorage();
}
}
/**
* Sets the ratingobject this rating is part of
*
* @param \WapplerSystems\BookmarksLikesRatings\Domain\Model\Ratingobject $ratingobject The Rating
*/
public function setRatingobject(Ratingobject $ratingobject)
{
$this->ratingobject = $ratingobject;
$this->setPid($ratingobject->getPid());
}
/**
* Returns the ratingobject this rating is part of
*
* @return \WapplerSystems\BookmarksLikesRatings\Domain\Model\Ratingobject The ratingobject this rating is part of
*/
public function getRatingobject(): Ratingobject
{
return $this->ratingobject;
}
/**
* Sets the rating object uid
*
* @param int $ratedobjectuid
*/
public function setRatedobjectuid($ratedobjectuid)
{
$this->ratedobjectuid = $ratedobjectuid;
}
/**
* Gets the rating object uid
*
* @return int Rating object row uid field value
*/
public function getRatedobjectuid()
{
return $this->ratedobjectuid;
}
/**
* Adds a vote to this rating
*
* @param \WapplerSystems\BookmarksLikesRatings\Domain\Model\Vote $vote
*/
public function addVote(Vote $vote)
{
$this->votes->attach($vote);
$this->addCurrentrate($vote);
$this->extensionHelperService->persistRepository(VoteRepository::class, $vote);
}
/**
* Updates an existing vote to this rating
*
* @param \WapplerSystems\BookmarksLikesRatings\Domain\Model\Vote $existingVote
* @param \WapplerSystems\BookmarksLikesRatings\Domain\Model\Vote $newVote
*/
public function updateVote(Vote $existingVote, Vote $newVote)
{
$this->removeCurrentrate($existingVote);
$existingVote->setVote($newVote->getVote());
$this->addCurrentrate($existingVote);
$this->extensionHelperService->persistRepository(VoteRepository::class, $existingVote);
}
/**
* Remove a vote from this rating
*
* @param \WapplerSystems\BookmarksLikesRatings\Domain\Model\Vote $voteToRemove The vote to be removed
*/
/** @noinspection PhpUnused */
public function removeVote(Vote $voteToRemove)
{
$this->removeCurrentrate($voteToRemove);
$this->votes->detach($voteToRemove);
}
/**
* Remove all votes from this rating
*/
/** @noinspection PhpUnused */
public function removeAllVotes()
{
$this->votes = new ObjectStorage();
unset($this->currentrates);
}
/**
* Returns all votes in this rating
*
* @return \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\WapplerSystems\BookmarksLikesRatings\Domain\Model\Vote>
*/
public function getVotes()
{
return clone $this->votes;
}
/**
* Checks all votes of this rating and sets currentrates accordingly
*
* This method is used for maintenance to assure consistency
*/
public function checkCurrentrates()
{
$currentratesDecoded['weightedVotes'] = [];
$currentratesDecoded['sumWeightedVotes'] = [];
$numAllVotes = 0;
$numAllAnonymousVotes = 0;
foreach ($this->getRatingobject()->getStepconfs() as $stepConf) {
$stepOrder = $stepConf->getSteporder();
$voteCount = $this->voteRepository->countByMatchingRatingAndVote($this, $stepConf);
$anonymousCount = $this->voteRepository->countAnonymousByMatchingRatingAndVote(
$this,
$stepConf,
$this->settings['mapAnonymous']
);
$currentratesDecoded['weightedVotes'][$stepOrder] = $voteCount * $stepConf->getStepweight();
$currentratesDecoded['sumWeightedVotes'][$stepOrder] =
$currentratesDecoded['weightedVotes'][$stepOrder] * $stepOrder;
$numAllVotes += $voteCount;
$numAllAnonymousVotes += $anonymousCount;
}
$currentratesDecoded['numAllVotes'] = $numAllVotes;
$currentratesDecoded['anonymousVotes'] = $numAllAnonymousVotes;
$this->currentrates = $this->jsonService->encodeToJson($currentratesDecoded);
}
/**
* Adds a vote to the calculations of this rating
*
* @param \WapplerSystems\BookmarksLikesRatings\Domain\Model\Vote $voting The vote to be added
*/
public function addCurrentrate(Vote $voting)
{
if (empty($this->currentrates)) {
$this->checkCurrentrates(); //initialize entry
}
$currentratesDecoded = $this->jsonService->decodeJsonToArray($this->currentrates);
$currentratesDecoded['numAllVotes']++;
if ($voting->isAnonymous()) {
$currentratesDecoded['anonymousVotes']++;
}
$votingStep = $voting->getVote();
/** @noinspection NullPointerExceptionInspection */
$votingSteporder = $votingStep->getSteporder();
/** @noinspection NullPointerExceptionInspection */
$votingStepweight = $votingStep->getStepweight();
$currentratesDecoded['weightedVotes'][$votingSteporder] += $votingStepweight;
$currentratesDecoded['sumWeightedVotes'][$votingSteporder] += $votingStepweight * $votingSteporder;
$this->currentrates = $this->jsonService->encodeToJson($currentratesDecoded);
}
/**
* Adds a vote to the calculations of this rating
*
* @param \WapplerSystems\BookmarksLikesRatings\Domain\Model\Vote $voting The vote to be removed
*/
public function removeCurrentrate(Vote $voting)
{
if (empty($this->currentrates)) {
$this->checkCurrentrates(); //initialize entry
}
$currentratesDecoded = $this->jsonService->decodeJsonToArray($this->currentrates);
$currentratesDecoded['numAllVotes']--;
if ($voting->isAnonymous()) {
$currentratesDecoded['anonymousVotes']--;
}
$votingStep = $voting->getVote();
/** @noinspection NullPointerExceptionInspection */
$votingSteporder = $votingStep->getSteporder();
/** @noinspection NullPointerExceptionInspection */
$votingStepweight = $votingStep->getStepweight();
$currentratesDecoded['weightedVotes'][$votingSteporder] -= $votingStepweight;
$currentratesDecoded['sumWeightedVotes'][$votingSteporder] -= $votingStepweight * $votingSteporder;
$this->currentrates = $this->jsonService->encodeToJson($currentratesDecoded);
}
/**
* Returns the calculated rating
*
* @return array
*/
public function getCurrentrates(): array
{
$currentratesDecoded = $this->jsonService->decodeJsonToArray($this->currentrates);
if (empty($currentratesDecoded['numAllVotes'])) {
$this->checkCurrentrates();
$currentratesDecoded = $this->jsonService->decodeJsonToArray($this->currentrates);
}
$numAllVotes = $currentratesDecoded['numAllVotes'];
if (!empty($numAllVotes)) {
$currentrate = array_sum($currentratesDecoded['sumWeightedVotes']) / $numAllVotes;
} else {
$currentrate = 0;
$numAllVotes = 0;
}
$sumAllWeightedVotes = array_sum($currentratesDecoded['weightedVotes']);
//initialize array to handle missing stepconfs correctly
$currentPollDimensions = [];
foreach ($this->getRatingobject()->getStepconfs() as $stepConf) {
if (empty($sumAllWeightedVotes)) {
//set current polling styles to zero percent and prevent division by zero error in lower formula
$currentPollDimensions[$stepConf->getStepOrder()]['pctValue'] = 0;
} else {
/* calculate current polling styles -> holds a percent value for usage in CSS
to display polling relations */
$currentPollDimensions[$stepConf->getStepOrder()]['pctValue'] =
round(
($currentratesDecoded['weightedVotes'][$stepConf->getStepOrder()] * 100) /
$sumAllWeightedVotes,
1
);
}
}
return ['currentrate' => $currentrate,
'weightedVotes' => $currentratesDecoded['weightedVotes'],
'sumWeightedVotes' => $currentratesDecoded['sumWeightedVotes'],
'anonymousVotes' => $currentratesDecoded['anonymousVotes'],
'currentPollDimensions' => $currentPollDimensions,
'numAllVotes' => $numAllVotes, ];
}
/**
* Returns the calculated rating in percent
*
* @return int
*/
public function getCalculatedRate(): int
{
$currentrate = $this->getCurrentrates();
if (!empty($currentrate['weightedVotes'])) {
$calculatedRate = round(($currentrate['currentrate'] * 100) / count($currentrate['weightedVotes']), 1);
} else {
$calculatedRate = 0;
}
return $calculatedRate;
}
}

View File

@@ -0,0 +1,196 @@
<?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.
*/
namespace WapplerSystems\BookmarksLikesRatings\Domain\Model;
use TYPO3\CMS\Core\Core\Environment;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
use TYPO3\CMS\Frontend\Imaging\GifBuilder;
/**
* Model for rating votes
*
* @copyright Copyright belongs to the respective authors
* @license http://opensource.org/licenses/gpl-license.php GNU Public License, version 2
* @entity
*/
class RatingImage extends AbstractEntity
{
/**
* @var bool
*/
protected $isBuilderObject = false;
/**
* The filename of the final image
*
* @var string
*/
protected $imageFile;
/**
* The typoscript image configuration array
* Only the top level node ['GIFBUILDER'] will be used for building the image
*
* @var array
*/
protected $conf;
/**
* @var GifBuilder
*/
protected $gifBuilder;
/**
* @param GifBuilder $gifBuilder
*/
public function injectGifBuilder(GifBuilder $gifBuilder)
{
$this->gifBuilder = $gifBuilder;
}
/**
* Constructs a new image object
*
* @param mixed $conf either an array consisting of GIFBUILDER typoscript or a plain string having the filename
*/
public function __construct($conf = null)
{
$this->initializeObject();
if (!empty($conf)) {
$this->setConf($conf);
}
}
/**
* Initializes the new vote object
*/
public function initializeObject()
{
if (empty($this->gifBuilder)) {
$this->injectGifBuilder(GeneralUtility::makeInstance(GifBuilder::class));
}
}
/**
* Sets the typoscript configuration for the GIFBUILDER object
*
* @param mixed $conf either an array consisting of GIFBUILDER typoscript or a plain string having the filename
*/
public function setConf($conf)
{
switch (gettype($conf)) {
case 'string':
$this->setImageFile($conf);
break;
case 'array':
$this->conf = $conf;
$this->generateImage();
break;
default:
//TODO: Error message
}
}
/**
* Returns the current typoscript configuration of the GIFBUILDER object
*
* @return array
*/
public function getConf(): array
{
if (empty($this->conf)) {
return [];
}
return $this->conf;
}
/**
* Sets the filename of the image
*
* @param string $imageFile
*/
public function setImageFile($imageFile)
{
$fullImagePath = Environment::getPublicPath() . '/' . $imageFile;
if (file_exists($fullImagePath)) {
$this->imageFile = $imageFile;
$this->isBuilderObject = false;
} else {
//clear path if given file is invalid
unset($this->imageFile, $this->isBuilderObject);
//TODO: error handling
}
}
/**
* Returns the filename of the image
*
* @param mixed $fullPath
* @return string
*/
public function getImageFile($fullPath = false)
{
$checkedFile = $this->gifBuilder->checkFile($this->imageFile);
if (empty($checkedFile)) {
//clear image if file doe not exist
$this->setImageFile('xxx');
}
return $fullPath ? Environment::getPublicPath() . '/' . $this->imageFile : $this->imageFile;
}
/**
* Generates the image using the given typoscript
*
* @return bool The result; true if the given the image has been created successfully; otherwise false
*/
public function generateImage()
{
if (!empty($this->conf)) {
$this->gifBuilder->start($this->getConf(), []);
$genImageFile = $this->gifBuilder->gifBuild();
if (!file_exists($genImageFile)) {
//TODO: error handling
return false;
}
$this->setImageFile($genImageFile);
$this->isBuilderObject = true;
return true;
}
return false;
}
/**
* Returns the filename of the image
*
* @var bool switch if absolute path should be returned
* @return array('width','height')
*/
public function getImageDimensions()
{
if ($this->isBuilderObject) {
[$width, $height] = $this->gifBuilder->getImageDimensions($this->imageFile);
} else {
[$width, $height] = getimagesize($this->getImageFile(true));
}
return ['width' => $width, 'height' => $height, 'builderObject' => $this->isBuilderObject];
}
/**
* Method to use Object as plain string
*
* @return string
*/
public function __toString()
{
return $this->imageFile;
}
}

View File

@@ -0,0 +1,257 @@
<?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.
*/
namespace WapplerSystems\BookmarksLikesRatings\Domain\Model;
use WapplerSystems\BookmarksLikesRatings\Domain\Repository\RatingRepository;
use WapplerSystems\BookmarksLikesRatings\Domain\Repository\StepconfRepository;
use WapplerSystems\BookmarksLikesRatings\Service\ExtensionHelperService;
use TYPO3\CMS\Extbase\Annotation as Extbase;
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
/**
* Aggregate object for rating of content objects
*
* @version $Id:$
* @copyright Copyright belongs to the respective authors
* @license http://opensource.org/licenses/gpl-license.php GNU Public License, version 2
* @entity
*/
class Ratingobject extends AbstractEntity
{
/**
* Table name of the cObj
* Defaults to Typo3 tablename of pages
*
* @Extbase\Validate("StringLength", options={"minimum": 3})
* @Extbase\Validate("StringLength", options={"maximum": 60})
* @Extbase\Validate("NotEmpty")
* @var string
*/
protected $ratetable;
/**
* Fieldname within the table of the cObj
* Defaults to the field 'uid'
*
* @Extbase\Validate("StringLength", options={"minimum": 3})
* @Extbase\Validate("StringLength", options={"maximum": 60})
* @Extbase\Validate("NotEmpty")
* @var string
*/
protected $ratefield;
/**
* The stepconfs of this object
*
* @Extbase\ORM\Lazy
* @Extbase\ORM\Cascade("remove")
* @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepconf>
*/
protected $stepconfs;
/**
* The ratings of this object
*
* @Extbase\ORM\Lazy
* @Extbase\ORM\Cascade("remove")
* @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\WapplerSystems\BookmarksLikesRatings\Domain\Model\Rating>
*/
protected $ratings;
/**
* @var \WapplerSystems\BookmarksLikesRatings\Domain\Repository\StepconfRepository
*/
protected $stepconfRepository;
/**
* @param \WapplerSystems\BookmarksLikesRatings\Domain\Repository\StepconfRepository $stepconfRepository
*/
public function injectStepconfRepository(StepconfRepository $stepconfRepository)
{
$this->stepconfRepository = $stepconfRepository;
}
/**
* @var \WapplerSystems\BookmarksLikesRatings\Service\ExtensionHelperService
*/
protected $extensionHelperService;
/**
* @param \WapplerSystems\BookmarksLikesRatings\Service\ExtensionHelperService $extensionHelperService
*/
/** @noinspection PhpUnused */
public function injectExtensionHelperService(ExtensionHelperService $extensionHelperService)
{
$this->extensionHelperService = $extensionHelperService;
}
/**
* Constructs a new rating object
* @param string $ratetable The rating objects table name
* @param string $ratefield The rating objects field name
* @Extbase\Validate("StringLength", options={"minimum": 3}, param="ratetable")
* @Extbase\Validate("StringLength", options={"maximum": 60}, param="ratetable")
* @Extbase\Validate("StringLength", options={"minimum": 3}, param="ratefield")
* @Extbase\Validate("StringLength", options={"maximum": 60}, param="ratefield")
*/
public function __construct($ratetable = null, $ratefield = null)
{
if ($ratetable) {
$this->setRatetable($ratetable);
}
if ($ratefield) {
$this->setRatefield($ratefield);
}
$this->initializeObject();
}
/**
* Initializes a new ratingobject
*/
public function initializeObject()
{
//Initialize rating storage if ratingobject is new
if (!is_object($this->ratings)) {
$this->ratings = new ObjectStorage();
}
//Initialize stepconf storage if ratingobject is new
if (!is_object($this->stepconfs)) {
$this->stepconfs = new ObjectStorage();
}
}
/**
* Sets the rating table name
*
* @param string $ratetable
*/
public function setRatetable($ratetable)
{
$this->ratetable = $ratetable;
}
/**
* Gets the rating table name
*
* @return string Rating object table name
*/
public function getRatetable()
{
return $this->ratetable;
}
/**
* Sets the rating field name
*
* @param string $ratefield
*/
public function setRatefield($ratefield)
{
$this->ratefield = $ratefield;
}
/**
* Sets the rating field name
*
* @return string Rating object field name
*/
public function getRatefield()
{
return $this->ratefield;
}
/**
* Adds a rating to this object
*
* @param \WapplerSystems\BookmarksLikesRatings\Domain\Model\Rating $rating
*/
/** @noinspection PhpUnused */
public function addRating(Rating $rating)
{
$this->ratings->attach($rating);
$this->extensionHelperService->persistRepository(RatingRepository::class, $rating);
$this->extensionHelperService->clearDynamicCssFile();
}
/**
* Remove a rating from this object
*
* @param \WapplerSystems\BookmarksLikesRatings\Domain\Model\Rating $rating The rating to be removed
*/
public function removeRating(Rating $rating): void
{
$this->ratings->detach($rating);
}
/**
* Remove all ratings from this object
*/
public function removeAllRatings(): void
{
$this->ratings = new ObjectStorage();
}
/**
* Adds a stepconf to this object
*
* @param \WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepconf $stepconf
*/
public function addStepconf(Stepconf $stepconf): void
{
if (!$this->stepconfRepository->existStepconf($stepconf)) {
$this->stepconfs->attach($stepconf);
$this->extensionHelperService->persistRepository(StepconfRepository::class, $stepconf);
$this->extensionHelperService->clearDynamicCssFile();
}
}
/**
* Sets all ratings of this ratingobject
*
* @param \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepconf> $stepconfs
* The step configurations for this ratingobject
*/
public function setStepconfs(ObjectStorage $stepconfs)
{
$this->stepconfs = $stepconfs;
}
/**
* Returns all ratings in this object
*
* @return \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepconf>
*/
public function getStepconfs()
{
return clone $this->stepconfs;
}
/**
* Sets all ratings of this ratingobject
*
* @param \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\WapplerSystems\BookmarksLikesRatings\Domain\Model\Rating> $ratings
* The ratings of the organization
*/
public function setRatings(ObjectStorage $ratings)
{
$this->ratings = $ratings;
}
/**
* Returns all ratings in this object
*
* @return \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\WapplerSystems\BookmarksLikesRatings\Domain\Model\Rating>
*/
public function getRatings()
{
return clone $this->ratings;
}
}

View File

@@ -0,0 +1,271 @@
<?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.
*/
namespace WapplerSystems\BookmarksLikesRatings\Domain\Model;
use WapplerSystems\BookmarksLikesRatings\Domain\Repository\StepconfRepository;
use WapplerSystems\BookmarksLikesRatings\Domain\Repository\StepnameRepository;
use WapplerSystems\BookmarksLikesRatings\Service\ExtensionHelperService;
use TYPO3\CMS\Extbase\Annotation as Extbase;
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
use TYPO3\CMS\Extbase\Object\ObjectManagerInterface;
use TYPO3\CMS\Extbase\Persistence\Generic\LazyLoadingProxy;
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
/**
* Model for ratingstep configuration
*
* @copyright Copyright belongs to the respective authors
* @license http://opensource.org/licenses/gpl-license.php GNU Public License, version 2
* @entity
*/
class Stepconf extends AbstractEntity
{
/**
* @Extbase\Validate("\WapplerSystems\BookmarksLikesRatings\Domain\Validator\RatingobjectValidator")
* @Extbase\Validate("NotEmpty")
* @var \WapplerSystems\BookmarksLikesRatings\Domain\Model\Ratingobject
*/
protected $ratingobject;
/**
* The order of this config entry
*
* @Extbase\Validate("NumberRange", options={"minimum": 1})
* @Extbase\Validate("NotEmpty")
* @var int discrete order of ratingsteps
*/
protected $steporder;
/**
* The weight of this config entry
*
* @Extbase\Validate("Integer")
* @Extbase\Validate("NumberRange", options={"minimum": 1})
* @var int default is 1 which is equal weight
*/
protected $stepweight;
/**
* The value of this config entry
*
* @Extbase\ORM\Lazy
* @Extbase\ORM\Cascade("remove")
* @var \WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepname
*/
protected $stepname;
/**
* The ratings of this object
*
* @Extbase\ORM\Lazy
* @Extbase\ORM\Cascade("remove")
* @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\WapplerSystems\BookmarksLikesRatings\Domain\Model\Vote>
*/
protected $votes;
/**
* @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
*/
protected $objectManager;
/**
* @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
*/
public function injectObjectManager(ObjectManagerInterface $objectManager)
{
$this->objectManager = $objectManager;
}
/**
* @var \WapplerSystems\BookmarksLikesRatings\Domain\Repository\StepnameRepository $stepnameRepository
*/
protected $stepnameRepository;
/**
* @param \WapplerSystems\BookmarksLikesRatings\Domain\Repository\StepnameRepository $stepnameRepository
*/
public function injectStepnameRepository(StepnameRepository $stepnameRepository)
{
$this->stepnameRepository = $stepnameRepository;
}
/**
* @var \WapplerSystems\BookmarksLikesRatings\Service\ExtensionHelperService
*/
protected $extensionHelperService;
/**
* @param \WapplerSystems\BookmarksLikesRatings\Service\ExtensionHelperService $extensionHelperService
*/
public function injectExtensionHelperService(ExtensionHelperService $extensionHelperService)
{
$this->extensionHelperService = $extensionHelperService;
}
/**
* Constructs a new stepconfig object
* @param \WapplerSystems\BookmarksLikesRatings\Domain\Model\Ratingobject|null $ratingobject
* @param int|null $steporder
*/
public function __construct(Ratingobject $ratingobject = null, $steporder = null)
{
if ($ratingobject) {
$this->setRatingobject($ratingobject);
}
if ($steporder) {
$this->setSteporder($steporder);
}
$this->initializeObject();
}
/**
* Initializes a new stepconf object
*/
public function initializeObject()
{
//Initialize vote storage if rating is new
if (!is_object($this->votes)) {
$this->votes = new ObjectStorage();
}
}
/**
* Sets the ratingobject this rating is part of
*
* @param \WapplerSystems\BookmarksLikesRatings\Domain\Model\Ratingobject $ratingobject The Rating
*/
public function setRatingobject(Ratingobject $ratingobject)
{
$this->ratingobject = $ratingobject;
$this->setPid($ratingobject->getPid());
}
/**
* Returns the ratingobject this rating is part of
*
* @return \WapplerSystems\BookmarksLikesRatings\Domain\Model\Ratingobject|null
*/
public function getRatingobject()
{
return $this->ratingobject;
}
/**
* Sets the stepconfig order
*
* @param int $steporder
*/
public function setSteporder($steporder)
{
$this->steporder = $steporder;
}
/**
* Gets the stepconfig order
*
* @return int stepconfig position
*/
public function getSteporder(): int
{
return $this->steporder;
}
/**
* Sets the stepconfig value
*
* @param int $stepweight
*/
public function setStepweight($stepweight)
{
$this->stepweight = $stepweight;
}
/**
* Gets the stepconfig value
* If not set steporder is copied
*
* @return int Stepconfig value
*/
public function getStepweight()
{
empty($this->stepweight) && $this->stepweight = $this->steporder;
return $this->stepweight;
}
/**
* Adds a localized stepname to this stepconf
*
* @param \WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepname $stepname
* @throws \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException
* @throws \TYPO3\CMS\Extbase\Persistence\Exception\InvalidQueryException
* @return bool
*/
public function addStepname(Stepname $stepname): bool
{
$success = true;
$stepname->setStepconf($this);
if (!$this->stepnameRepository->existStepname($stepname)) {
$defaultLanguageObject = $this->stepnameRepository->findDefaultStepname($stepname);
if (is_object($defaultLanguageObject)) {
//handle localization if an entry for the default language exists
$stepname->setL18nParent($defaultLanguageObject->getUid());
}
$this->stepnameRepository->add($stepname);
$this->extensionHelperService->persistRepository(StepnameRepository::class, $stepname);
$stepname->getStepconf()->getStepname();
$this->extensionHelperService->persistRepository(StepconfRepository::class, $this);
$this->extensionHelperService->clearDynamicCssFile();
$this->stepname = $stepname;
} else {
//warning - existing stepname entry for a language will not be overwritten
$success = false;
}
return $success;
}
/**
* Returns the localized stepname object of this stepconf
*
* @return \WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepname|null
*/
public function getStepname(): ?Stepname
{
/* @phpstan-ignore-next-line */
if ($this->stepname instanceof LazyLoadingProxy) {
$this->stepname = $this->stepname->_loadRealInstance();
}
return $this->stepname;
}
/**
* Returns all votes in this rating
*
* @return \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\WapplerSystems\BookmarksLikesRatings\Domain\Model\Vote>
*/
public function getVotes()
{
return clone $this->votes;
}
/**
* Method to use Object as plain string
*
* @return string
*/
public function __toString()
{
$stepnameText = $this->getStepname();
if (!$stepnameText) {
$stepnameText = $this->getSteporder();
}
return (string)$stepnameText;
}
}

View File

@@ -0,0 +1,158 @@
<?php
declare(strict_types = 1);
/*
* 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.
*/
namespace WapplerSystems\BookmarksLikesRatings\Domain\Model;
use TYPO3\CMS\Extbase\Annotation as Extbase;
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
/**
* Model for ratingstep configuration names
*
* @copyright Copyright belongs to the respective authors
* @license http://opensource.org/licenses/gpl-license.php GNU Public License, version 2
* @entity
*/
class Stepname extends AbstractEntity
{
/**
* @Extbase\Validate("\WapplerSystems\BookmarksLikesRatings\Domain\Validator\StepconfValidator")
* @Extbase\Validate("NotEmpty")
* @var \WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepconf
*/
protected $stepconf;
/**
* The name of this config entry
*
* @var string Name or description to display
*/
protected $stepname;
/**
* Localization entry
* workaround to help avoiding bug in Typo 4.7 handling localized objects
*
* @var int
*/
protected $l18nParent;
/**
* @var int
*/
protected $sysLanguageUid;
/**
* Sets the stepconf this rating is part of
*
* @param \WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepconf $stepconf The Rating
*/
public function setStepconf(Stepconf $stepconf): void
{
$this->stepconf = $stepconf;
$this->setPid($stepconf->getPid());
}
/**
* Returns the stepconf this rating is part of
*
* @return \WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepconf The stepconf this rating is part of
*/
public function getStepconf(): Stepconf
{
return $this->stepconf;
}
/**
* Sets the stepconfig name
*
* @param string $stepname
*/
public function setStepname($stepname): void
{
$this->stepname = $stepname;
}
/**
* Gets the stepconfig name
* If not set stepweight is copied
*
* @return string Stepconfig name
*/
public function getStepname(): string
{
$value = $this->stepname;
if (stripos($value, 'LLL:') === 0) {
$value = 'stepnames.' . substr($value, 4);
$value = LocalizationUtility::translate($value, 'ThRating');
}
if (empty($value)) {
$value = (string)$this->getStepconf()->getSteporder();
}
return $value;
}
/**
* @return int
*/
/** @noinspection PhpUnused */
public function getL18nParent(): int
{
return $this->l18nParent;
}
/**
* @param int $l18nParent
*/
public function setL18nParent($l18nParent): void
{
$this->l18nParent = $l18nParent;
}
/**
* Get sys language
*
* @return int
*/
public function getSysLanguageUid(): int
{
return $this->_languageUid;
}
/**
* Set sys language
*
* @param int $sysLanguageUid language uid
*/
public function setSysLanguageUid($sysLanguageUid): void
{
$this->_languageUid = $sysLanguageUid;
}
/**
* @return bool
*/
public function isValid(): bool
{
return !empty($this->stepconf);
}
/**
* Method to use Object as plain string
*
* @return string
*/
public function __toString(): string
{
return $this->getStepname();
}
}

View File

@@ -0,0 +1,242 @@
<?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.
*/
namespace WapplerSystems\BookmarksLikesRatings\Domain\Model;
use WapplerSystems\BookmarksLikesRatings\Service\ExtensionHelperService;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Annotation as Extbase;
use TYPO3\CMS\Extbase\Configuration\ConfigurationManager;
use TYPO3\CMS\Extbase\Configuration\Exception\InvalidConfigurationTypeException;
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
use TYPO3\CMS\Extbase\Object\ObjectManager;
use TYPO3\CMS\Extbase\Object\ObjectManagerInterface;
/**
* Model for rating votes
*
* @copyright Copyright belongs to the respective authors
* @license http://opensource.org/licenses/gpl-license.php GNU Public License, version 2
* @entity
*/
class Vote extends AbstractEntity
{
/**
* @Extbase\Validate("\WapplerSystems\BookmarksLikesRatings\Domain\Validator\RatingValidator")
* @Extbase\Validate("NotEmpty")
* @var \WapplerSystems\BookmarksLikesRatings\Domain\Model\Rating
*/
protected $rating;
/**
* The voter of this object
*
* @Extbase\Validate("NotEmpty")
* @var \WapplerSystems\BookmarksLikesRatings\Domain\Model\Voter
*/
protected $voter;
/**
* The actual voting of this object
*
* @Extbase\Validate("\WapplerSystems\BookmarksLikesRatings\Domain\Validator\StepconfValidator")
* @Extbase\Validate("NotEmpty")
* @var \WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepconf
*/
protected $vote;
/**
* @var array
*/
protected $settings;
/**
* @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
*/
protected $objectManager;
/**
* @var \TYPO3\CMS\Core\Log\Logger
*/
protected $logger;
/**
* @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
*/
public function injectObjectManager(ObjectManagerInterface $objectManager)
{
$this->objectManager = $objectManager;
}
/**
* @var \WapplerSystems\BookmarksLikesRatings\Service\ExtensionHelperService
*/
protected $extensionHelperService;
/**
* @param \WapplerSystems\BookmarksLikesRatings\Service\ExtensionHelperService $extensionHelperService
*/
public function injectExtensionHelperService(ExtensionHelperService $extensionHelperService): void
{
$this->extensionHelperService = $extensionHelperService;
}
/**
* Constructs a new rating object
*
* @param \WapplerSystems\BookmarksLikesRatings\Domain\Model\Rating|null $rating
* @param \WapplerSystems\BookmarksLikesRatings\Domain\Model\Voter|null $voter
* @param \WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepconf|null $vote
* @throws InvalidConfigurationTypeException
*/
/** @noinspection PhpUnused */
public function __construct(
Rating $rating = null,
Voter $voter = null,
Stepconf $vote = null
) {
if ($rating) {
$this->setRating($rating);
}
if ($voter) {
$this->setVoter($voter);
}
if ($vote) {
$this->setVote($vote);
}
$this->initializeObject();
}
/**
* Initializes the new vote object
* @throws \TYPO3\CMS\Extbase\Configuration\Exception\InvalidConfigurationTypeException
*/
public function initializeObject()
{
if (empty($this->objectManager)) {
$this->objectManager = GeneralUtility::makeInstance(ObjectManager::class);
}
if (empty($this->extensionHelperService)) {
$this->extensionHelperService = GeneralUtility::makeInstance(ExtensionHelperService::class);
}
$this->logger = $this->extensionHelperService->getLogger(__CLASS__);
$this->settings = $this->objectManager->get(ConfigurationManager::class)->getConfiguration(
'Settings',
'thRating',
'pi1'
);
//\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($this,get_class($this).' initializeObject');
}
/**
* Sets the rating this vote is part of
*
* @param \WapplerSystems\BookmarksLikesRatings\Domain\Model\Rating $rating The Rating
*/
public function setRating(Rating $rating)
{
$this->rating = $rating;
$this->setPid($rating->getPid());
}
/**
* Returns the rating this vote is part of
*
* @return \WapplerSystems\BookmarksLikesRatings\Domain\Model\Rating The rating this vote is part of
*/
public function getRating(): Rating
{
return $this->rating;
}
/**
* Sets the frontenduser of this vote
*
* @param \WapplerSystems\BookmarksLikesRatings\Domain\Model\Voter $voter The frontenduser
*/
public function setVoter(Voter $voter)
{
$this->voter = $voter;
}
/**
* Returns the frontenduser of this vote
*
* @return \WapplerSystems\BookmarksLikesRatings\Domain\Model\Voter|null
*/
public function getVoter(): ?Voter
{
return $this->voter;
}
/**
* Sets the choosen stepconfig
*
* @param \WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepconf $vote
*/
public function setVote($vote)
{
$this->vote = $vote;
}
/**
* Gets the rating object uid
*
* @return \WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepconf|null Reference to selected stepconfig
*/
public function getVote()
{
return $this->vote;
}
/**
* Sets the rating this vote is part of
*
* @return bool
*/
/** @noinspection PhpUnused */
public function hasRated()
{
return $this->getVote() !== null && ($this->getVote() instanceof Stepconf);
}
/**
* Checks if vote is done by anonymous user
*
* @return bool
*/
public function isAnonymous(): bool
{
return !empty($this->settings['mapAnonymous']) && !empty($this->getVoter()) &&
$this->getVoter()->getUid() === (int)$this->settings['mapAnonymous'];
}
/**
* Checks cookie if anonymous vote is already done
* always false if cookie checks is deactivated
*
* @param string $prefixId Extension prefix to identify cookie
* @return bool
*/
public function hasAnonymousVote($prefixId = 'DummyPrefix'): bool
{
$anonymousRating = GeneralUtility::makeInstance(\WapplerSystems\BookmarksLikesRatings\Service\JsonService::class)
->decodeJsonToArray($_COOKIE[$prefixId . '_AnonymousRating_' . $this->getRating()->getUid()]);
return !empty($anonymousRating['voteUid']);
}
/**
* Method to use Object as plain string
*
* @return string
*/
public function __toString(): string
{
return (string)$this->getVote();
}
}

View File

@@ -0,0 +1,17 @@
<?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.
*/
namespace WapplerSystems\BookmarksLikesRatings\Domain\Model;
/**
* The voter
*/
class Voter extends \TYPO3\CMS\Extbase\Domain\Model\FrontendUser
{
}

View File

@@ -0,0 +1,89 @@
<?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.
*/
namespace WapplerSystems\BookmarksLikesRatings\Domain\Repository;
use WapplerSystems\BookmarksLikesRatings\Domain\Model\Rating;
use WapplerSystems\BookmarksLikesRatings\Domain\Model\Ratingobject;
use WapplerSystems\BookmarksLikesRatings\Domain\Validator\RatingValidator;
use WapplerSystems\BookmarksLikesRatings\Service\ExtensionHelperService;
use TYPO3\CMS\Extbase\Annotation as Extbase;
use TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException;
use TYPO3\CMS\Extbase\Persistence\Repository;
/**
* A repository for ratings
*/
class RatingRepository extends Repository
{
/**
* Defines name for function parameter
*/
public const ADD_IF_NOT_FOUND = true;
/**
* @var \WapplerSystems\BookmarksLikesRatings\Service\ExtensionHelperService
*/
protected $extensionHelperService;
/**
* @param \WapplerSystems\BookmarksLikesRatings\Service\ExtensionHelperService $extensionHelperService
*/
public function injectExtensionHelperService(ExtensionHelperService $extensionHelperService): void
{
$this->extensionHelperService = $extensionHelperService;
}
/**
* Finds the specific rating by giving the object and row uid
*
* @Extbase\Validate("\WapplerSystems\BookmarksLikesRatings\Domain\Validator\RatingobjectValidator", param="ratingobject")
* @param \WapplerSystems\BookmarksLikesRatings\Domain\Model\Ratingobject $ratingobject The concerned ratingobject
* @Extbase\Validate("NumberRange", options={"minimum": 1}, param="ratedobjectuid")
* @param int $ratedobjectuid The Uid of the rated row
* @param bool $addIfNotFound Set to true if new objects should instantly be added
* @return Rating
* @throws IllegalObjectTypeException
*/
public function findMatchingObjectAndUid(
Ratingobject $ratingobject,
int $ratedobjectuid,
$addIfNotFound = false
): Rating {
/** @var \WapplerSystems\BookmarksLikesRatings\Domain\Model\Rating $foundRow */
$foundRow = $this->objectManager->get(Rating::class);
$query = $this->createQuery();
$query->matching($query->logicalAnd(
[
$query->equals('ratingobject', $ratingobject->getUid()),
$query->equals('ratedobjectuid', $ratedobjectuid)
]
))->setLimit(1);
/*$queryParser = $this->objectManager->get(\TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser::class);
\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($queryParser->convertQueryToDoctrineQueryBuilder($query)->getSQL(), get_class($this).' SQL');
\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($queryParser->convertQueryToDoctrineQueryBuilder($query)->getParameters(), get_class($this).' SQL Parameter');*/
$queryResult = $query->execute();
if ($queryResult->count() > 0) {
$foundRow = $queryResult->getFirst();
} elseif ($addIfNotFound) {
$foundRow->setRatingobject($ratingobject);
$foundRow->setRatedobjectuid($ratedobjectuid);
$validator = $this->objectManager->get(RatingValidator::class);
if (!$validator->validate($foundRow)->hasErrors()) {
$this->add($foundRow);
}
$this->extensionHelperService->persistRepository(__CLASS__, $foundRow);
$foundRow = $this->findMatchingObjectAndUid($ratingobject, $ratedobjectuid);
}
return $foundRow;
}
}

View File

@@ -0,0 +1,114 @@
<?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.
*/
namespace WapplerSystems\BookmarksLikesRatings\Domain\Repository;
use WapplerSystems\BookmarksLikesRatings\Domain\Model\Ratingobject;
use WapplerSystems\BookmarksLikesRatings\Domain\Validator\RatingobjectValidator;
use WapplerSystems\BookmarksLikesRatings\Exception\RecordNotFoundException;
use WapplerSystems\BookmarksLikesRatings\Service\ExtensionHelperService;
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
use TYPO3\CMS\Extbase\Persistence\Repository;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
/**
* A repository for rating objects
*/
class RatingobjectRepository extends Repository
{
/**
* Defines name for function parameter
*/
public const ADD_IF_NOT_FOUND = true;
/**
* @var \WapplerSystems\BookmarksLikesRatings\Service\ExtensionHelperService
*/
protected $extensionHelperService;
/**
* @param \WapplerSystems\BookmarksLikesRatings\Service\ExtensionHelperService $extensionHelperService
*/
public function injectExtensionHelperService(ExtensionHelperService $extensionHelperService): void
{
$this->extensionHelperService = $extensionHelperService;
}
/**
* @var \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface
*/
protected $configurationManager;
/**
* @param \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface $configurationManager
*/
public function injectConfigurationManager(ConfigurationManagerInterface $configurationManager): void
{
$this->configurationManager = $configurationManager;
}
/**
* Finds the specific ratingobject by giving table and fieldname
*
* @param string $ratetable The tablename of the ratingobject
* @param string $ratefield The fieldname of the ratingobject
* @param bool $addIfNotFound Set to true if new objects should instantly be added
* @return \WapplerSystems\BookmarksLikesRatings\Domain\Model\Ratingobject The ratingobject
* @throws RecordNotFoundException
* @throws \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException
*/
public function findMatchingTableAndField(string $ratetable, string $ratefield, bool $addIfNotFound = false): Ratingobject
{
/** @var \WapplerSystems\BookmarksLikesRatings\Domain\Model\Ratingobject $foundRow */
$foundRow = $this->objectManager->get(Ratingobject::class);
$query = $this->createQuery();
$query->matching($query->logicalAnd([
$query->equals('ratetable', $ratetable),
$query->equals('ratefield', $ratefield),
]))->setLimit(1);
/*$queryParser = $this->objectManager->get(\TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser::class);
\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($queryParser->convertQueryToDoctrineQueryBuilder($query)->getSQL(), get_class($this).' SQL');
\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($queryParser->convertQueryToDoctrineQueryBuilder($query)->getParameters(), get_class($this).' SQL Parameter');*/
/** @var \TYPO3\CMS\Extbase\Persistence\QueryResultInterface $queryResult */
$queryResult = $query->execute();
if ($queryResult->count() > 0) {
$foundRow = $queryResult->getFirst();
} elseif ($addIfNotFound) {
$foundRow->setRatetable($ratetable);
$foundRow->setRatefield($ratefield);
if (!$this->objectManager->get(RatingobjectValidator::class)->validate($foundRow)->hasErrors()) {
$this->add($foundRow);
}
$this->extensionHelperService->persistRepository(self::class, $foundRow);
$foundRow = $this->findMatchingTableAndField($ratetable, $ratefield);
} else {
throw new RecordNotFoundException(LocalizationUtility::translate('recordNotFound', 'ThRating'), 1567962473);
}
return $foundRow;
}
/**
* Finds the specific ratingobject by giving table and fieldname
*
* @param bool Switch to fetch ALL entries regardless of their pid
* @return \TYPO3\CMS\Extbase\Persistence\QueryResultInterface|array All ratingobjects of the site
*/
/** @noinspection PhpMissingParentCallCommonInspection */
public function findAll($ignoreStoragePage = false)
{
$query = $this->createQuery();
$query->getQuerySettings()->setRespectStoragePage(!$ignoreStoragePage);
return $query->execute();
}
}

View File

@@ -0,0 +1,78 @@
<?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.
*/
namespace WapplerSystems\BookmarksLikesRatings\Domain\Repository;
use WapplerSystems\BookmarksLikesRatings\Domain\Model\Ratingobject;
use WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepconf;
use WapplerSystems\BookmarksLikesRatings\Domain\Validator\StepconfValidator;
use TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface;
use TYPO3\CMS\Extbase\Persistence\QueryInterface;
use TYPO3\CMS\Extbase\Persistence\Repository;
/**
* A repository for ratingstep configurations
* @method findByRatingobject(Ratingobject $getRatingobject)
*/
class StepconfRepository extends Repository
{
protected $defaultOrderings = ['steporder' => QueryInterface::ORDER_ASCENDING];
/**
* Initialize this repository
*/
public function initializeObject(): void
{
//disable RespectStoragePage as pid is always bound to parent objects pid
/** @var \TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface $defaultQuerySettings */
$defaultQuerySettings = $this->objectManager->get(QuerySettingsInterface::class);
$defaultQuerySettings->setRespectStoragePage(false);
$this->setDefaultQuerySettings($defaultQuerySettings);
}
/**
* Finds the given stepconf object in the repository
*
* @param \WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepconf $stepconf The ratingobject to look for
* @return \WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepconf
*/
public function findStepconfObject(Stepconf $stepconf): Stepconf
{
$query = $this->createQuery();
/** @noinspection NullPointerExceptionInspection */
$query->matching($query->logicalAnd([
$query->equals('ratingobject', $stepconf->getRatingobject()->getUid()),
$query->equals('steporder', $stepconf->getSteporder()),
]))->setLimit(1);
$queryResult = $query->execute();
/** @var \WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepconf $foundRow */
$foundRow = $this->objectManager->get(Stepconf::class);
if (count($queryResult) !== 0) {
$foundRow = $queryResult->getFirst();
}
return $foundRow;
}
/**
* Finds the ratingstep entry by giving ratingobjectUid
*
* @param \WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepconf $stepconf The uid of the ratingobject
* @return bool true if stepconf object exists in repository
*/
public function existStepconf(Stepconf $stepconf): bool
{
$foundRow = $this->findStepconfObject($stepconf);
$stepconfValidator = $this->objectManager->get(StepconfValidator::class);
return !$stepconfValidator->validate($foundRow)->hasErrors();
}
}

View File

@@ -0,0 +1,255 @@
<?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.
*/
namespace WapplerSystems\BookmarksLikesRatings\Domain\Repository;
use InvalidArgumentException;
use Psr\Http\Message\ServerRequestInterface;
use WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepname;
use WapplerSystems\BookmarksLikesRatings\Service\ExtensionHelperService;
use TYPO3\CMS\Core\Site\Entity\Site;
use TYPO3\CMS\Extbase\Persistence\Exception\InvalidQueryException;
use TYPO3\CMS\Extbase\Persistence\QueryInterface;
use TYPO3\CMS\Extbase\Persistence\QueryResultInterface;
use TYPO3\CMS\Extbase\Persistence\Repository;
/**
* A repository for ratingstep configurations
*/
class StepnameRepository extends Repository
{
protected const TABLE_NAME = 'tx_thrating_domain_model_stepname';
protected const STEPCONF_NAME = 'stepconf';
/**
* @var string $syslangUidLiteral
*/
protected $syslangUidLiteral;
/**
* @var array
*/
protected $defaultOrderings;
/**
* Initialize this repository
*/
public function initializeObject(): void
{
$this->syslangUidLiteral = $GLOBALS['TCA'][self::TABLE_NAME]['ctrl']['languageField'];
$this->defaultOrderings = [ $this->syslangUidLiteral => QueryInterface::ORDER_ASCENDING];
}
/**
* Checks if stepname got a valid language code
*
* @param Stepname $stepname The stepname object
* @return bool
*/
public function checkStepnameLanguage(Stepname $stepname): bool
{
$stepnameLang = $stepname->getSysLanguageUid();
if ($stepnameLang > 0) {
//check if given language exist
try {
// only get language and do not assign the result to check if it exists
$this->objectManager
->get(ExtensionHelperService::class)
->getStaticLanguageById($stepnameLang);
} catch (InvalidArgumentException $exception) {
//invalid language code -> NOK
return false;
}
}
//language code found -> OK
return true;
}
/**
* Finds the given stepconf object in the repository
*
* @param Stepname $stepname The ratingname to look for
* @return Stepname|null
*/
public function findStepnameObject(Stepname $stepname): ?Stepname
{
$query = $this->createQuery();
$query->getQuerySettings()->setRespectSysLanguage(false);
$query->getQuerySettings()->setLanguageOverlayMode(false);
$query->matching(
$query->logicalAnd(
[
$query->equals(self::STEPCONF_NAME, $stepname->getStepconf()),
$query->equals($this->syslangUidLiteral, $stepname->getSysLanguageUid()),
]
)
)->setLimit(1);
/** @var \TYPO3\CMS\Extbase\Persistence\QueryResultInterface $queryResult */
$queryResult = $query->execute();
/*
$queryParser = $this->objectManager->get(\TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser::class);
\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($queryParser->convertQueryToDoctrineQueryBuilder($query)->getSQL(), get_class($this).' SQL');
\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($queryParser->convertQueryToDoctrineQueryBuilder($query)->getParameters(), get_class($this).' SQL Parameter');
*/
/** @var \WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepname $foundRow */
$foundRow = null;
if ($queryResult->count() > 0) {
$foundRow = $queryResult->getFirst();
}
return $foundRow;
}
/**
* Finds the given stepname object in the repository
*
* @param int $uid
* @return Stepname|null
*/
public function findStrictByUid(int $uid): ?Stepname
{
$query = $this->createQuery();
$query->getQuerySettings()->setRespectSysLanguage(false);
$query->getQuerySettings()->setRespectStoragePage(false);
$query->getQuerySettings()->setLanguageOverlayMode(false);
$query->matching(
$query->logicalAnd(
[$query->equals('uid', $uid)]
)
)->setLimit(1);
$queryResult = $query->execute();
/** @var Stepname $foundRow */
$foundRow = null;
if ($queryResult->count() > 0) {
$foundRow = $queryResult->getFirst();
}
return $foundRow;
}
/**
* Check on double language entries
*
* @param Stepname $stepname The ratingname to look for
* @return array return values false says OK
*/
public function checkConsistency(Stepname $stepname): array
{
$query = $this->createQuery();
$query ->getQuerySettings()->setRespectSysLanguage(false);
$query ->matching(
$query->equals(self::STEPCONF_NAME, $stepname->getStepconf()->getUid())
);
$queryResult = $query
->execute(true);
$checkConsistency = [];
if (count($queryResult) > 1) {
$websiteLanguagesArray = [];
$allWebsiteLanguages = $this->getCurrentSite()->getAllLanguages();
/** @var \TYPO3\CMS\Core\Site\Entity\SiteLanguage $language */
foreach (array_values($allWebsiteLanguages) as $language) {
$websiteLanguagesArray[] = $language->getLanguageId();
}
$languageCounter = [];
foreach (array_values($queryResult) as $value) {
$languageUid = $value[$this->syslangUidLiteral];
$languageCounter[$languageUid]++;
if ($languageCounter[$languageUid] > 1) {
$checkConsistency['doubleLang'] = true;
}
//check if language flag exists in current website
if (($languageUid > 0) && in_array($languageUid, $websiteLanguagesArray, true)) {
$checkConsistency['existLang'] = true;
}
}
}
return $checkConsistency;
}
/**
* Finds the default language stepconf by giving ratingobject and steporder
*
* @param \WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepname $stepname The ratingname to look for
* @throws InvalidQueryException
* @return Stepname|null The stepname in default language
* @var Stepname $foundRow
*/
public function findDefaultStepname(Stepname $stepname): ?Stepname
{
$foundRow = $this->objectManager->get(Stepname::class);
$query = $this->createQuery();
$query->getQuerySettings()->setRespectSysLanguage(false);
$query->getQuerySettings()->setLanguageOverlayMode(false);
$query->matching(
$query->logicalAnd(
[
$query->equals(self::STEPCONF_NAME, $stepname->getStepconf()),
$query->in($this->syslangUidLiteral, [0, -1])
]
)
)->setLimit(1);
/** @var QueryResultInterface $queryResult */
$queryResult = $query->execute();
/*
$queryParser = $this->objectManager->get(\TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser::class);
\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($queryParser->convertQueryToDoctrineQueryBuilder($query)->getSQL(), get_class($this).' SQL');
\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($queryParser->convertQueryToDoctrineQueryBuilder($query)->getParameters(), get_class($this).' SQL Parameter');
*/
/** @var Stepname $foundRow */
$foundRow = null;
if ($queryResult->count() > 0) {
$foundRow = $queryResult->getFirst();
}
return $foundRow;
}
/**
* Finds the localized ratingstep entry by giving ratingobjectUid
*
* @param Stepname $stepname The ratingname to look for
* @return bool true if stepconf having same steporder and _languageUid exists
*/
public function existStepname(Stepname $stepname): bool
{
$lookForStepname = $this->findStepnameObject($stepname);
return !is_null($lookForStepname);
}
/**
* Set default query settings to find ALL records
*/
public function clearQuerySettings(): void
{
$querySettings = $this->createQuery()->getQuerySettings();
$querySettings->setRespectSysLanguage(true);
$querySettings->setIgnoreEnableFields(true);
$querySettings->setLanguageOverlayMode(false);
$this->setDefaultQuerySettings($querySettings);
}
protected function getCurrentSite(): ?Site
{
if ($GLOBALS['TYPO3_REQUEST'] instanceof ServerRequestInterface
&& $GLOBALS['TYPO3_REQUEST']->getAttribute('site') instanceof Site) {
return $GLOBALS['TYPO3_REQUEST']->getAttribute('site');
}
return null;
}
}

View File

@@ -0,0 +1,105 @@
<?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.
*/
namespace WapplerSystems\BookmarksLikesRatings\Domain\Repository;
use WapplerSystems\BookmarksLikesRatings\Domain\Model\Rating;
use WapplerSystems\BookmarksLikesRatings\Domain\Model\Vote;
use WapplerSystems\BookmarksLikesRatings\Domain\Model\Voter;
use TYPO3\CMS\Extbase\Persistence\Repository;
/**
* A repository for votes
*/
class VoteRepository extends Repository
{
/**
* Defines name for function parameter
*/
public const /** @noinspection PhpUnused */
ADD_IF_NOT_FOUND = true;
/**
* Initialize this repository
*/
/** @noinspection PhpUnused */
public function initializeObject(): void
{
}
/**
* Finds the voting by giving the rating and voter objects
*
* @param Rating|null $rating The concerned ratingobject
* @param Voter|null $voter The Uid of the rated row
* @return Vote|object The voting
*/
public function findMatchingRatingAndVoter($rating = null, $voter = null)
{
/** @var \TYPO3\CMS\Extbase\Persistence\QueryInterface $query */
$query = $this->createQuery();
return $query->matching(
$query->logicalAnd(
[
$query->equals('rating', $rating),
$query->equals('voter', $voter)
]
)
)->execute()->getFirst();
}
/**
* Counts all votings by giving the rating and ratingstep
*
* @param Rating $rating The concerned ratingobject
* @param \WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepconf $stepconf The stepconf object
* @return int
*/
public function countByMatchingRatingAndVote($rating = null, $stepconf = null): int
{
$query = $this->createQuery();
$query->matching($query->logicalAnd(
[
$query->equals('rating', $rating->getUid()),
$query->equals('vote', $stepconf->getUid())
]
));
return count($query->execute());
}
/**
* Counts all anonymous votings by giving the rating and ratingstep
*
* @param Rating $rating The concerned ratingobject
* @param \WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepconf $stepconf The stepconf object
* @param int $anonymousVoter UID of the anonymous account
* @return int
*/
public function countAnonymousByMatchingRatingAndVote($rating = null, $stepconf = null, $anonymousVoter = null): int
{
/** @var int $count */
$count = 0;
if ($anonymousVoter !== null) {
$query = $this->createQuery();
$query->matching(
$query->logicalAnd([
$query->equals('rating', $rating->getUid()),
$query->equals('vote', $stepconf->getUid()),
$query->equals('voter', $anonymousVoter),
])
);
$count = count($query->execute());
}
return $count;
}
}

View File

@@ -0,0 +1,31 @@
<?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.
*/
namespace WapplerSystems\BookmarksLikesRatings\Domain\Repository;
use TYPO3\CMS\Extbase\Domain\Repository\FrontendUserRepository;
use TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface;
/**
* A repository for votes
*/
class VoterRepository extends FrontendUserRepository
{
/**
* Initialze this repository
*/
public function initializeObject()
{
//Even hidden or deleted FE Users should be found
/** @var \TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface $querySettings */
$querySettings = $this->objectManager->get(QuerySettingsInterface::class);
$querySettings->setIgnoreEnableFields(true);
$this->setDefaultQuerySettings($querySettings);
}
}

View File

@@ -0,0 +1,60 @@
<?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.
*/
namespace WapplerSystems\BookmarksLikesRatings\Domain\Validator;
use WapplerSystems\BookmarksLikesRatings\Domain\Model\Rating;
use WapplerSystems\BookmarksLikesRatings\Domain\Model\Ratingobject;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
use TYPO3\CMS\Extbase\Validation\Validator\AbstractValidator;
/**
* A validator for Ratings
*
* @copyright Copyright belongs to the respective authors
* @scope singleton
*/
class RatingValidator extends AbstractValidator
{
/**
* This validator always needs to be executed even if the given value is empty.
* See AbstractValidator::validate()
*
* @var bool
*/
protected $acceptsEmptyValues = false;
/**
* If the given Rating is valid
*
* @param \WapplerSystems\BookmarksLikesRatings\Domain\Model\Rating $rating
* @noinspection PhpUnnecessaryFullyQualifiedNameInspection
*/
protected function isValid($rating): void
{
/** @noinspection NotOptimalIfConditionsInspection */
if (!$this->isEmpty($rating) && $rating instanceof Rating) {
$ratedobjectuid = $rating->getRatedobjectuid();
if (empty($ratedobjectuid)) {
$this->addError(
LocalizationUtility::translate('error.validator.rating.ratedobjectuid', 'ThRating'),
1283536994
);
}
if (!$rating->getRatingobject() instanceof Ratingobject) {
$this->addError(
LocalizationUtility::translate('error.validator.rating.ratingobject', 'ThRating'),
1283538549
);
}
} else {
$this->addError(LocalizationUtility::translate('error.validator.rating.empty', 'ThRating'), 1568138421);
}
}
}

View File

@@ -0,0 +1,54 @@
<?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.
*/
namespace WapplerSystems\BookmarksLikesRatings\Domain\Validator;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
use TYPO3\CMS\Extbase\Validation\Validator\AbstractValidator;
/**
* A validator for Ratingobjects
*
* @copyright Copyright belongs to the respective author
* @scope singleton
*/
class RatingobjectValidator extends AbstractValidator
{
/**
* If the given Ratingobject is valid
*
* @param \WapplerSystems\BookmarksLikesRatings\Domain\Model\Ratingobject $ratingobject The ratingobject
*/
protected function isValid($ratingobject)
{
/** @var string $ratetable */
$ratetable = $ratingobject->getRatetable();
/** @var string $ratefield */
$ratefield = $ratingobject->getRatefield();
if (empty($ratetable)) {
$this->addError(
LocalizationUtility::translate(
'error.validator.ratingobject_table_extbase',
'ThRating'
),
1283528638
);
}
if (empty($ratefield)) {
$this->addError(
LocalizationUtility::translate(
'error.validator.ratingobject_field_extbase',
'ThRating'
),
1283536038
);
}
}
}

View File

@@ -0,0 +1,185 @@
<?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 PhpUnnecessaryFullyQualifiedNameInspection */
namespace WapplerSystems\BookmarksLikesRatings\Domain\Validator;
use WapplerSystems\BookmarksLikesRatings\Domain\Model\Ratingobject;
use WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepconf;
use WapplerSystems\BookmarksLikesRatings\Domain\Repository\StepconfRepository;
use WapplerSystems\BookmarksLikesRatings\Domain\Repository\StepnameRepository;
use TYPO3\CMS\Extbase\Persistence\Exception\InvalidQueryException;
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
use TYPO3\CMS\Extbase\Validation\Validator\AbstractValidator;
/**
* A validator for Ratings
*
* @copyright Copyright belongs to the respective authors
* @scope singleton
*/
class StepconfValidator extends AbstractValidator
{
/**
* @var \WapplerSystems\BookmarksLikesRatings\Domain\Repository\StepconfRepository
*/
protected $stepconfRepository;
/**
* @param \WapplerSystems\BookmarksLikesRatings\Domain\Repository\StepconfRepository $stepconfRepository
*/
public function injectStepconfRepository(StepconfRepository $stepconfRepository)
{
$this->stepconfRepository = $stepconfRepository;
}
/**
* @var \WapplerSystems\BookmarksLikesRatings\Domain\Repository\StepnameRepository
*/
protected $stepnameRepository;
/**
* @param \WapplerSystems\BookmarksLikesRatings\Domain\Repository\StepnameRepository $stepnameRepository
*/
public function injectStepnameRepository(StepnameRepository $stepnameRepository)
{
$this->stepnameRepository = $stepnameRepository;
}
/**
* If the given step is valid
*
* @param \WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepconf $stepconf
* @throws InvalidQueryException
*/
protected function isValid($stepconf): void
{
/** @noinspection NotOptimalIfConditionsInspection */
if (!$this->isEmpty($stepconf) && $stepconf instanceof Stepconf) {
$this->checkRatingobject($stepconf);
if (!$this->result->hasErrors()) {
$this->checkSteporder($stepconf);
}
if (!$this->result->hasErrors()) {
$this->validateStepnames($stepconf);
}
} else {
$this->addError(LocalizationUtility::translate('error.validator.stepconf.empty', 'ThRating'), 1568139528);
}
}
/**
* A stepconf object must have a ratingobject
* @param Stepconf $stepconf
*/
protected function checkRatingobject(Stepconf $stepconf): void
{
if (!$stepconf->getRatingobject() instanceof Ratingobject) {
$this->addError(
LocalizationUtility::translate('error.validator.stepconf.ratingobject', 'ThRating'),
1284700846
);
}
}
/**
* At least a steporder value must be set and a positive integer ( >0 ) and valid regaing existing values
* @param Stepconf $stepconf
*/
protected function checkSteporder(Stepconf $stepconf): void
{
$steporder = $stepconf->getSteporder();
if (empty($steporder)) {
$this->addError(
LocalizationUtility::translate('error.validator.stepconf.steps', 'ThRating'),
1284700903
);
return;
}
if (!is_int($stepconf->getSteporder()) || $stepconf->getSteporder() < 1) {
$this->addError(
LocalizationUtility::translate(
'error.validator.stepconf.invalidSteporderNumber',
'ThRating'
),
1368123953
);
}
//check if given steporder is valid (integer, maximum +1)
/** @var object $maxSteporderStepconfobject */
$maxSteporderStepconfobject = $this->stepconfRepository->findByRatingobject($stepconf->getRatingobject());
$maxSteporder = $maxSteporderStepconfobject[$maxSteporderStepconfobject->count() - 1]->getSteporder();
if ($stepconf->getSteporder() > $maxSteporder + 1) {
$this->addError(
LocalizationUtility::translate('error.validator.stepconf.maxSteporder', 'ThRating'),
1368123970
);
}
}
/**
* If the given step is valid
*
* @param Stepconf $stepconf
* @throws InvalidQueryException
* @throws \TYPO3\CMS\Extbase\Persistence\Exception\InvalidQueryException
*/
protected function validateStepnames($stepconf): void
{
//check if a stepname is given that at least has the default language definition
//TODO move to query on stepname repository
$stepname = $stepconf->getStepname();
$countNames = 0;
if ($stepname instanceof ObjectStorage) {
$countNames = $stepname->count();
}
if ($countNames != 0) {
/** @var \WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepname $firstStepname */
$firstStepname = $stepname->current();
/** @var \WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepname|object $defaultName */
$defaultName = $this->stepnameRepository->findDefaultStepname($firstStepname);
if (!$defaultName->isValid()) {
$this->addError(
LocalizationUtility::translate(
'error.validator.stepconf.defaultStepname',
'ThRating',
[$firstStepname->getStepconf()->getUid()]
),
1384374165
);
} else {
//Finally check on language consistency
$checkConsistency = $this->stepnameRepository->checkConsistency($firstStepname);
if ($checkConsistency['doubleLang']) {
$this->addError(
LocalizationUtility::translate(
'error.validator.stepconf.doubleLangEntry',
'ThRating',
[$firstStepname->getStepconf()->getUid()]
),
1384374589
);
} elseif ($checkConsistency['existLang']) {
$this->addError(
LocalizationUtility::translate(
'error.validator.stepconf.notExistingLanguage',
'ThRating',
[$firstStepname->getUid()]
),
1384374589
);
}
}
}
}
}

View File

@@ -0,0 +1,72 @@
<?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\Domain\Validator;
use WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepconf;
use WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepname;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
use TYPO3\CMS\Extbase\Validation\Validator\AbstractValidator;
/**
* A validator for Ratings
*
* @copyright Copyright belongs to the respective authors
* @scope singleton
*/
class StepnameValidator extends AbstractValidator
{
/**
* @var \WapplerSystems\BookmarksLikesRatings\Domain\Repository\StepnameRepository
*/
protected $stepnameRepository;
/**
* @param \WapplerSystems\BookmarksLikesRatings\Domain\Repository\StepnameRepository $stepnameRepository
*/
public function injectStepnameRepository(\WapplerSystems\BookmarksLikesRatings\Domain\Repository\StepnameRepository $stepnameRepository)
{
$this->stepnameRepository = $stepnameRepository;
}
/**
* If the given step is valid
*
* @param \WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepname $stepname
* @throws \TYPO3\CMS\Extbase\Persistence\Exception\InvalidQueryException
*/
protected function isValid($stepname): void
{
//a stepname object must have a stepconf
if (!$stepname->getStepconf() instanceof Stepconf) {
$this->addError(
LocalizationUtility::translate('error.validator.stepname.stepconf', 'ThRating'),
1382895072
);
}
//check if given languagecode exists in website
if (!$this->stepnameRepository->checkStepnameLanguage($stepname)) {
$this->addError(LocalizationUtility::translate('error.validator.stepname.sysLang', 'ThRating'), 1382895089);
}
//now check if entry for default language exists
$langUid = $stepname->getSysLanguageUid();
if (!empty($langUid)) {
$defaultStepname = $this->stepnameRepository->findDefaultStepname($stepname);
if (get_class($defaultStepname) !== Stepname::class || $this->validate($defaultStepname)->hasErrors()) {
$this->addError(
LocalizationUtility::translate('error.validator.stepname.defaultLang', 'ThRating'),
1382895097
);
}
}
}
}

View File

@@ -0,0 +1,79 @@
<?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.
*/
namespace WapplerSystems\BookmarksLikesRatings\Domain\Validator;
use WapplerSystems\BookmarksLikesRatings\Domain\Model\Stepconf;
use WapplerSystems\BookmarksLikesRatings\Domain\Model\Vote;
use WapplerSystems\BookmarksLikesRatings\Domain\Model\Voter;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
use TYPO3\CMS\Extbase\Validation\Validator\AbstractValidator;
/**
* A validator for Votes
*
* @copyright Copyright belongs to the respective authors
* @scope singleton
*/
class VoteValidator extends AbstractValidator
{
/**
* This validator always needs to be executed even if the given value is empty.
* See AbstractValidator::validate()
*
* @var bool
*/
protected $acceptsEmptyValues = false;
/**
* If the given Vote is valid
*
* @param \WapplerSystems\BookmarksLikesRatings\Domain\Model\Vote $vote The vote
*/
protected function isValid($vote)
{
/** @noinspection NotOptimalIfConditionsInspection */
if (!$this->isEmpty($vote) && $vote instanceof Vote) {
//a vote object must have a vote
if (!$vote->getVote() instanceof Stepconf) {
$this->addError(LocalizationUtility::translate('error.validator.vote.vote', 'ThRating'), 1283537235);
} else {
//a vote must have a valid voter
if (!$vote->getVoter() instanceof Voter) {
$this->addError(
LocalizationUtility::translate('error.validator.vote.voter', 'ThRating'),
1283540684
);
}
//check if the given vote is a valid step for this ratingobject
if (!$vote->getRating()->getRatingobject()->getStepconfs()->contains($vote->getVote())) {
$this->addError(
LocalizationUtility::translate('error.validator.vote.stepconf', 'ThRating'),
1283612492
);
}
}
} else {
$this->addError(LocalizationUtility::translate('error.validator.vote.empty', 'ThRating'), 1568141014);
}
}
/**
* If the given Vote is set
*
* @param \WapplerSystems\BookmarksLikesRatings\Domain\Model\Vote $vote The vote
* @return bool
*/
public function isObjSet($vote)
{
$result = !$this->isEmpty($vote) && $vote instanceof Vote;
return $result;
}
}