public function FlippyPager::flippy_build_list in Flippy 8
Helper function: Query to get the list of flippy pagers.
Parameters
Drupal\node\Entity\Node $node: Current node object.
Return value
array A list of flippy pagers.
File
- src/
FlippyPager.php, line 108
Class
- FlippyPager
- Defines the flippy pager service.
Namespace
Drupal\flippyCode
public function flippy_build_list(Node $node) {
// Get all the properties from the current node.
$master_list =& drupal_static(__FUNCTION__);
if (!isset($master_list)) {
$master_list = [];
}
if (!isset($master_list[$node
->id()])) {
// Check to see if we need custom sorting.
if ($this->flippySettings
->get('flippy_custom_sorting_' . $node
->getType())) {
// Get order.
$order = $this->flippySettings
->get('flippy_order_' . $node
->getType());
// Get sort.
$sort = $this->flippySettings
->get('flippy_sort_' . $node
->getType());
}
else {
$order = 'ASC';
$sort = 'created';
}
// Validate that the sort criteria is OK to use.
// Achieve the base field from a node type.
$sort_options = [];
// Get all the field from a node type.
$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') {
// It is a base field.
$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 the sort criteria is not in the $sort_option array, we assume it's
// a field.
if (!in_array($sort, $base_table_properties)) {
// Get the value of the current node's field (use the first one only)
$current_field_items = $node->{$sort}
->getValue();
if (!isset($current_field_items[0]['value'])) {
// Should never happen, but just in case, fall back to post date
// ascending.
$sort = 'created';
$order = 'ASC';
}
else {
// Otherwise save the field value for later.
$field_value = $current_field_items[0]['value'];
}
}
// Depending on order, decide what before and after means.
$before = $order == 'ASC' ? '<' : '>';
$after = $order == 'ASC' ? '>' : '<';
// Also decide what up and down means.
$up = $order == 'ASC' ? 'ASC' : 'DESC';
$down = $order == 'ASC' ? 'DESC' : 'ASC';
// Create a starting-point EntityQuery object.
$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');
// Create the individual queries.
$first = clone $query;
$prev = clone $query;
$next = clone $query;
$last = clone $query;
$random = clone $query;
// We will construct the queries differently depending on whether the
// sorting criteria is a field or a base table property.
// If we found a field value earlier, we know we're dealing with a field.
if (isset($field_value)) {
// Set the conditions.
// The first query.
$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);
// The last query.
$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);
// Previous query to find out the previous item based on the field,
// using node id if the other criteria is the same.
// The prev query.
$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);
// The next query.
$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);
// Set the ordering.
$first
->sort($sort, $up);
$prev
->sort($sort, $down);
$next
->sort($sort, $up);
$last
->sort($sort, $down);
}
else {
// Otherwise we assume the variable is a column in the base table
// (a property). Like above, set the conditions.
$sort_value = $node
->get($sort);
$sort_value = $sort_value
->getValue();
// First and last query.
$first
->condition($sort, $sort_value[0]['value'], $before);
$last
->condition($sort, $sort_value[0]['value'], $after);
// Previous query to find out the previous item based on the field,
// using node id if the other criteria is the same.
$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);
// Next query to find out the next item based on the field, using
// node id if the other criteria is the same.
$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);
// Set the ordering.
$first
->sort($sort, $up);
$prev
->sort($sort, $down);
$next
->sort($sort, $up);
$last
->sort($sort, $down);
}
// Event dispatcher.
$queries = [
'first' => $first,
'prev' => $prev,
'next' => $next,
'last' => $last,
];
$event = new FlippyEvent($queries, $node);
$this->eventDispatcher
->dispatch('buildFlippyQuery', $event);
$queries = $event
->getQueries();
// Execute the queries.
$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 the query returned no results, it means we're already
// at the beginning/end of the pager, so ignore those.
if (is_numeric($result)) {
// Otherwise we save the node ID.
$node_ids[$key] = (int) $result;
}
elseif (is_array($result) && count($result) > 0) {
// Otherwise we save the node ID.
$node_ids[$key] = $results[$key];
}
}
// Make our final array of node IDs and titles.
$list = [];
// But only if we actually found some matches.
if (count($node_ids) > 0) {
// We also need titles to go with our node ids.
$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 : '',
];
}
}
// Create random list.
// TODO: orderRandom is not available in entityQuery yet.
if ($this->flippySettings
->get('flippy_random_' . $node
->getType())) {
$random_nids = $random
->execute();
$random_nid = array_rand($random_nids, 1);
// Find out the node title.
$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()];
}