View source
<?php
namespace Drupal\votingapi_reaction;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Render\Renderer;
use Drupal\Core\Session\AccountProxy;
use Drupal\votingapi\Entity\Vote;
use Drupal\votingapi\Entity\VoteType;
use Drupal\votingapi\VoteResultFunctionManager;
use Drupal\votingapi_reaction\Plugin\Field\FieldType\VotingApiReactionItemInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
class VotingApiReactionManager implements ContainerInjectionInterface {
protected $voteStorage;
protected $voteTypeStorage;
protected $fileStorage;
protected $currentUser;
protected $votingApiResults;
protected $renderer;
protected $configFactory;
public function __construct(EntityTypeManagerInterface $entityTypeManager, AccountProxy $currentUser, VoteResultFunctionManager $votingApiResults, Renderer $renderer, ConfigFactoryInterface $configFactory) {
$this->voteStorage = $entityTypeManager
->getStorage('vote');
$this->voteTypeStorage = $entityTypeManager
->getStorage('vote_type');
$this->fileStorage = $entityTypeManager
->getStorage('file');
$this->currentUser = $currentUser;
$this->votingApiResults = $votingApiResults;
$this->renderer = $renderer;
$this->configFactory = $configFactory;
}
public static function create(ContainerInterface $container) {
return new static($container
->get('entity_type.manager'), $container
->get('current_user'), $container
->get('plugin.manager.votingapi.resultfunction'), $container
->get('renderer'), $container
->get('config.factory'));
}
public function lastReaction(Vote $entity, array $settings) {
$query = $this->voteStorage
->getQuery()
->condition('entity_id', $entity
->getVotedEntityId())
->condition('entity_type', $entity
->getVotedEntityType())
->condition('field_name', $entity
->get('field_name')->value)
->condition('user_id', $this->currentUser
->id());
if ($this->currentUser
->isAnonymous()) {
if (in_array(VotingApiReactionItemInterface::BY_COOKIES, $settings['anonymous_detection'])) {
$query
->condition('id', $this
->recallReaction($entity));
}
if (in_array(VotingApiReactionItemInterface::BY_IP, $settings['anonymous_detection'])) {
$query
->condition('vote_source', Vote::getCurrentIp());
}
$rollover = $settings['anonymous_rollover'];
if ($rollover == VotingApiReactionItemInterface::VOTINGAPI_ROLLOVER) {
$rollover = $this->configFactory
->get('votingapi.settings')
->get('anonymous_window');
}
if ($rollover != VotingApiReactionItemInterface::NEVER_ROLLOVER) {
$query
->condition('timestamp', time() - $rollover, '>=');
}
}
$ids = $query
->execute();
return $this->voteStorage
->load(intval(array_pop($ids)));
}
public function getResults(Vote $entity, array $settings) {
$results = $this->votingApiResults
->getResults($entity
->getVotedEntityType(), $entity
->getVotedEntityId());
$reactions = array_filter($settings['reactions']);
return array_intersect_key($results, $reactions);
}
public function recalculateResults($entity_type, $entity_id, $type) {
$this->votingApiResults
->recalculateResults($entity_type, $entity_id, $type);
}
public function allReactions() {
return array_filter($this->voteTypeStorage
->loadMultiple(), function (VoteType $entity) {
return $entity
->getThirdPartySetting('votingapi_reaction', 'reaction');
});
}
public function getReactions(array $settings, array $results) {
$entities = array_filter($this
->allReactions(), function (VoteType $entity) use ($settings) {
return in_array($entity
->id(), array_filter($settings['reactions']));
});
$reactions = array_map(function (VoteType $entity) use ($settings, $results) {
$reaction = [
'#theme' => 'votingapi_reaction_item',
'#reaction' => $entity
->id(),
];
if ($settings['show_icon']) {
$reaction['#icon'] = $this
->getIcon($entity);
}
if ($settings['show_label']) {
$reaction['#label'] = $entity
->label();
}
if ($settings['show_count']) {
$reaction['#count'] = isset($results[$entity
->id()]['vote_sum']) ? $results[$entity
->id()]['vote_sum'] : 0;
}
return $reaction;
}, $entities);
if ($settings['sort_reactions'] != 'none') {
uasort($reactions, function ($a, $b) use ($settings, $results) {
$count_a = isset($results[$a['#reaction']]['vote_count']) ? $results[$a['#reaction']]['vote_count'] : 0;
$count_b = isset($results[$b['#reaction']]['vote_count']) ? $results[$b['#reaction']]['vote_count'] : 0;
if ($settings['sort_reactions'] == 'desc') {
return $count_a > $count_b ? -1 : 1;
}
else {
return $count_a < $count_b ? -1 : 1;
}
});
}
return array_map(function ($reaction) {
return $this->renderer
->render($reaction);
}, $reactions);
}
public function rememberReaction(Vote $entity) {
$_SESSION['votingapi_reaction'][implode(':', [
$entity
->getVotedEntityId(),
$entity
->getVotedEntityType(),
$entity
->get('field_name')->value,
])] = $entity
->id();
}
public function forgetReaction(Vote $entity) {
unset($_SESSION['votingapi_reaction'][implode(':', [
$entity
->getVotedEntityId(),
$entity
->getVotedEntityType(),
$entity
->get('field_name')->value,
])]);
}
public function recallReaction(Vote $entity) {
$key = implode(':', [
$entity
->getVotedEntityId(),
$entity
->getVotedEntityType(),
$entity
->get('field_name')->value,
]);
return !empty($_SESSION['votingapi_reaction'][$key]) ? $_SESSION['votingapi_reaction'][$key] : NULL;
}
public function getIcon(VoteType $entity, &$default = TRUE) {
$path = implode('/', [
drupal_get_path('module', 'votingapi_reaction'),
'svg',
'',
]);
$url = $path . 'reaction_noicon.svg';
$icon = $entity
->getThirdPartySetting('votingapi_reaction', 'icon');
if ($icon && ($file = $this->fileStorage
->load($icon))) {
$url = $file
->getFileUri();
$default = FALSE;
}
elseif (file_exists(DRUPAL_ROOT . "/{$path}" . $entity
->id() . '.svg')) {
$url = $path . $entity
->id() . '.svg';
}
return file_create_url($url);
}
}