View source
<?php
namespace Drupal\flippy;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Language\LanguageManager;
use Drupal\Core\Link;
use Drupal\Core\Url;
use Drupal\node\Entity\Node;
use Drupal\Core\Utility\Token;
use Drupal\Component\Utility\Html;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
class FlippyPager {
public $entityFieldManager;
protected $eventDispatcher;
public $entityTypeManager;
protected $connection;
protected $flippySettings;
protected $token;
protected $languageManager;
public function __construct(EntityFieldManagerInterface $entityFieldManager, EventDispatcherInterface $event_dispatcher, EntityTypeManagerInterface $entity_type_manager, Connection $connection, ConfigFactoryInterface $config_factory, Token $token, LanguageManager $languageManager) {
$this->entityFieldManager = $entityFieldManager;
$this->eventDispatcher = $event_dispatcher;
$this->entityTypeManager = $entity_type_manager;
$this->connection = $connection;
$this->flippySettings = $config_factory
->get('flippy.settings');
$this->token = $token;
$this->languageManager = $languageManager;
}
public function flippy_build_list(Node $node) {
$master_list =& drupal_static(__FUNCTION__);
if (!isset($master_list)) {
$master_list = [];
}
if (!isset($master_list[$node
->id()])) {
if ($this->flippySettings
->get('flippy_custom_sorting_' . $node
->getType())) {
$order = $this->flippySettings
->get('flippy_order_' . $node
->getType());
$sort = $this->flippySettings
->get('flippy_sort_' . $node
->getType());
}
else {
$order = 'ASC';
$sort = 'created';
}
$sort_options = [];
$content_type_fields = $this->entityFieldManager
->getFieldDefinitions('node', $node
->getType());
foreach ($content_type_fields as $sort_field) {
if (get_class($sort_field) == 'Drupal\\Core\\Field\\BaseFieldDefinition') {
$schema_info = $sort_field
->getSchema();
}
if (isset($schema_info['columns']['value']) && $schema_info['columns']['value']['type'] == 'int') {
$sort_options[] = $sort_field
->getName();
}
}
$base_table_properties = $sort_options;
$field_value = NULL;
if (!in_array($sort, $base_table_properties)) {
$current_field_items = $node->{$sort}
->getValue();
if (!isset($current_field_items[0]['value'])) {
$sort = 'created';
$order = 'ASC';
}
else {
$field_value = $current_field_items[0]['value'];
}
}
$before = $order == 'ASC' ? '<' : '>';
$after = $order == 'ASC' ? '>' : '<';
$up = $order == 'ASC' ? 'ASC' : 'DESC';
$down = $order == 'ASC' ? 'DESC' : 'ASC';
$query = $this->entityTypeManager
->getStorage('node')
->getQuery();
$query
->condition('type', $node
->getType())
->condition('status', 1)
->condition('langcode', $this->languageManager
->getCurrentLanguage()
->getId())
->condition('nid', $node
->id(), '!=')
->addTag('node_access');
$first = clone $query;
$prev = clone $query;
$next = clone $query;
$last = clone $query;
$random = clone $query;
if (isset($field_value)) {
$field_value_equal_condition = $first
->orConditionGroup()
->condition($sort . '.value', $field_value, '=')
->condition($sort . '.value', NULL, 'IS NULL');
$field_default_condition = $first
->andConditionGroup()
->condition('nid', $node
->id(), $before)
->condition($field_value_equal_condition);
$field_sorting_group = $first
->orConditionGroup()
->condition($sort . '.value', $field_value, $before)
->condition($field_default_condition);
$first
->condition($field_sorting_group);
$field_value_equal_condition = $last
->orConditionGroup()
->condition($sort . '.value', $field_value, '=')
->condition($sort . '.value', NULL, 'IS NULL');
$field_default_condition = $last
->andConditionGroup()
->condition('nid', $node
->id(), $after)
->condition($field_value_equal_condition);
$field_sorting_group = $last
->orConditionGroup()
->condition($sort . '.value', $field_value, $after)
->condition($field_default_condition);
$last
->condition($field_sorting_group);
$field_value_equal_condition = $prev
->orConditionGroup()
->condition($sort . '.value', $field_value, '=')
->condition($sort . '.value', NULL, 'IS NULL');
$field_default_condition = $prev
->andConditionGroup()
->condition('nid', $node
->id(), $before)
->condition($field_value_equal_condition);
$field_sorting_group = $prev
->orConditionGroup()
->condition($sort . '.value', $field_value, $before)
->condition($field_default_condition);
$prev
->condition($field_sorting_group);
$field_value_equal_condition = $next
->orConditionGroup()
->condition($sort . '.value', $field_value, '=')
->condition($sort . '.value', NULL, 'IS NULL');
$field_default_condition = $next
->andConditionGroup()
->condition('nid', $node
->id(), $after)
->condition($field_value_equal_condition);
$field_sorting_group = $next
->orConditionGroup()
->condition($sort . '.value', $field_value, $after)
->condition($field_default_condition);
$next
->condition($field_sorting_group);
$first
->sort($sort, $up);
$prev
->sort($sort, $down);
$next
->sort($sort, $up);
$last
->sort($sort, $down);
}
else {
$sort_value = $node
->get($sort);
$sort_value = $sort_value
->getValue();
$first
->condition($sort, $sort_value[0]['value'], $before);
$last
->condition($sort, $sort_value[0]['value'], $after);
$field_default_condition = $prev
->andConditionGroup()
->condition($sort, $sort_value[0]['value'])
->condition('nid', $node
->id(), $before);
$field_sorting_group = $prev
->orConditionGroup()
->condition($sort, $sort_value[0]['value'], $before)
->condition($field_default_condition);
$prev
->condition($field_sorting_group);
$field_default_condition = $next
->andConditionGroup()
->condition($sort, $sort_value[0]['value'])
->condition('nid', $node
->id(), $after);
$field_sorting_group = $next
->orConditionGroup()
->condition($sort, $sort_value[0]['value'], $after)
->condition($field_default_condition);
$next
->condition($field_sorting_group);
$first
->sort($sort, $up);
$prev
->sort($sort, $down);
$next
->sort($sort, $up);
$last
->sort($sort, $down);
}
$queries = [
'first' => $first,
'prev' => $prev,
'next' => $next,
'last' => $last,
];
$event = new FlippyEvent($queries, $node);
$this->eventDispatcher
->dispatch('buildFlippyQuery', $event);
$queries = $event
->getQueries();
$results = [];
$results['first'] = $queries['first']
->range(0, 1)
->execute();
$results['first'] = !empty($results['first']) ? array_values($results['first'])[0] : NULL;
$results['prev'] = $queries['prev']
->range(0, 1)
->execute();
$results['prev'] = !empty($results['prev']) ? array_values($results['prev'])[0] : NULL;
$results['next'] = $queries['next']
->range(0, 1)
->execute();
$results['next'] = !empty($results['next']) ? array_values($results['next'])[0] : NULL;
$results['last'] = $queries['last']
->range(0, 1)
->execute();
$results['last'] = !empty($results['last']) ? array_values($results['last'])[0] : NULL;
$node_ids = [];
foreach ($results as $key => $result) {
if (is_numeric($result)) {
$node_ids[$key] = (int) $result;
}
elseif (is_array($result) && count($result) > 0) {
$node_ids[$key] = $results[$key];
}
}
$list = [];
if (count($node_ids) > 0) {
$title_query = $this->connection
->select('node_field_data', 'nfd')
->fields('nfd', [
'title',
'nid',
])
->condition('nfd.nid', $node_ids, 'IN')
->execute()
->fetchAllAssoc('nid');
foreach ($node_ids as $key => $nid) {
$list[$key] = [
'nid' => $nid,
'title' => isset($title_query[$nid]) ? $title_query[$nid]->title : '',
];
}
}
if ($this->flippySettings
->get('flippy_random_' . $node
->getType())) {
$random_nids = $random
->execute();
$random_nid = array_rand($random_nids, 1);
$title = $this->connection
->select('node_field_data', 'nfd')
->fields('nfd', [
'title',
])
->condition('nfd.nid', $random_nid, '=')
->execute()
->fetchField();
$list['random'] = [
'nid' => $random_nid,
'title' => $title,
];
}
$master_list[$node
->id()] = $list;
}
return $master_list[$node
->id()];
}
public function flippy_use_pager(Node $node) {
if (!is_object($node)) {
return FALSE;
}
return node_is_page($node) && $this->flippySettings
->get('flippy_' . $node
->getType());
}
public function flippy_generate_link($nodeId, $label) {
$token_service = $this->token;
$language = $this->languageManager
->getCurrentLanguage()
->getId();
$url = Url::fromRoute('entity.node.canonical');
$url
->setRouteParameter('node', $nodeId);
$node_storage = $this->entityTypeManager
->getStorage('node');
$flippyLink = Link::fromTextAndUrl(HTML::decodeEntities($token_service
->replace($label, [
'node' => $node_storage
->load($nodeId),
], [
'langcode' => $language,
])), $url);
return $flippyLink
->toRenderable();
}
}