function smart_paging_field_attach_view_alter in Smart Paging 7.2
Same name and namespace in other branches
- 7 smart_paging.module \smart_paging_field_attach_view_alter()
Implements hook_field_attach_view_alter().
File
- ./
smart_paging.module, line 617 - Provides smart paging capability to Drupal contents.
Code
function smart_paging_field_attach_view_alter(&$build, $context) {
$view_modes = array(
'full' => 'full',
);
if (isset($build['#entity_type'])) {
$entities = smart_paging_entities();
if (in_array($build['#entity_type'], $entities)) {
$view_modes = variable_get('smart_paging_allowed_view_modes_' . $build['#entity_type'], array(
'full' => 'full',
));
}
}
// Comment entity type (it has its own pagination) is not included. Only show smart paging on configured view modes.
if ($context['entity_type'] != 'comment' && isset($build['#entity_type']) && !empty($view_modes[$context['view_mode']])) {
global $pager_page_array, $pager_total;
$suffix;
$display_suffix;
$total_page = 0;
$output_index = 0;
$current_page = 0;
// Element index of our pager in multiple pagers on one page.
$pager_element = 1;
// Determine the user's current viewing page number
if (isset($_GET['page'])) {
$pager_page_array = explode(',', $_GET['page']);
if (count($pager_page_array) == 1) {
$pager_page_array = array(
$pager_page_array[0],
0,
);
$current_page = 0;
}
else {
$current_page = $pager_page_array[$pager_element];
}
$output_index = $current_page;
}
// Get display settings
$display_stored = field_bundle_settings($build['#entity_type'], $build['#bundle']);
$display_defaults = smart_paging_field_extra_fields(TRUE);
if (isset($display_stored['extra_fields']['display']['smart_paging'][$context['display']])) {
$display_settings = $display_stored['extra_fields']['display']['smart_paging'][$context['display']];
}
elseif (isset($display_stored['extra_fields']['display']['smart_paging']['default'])) {
$display_settings = $display_stored['extra_fields']['display']['smart_paging']['default'];
}
else {
$display_settings = $display_defaults['extra_fields']['display']['smart_paging'];
}
// Sort array fields according to weight
$fields = array();
foreach (element_children($build) as $field_name) {
if (isset($build[$field_name]['#weight'])) {
$fields[$field_name] = $build[$field_name]['#weight'];
}
}
asort($fields);
foreach (array_keys($fields) as $field_name) {
foreach ($build[$field_name] as $delta => $field_content) {
if (is_numeric($delta) && isset($field_content['#markup'])) {
if (strpos($field_content['#markup'], '<!--smart_paging_autop_filter-->') !== FALSE) {
$use_autop = TRUE;
$field_content['#markup'] = str_replace('<!--smart_paging_autop_filter-->', '', $field_content['#markup']);
}
$is_smart_paging_filter_found = strpos($field_content['#markup'], '<!--smart_paging_filter-->');
$is_smart_paging_filter_done_found = strpos($field_content['#markup'], '<!--smart_paging_filter_done-->');
if ($is_smart_paging_filter_found !== FALSE || $is_smart_paging_filter_done_found !== FALSE) {
$entity_type = $context['entity_type'];
$entity_info = entity_get_info($entity_type);
$entity_id = $context['entity']->{$entity_info['entity keys']['id']};
$language = isset($build[$field_name]['#language']) ? $build[$field_name]['#language'] : 'und';
if ($display_settings['settings']['smart_paging_settings_context'] == 'content_type') {
// Use Smart Paging settings stored at Manage Display
if (isset($display_settings['settings']['smart_paging_method'])) {
$smart_paging_method = $display_settings['settings']['smart_paging_method'];
}
else {
$smart_paging_method = variable_get('smart_paging_method', SMART_PAGING_PLACEHOLDER_METHOD);
}
if (isset($display_settings['settings']['smart_paging_pagebreak'])) {
$placeholder = $display_settings['settings']['smart_paging_pagebreak'];
}
else {
$placeholder = variable_get('smart_paging_pagebreak', '<!--pagebreak-->');
}
if (isset($display_settings['settings']['smart_paging_title_display_suffix'])) {
$display_suffix = $display_settings['settings']['smart_paging_title_display_suffix'];
}
else {
$display_suffix = variable_get('smart_paging_title_display_suffix', TRUE);
}
if (isset($display_settings['settings']['smart_paging_title_suffix'])) {
$suffix = $display_settings['settings']['smart_paging_title_suffix'];
}
else {
$suffix = variable_get('smart_paging_title_suffix', t(': Page '));
}
if (isset($display_settings['settings']['smart_paging_character_count'])) {
$max_char = $display_settings['settings']['smart_paging_character_count'];
}
else {
$max_char = variable_get('smart_paging_character_count', SMART_PAGING_MAX_CHAR_LIMIT);
}
if (isset($display_settings['settings']['smart_paging_word_count'])) {
$max_words = $display_settings['settings']['smart_paging_word_count'];
}
else {
$max_words = variable_get('smart_paging_word_count', SMART_PAGING_MAX_WORD_LIMIT);
}
}
else {
// Retrieve the stored Smart Paging settings for this content
$smart_paging_config = smart_paging_get_content_configuration($entity_type, $entity_id);
$smart_paging_use_default = isset($smart_paging_config['use_default']) ? $smart_paging_config['use_default'] : TRUE;
$smart_paging_method = $smart_paging_use_default ? variable_get('smart_paging_method', SMART_PAGING_PLACEHOLDER_METHOD) : $smart_paging_config['method'];
$placeholder = $smart_paging_use_default ? variable_get('smart_paging_pagebreak', '<!--pagebreak-->') : $smart_paging_config['pagebreak'];
$display_suffix = $smart_paging_use_default ? variable_get('smart_paging_title_display_suffix', TRUE) : $smart_paging_config['title_display_suffix'];
$suffix = $smart_paging_use_default ? variable_get('smart_paging_title_suffix', t(': Page ')) : $smart_paging_config['title_suffix'];
$max_char = $smart_paging_use_default ? variable_get('smart_paging_character_count', SMART_PAGING_MAX_CHAR_LIMIT) : $smart_paging_config['character_count'];
$max_words = $smart_paging_use_default ? variable_get('smart_paging_word_count', SMART_PAGING_MAX_WORD_LIMIT) : $smart_paging_config['word_count'];
}
$markup_content = $field_content['#markup'];
if ($smart_paging_method == SMART_PAGING_NO_METHOD) {
// Do nothing, no paging is desired
$cached_field = cache_get("field:{$entity_type}:{$entity_id}", 'cache_field');
$cached_field->data[$field_name][$language][$delta]['safe_value'] = '<!--smart_paging_filter_done-->' . $markup_content;
cache_set("field:{$entity_type}:{$entity_id}", $cached_field->data, 'cache_field');
return;
}
}
// Check first if Smart Paging is allowed as input filter
if ($is_smart_paging_filter_found !== FALSE) {
// Remove the Smart Paging input filter marker
$markup_content = str_replace('<!--smart_paging_filter-->', '', $markup_content);
// Default this to 'no method' if it's being called as a full page
$query_parameters = drupal_get_query_parameters();
if (isset($query_parameters['nopaging'])) {
// Add canonical link if configured to do so.
if (variable_get('smart_paging_use_link_canonical', TRUE)) {
// @TODO: Somewhat duplicated from below pagination code. Refactor candidate.
$get = drupal_get_query_parameters();
$path_prefix = variable_get('smart_paging_path_prefix', 'page');
// Do we want nopaging as canonical instead of current page?
if (variable_get('smart_paging_use_nopaging_canonical', FALSE) && !isset($_GET[$path_prefix])) {
$get['nopaging'] = 1;
}
// Build url representation of current page. Using an absolute url allows outbound
// url hooks to modify the domain if necessary (domain module).
$link_current_page = url($_GET['q'], array(
'absolute' => TRUE,
'query' => $get,
));
// By default add a canonical head element here. We will clean up any duplicates
// in the hook.
drupal_add_html_head(array(
'#attributes' => array(
'rel' => 'canonical',
'href' => $link_current_page,
),
'#tag' => 'link',
'#attached' => array(
'drupal_add_http_header' => array(
array(
'Link',
'<' . $link_current_page . '>; rel="canonical"',
1,
),
),
),
), 'smart_paging_link_canonical');
}
// If set, use "Convert line breaks into HTML" filter
if (isset($use_autop)) {
$build[$field_name][$delta]['#markup'] = _filter_autop($markup_content);
}
return;
}
if ($smart_paging_method != SMART_PAGING_PLACEHOLDER_METHOD) {
// Check if breaking the page is based on number of characters
if ($smart_paging_method == SMART_PAGING_CHARACTER_LIMIT_METHOD) {
$char_count = 0;
}
elseif ($smart_paging_method == SMART_PAGING_WORD_LIMIT_METHOD || $smart_paging_method == SMART_PAGING_WORD_BLOCK_LIMIT_METHOD) {
$word_count = 0;
}
// Reset counts if this field was included via panels
if (isset($fields_processed) && in_array($field_name, $fields_processed)) {
$char_count = 0;
$word_count = 0;
}
// Remove user defined Smart Paging placeholder, we don't need it here
$markup_content = str_replace($placeholder, '', $markup_content);
$split_tags = preg_split('/<(!--.*?--|[^>]+?)>/s', $markup_content, -1, PREG_SPLIT_DELIM_CAPTURE);
$markup_content = '';
foreach ($split_tags as $split_tags_key => $split_tags_value) {
if ($split_tags_key & 1) {
$markup_content .= '<' . $split_tags_value . '>';
// Keep track of block level tags
if ($smart_paging_method == SMART_PAGING_WORD_BLOCK_LIMIT_METHOD) {
if (!isset($block_tag_value)) {
$block_tag_value = strpos($split_tags_value, ' ') !== FALSE ? strstr($split_tags_value, ' ', TRUE) : $split_tags_value;
$block_tag_occurrences = 0;
}
else {
// Keep track of additional occurrences of the block level tag
if ((strpos($split_tags_value, ' ') !== FALSE ? strstr($split_tags_value, ' ', TRUE) : $split_tags_value) == $block_tag_value) {
$block_tag_occurrences++;
}
else {
// If the tag is a closing tag and we have occurrences then deincrement
if ($split_tags_value == '/' . $block_tag_value) {
if ($block_tag_occurrences) {
$block_tag_occurrences--;
}
else {
unset($block_tag_value);
if ($word_count >= $max_words) {
$markup_content .= $placeholder;
$word_count = 0;
}
}
}
}
}
}
}
else {
if ($smart_paging_method == SMART_PAGING_CHARACTER_LIMIT_METHOD) {
$split_htmlcodes = preg_split('/(&[a-zA-Z]+;)/s', $split_tags_value, -1, PREG_SPLIT_DELIM_CAPTURE);
foreach ($split_htmlcodes as $split_htmlcodes_key => $split_htmlcodes_value) {
if ($split_htmlcodes_key & 1) {
// Count html charater as 1
$char_count++;
$markup_content .= $split_htmlcodes_value;
}
else {
$split_text = explode(' ', $split_htmlcodes_value);
$split_text_size = count($split_text);
foreach ($split_text as $text_value) {
$char_count += drupal_strlen($text_value);
$markup_content .= $text_value;
if ($split_text_size > 1) {
// Count the space
$char_count++;
$markup_content .= ' ';
}
if ($char_count >= $max_char) {
$markup_content .= $placeholder;
$char_count = 0;
}
}
}
}
}
else {
$split_text = explode(' ', $split_tags_value);
$split_text_size = count($split_text);
foreach ($split_text as $text_value) {
// Exclude whitespace
if (preg_match('/\\S/s', $text_value)) {
++$word_count;
}
$markup_content .= $text_value;
if ($split_text_size > 1) {
$markup_content .= ' ';
}
if ($smart_paging_method != SMART_PAGING_WORD_BLOCK_LIMIT_METHOD) {
if ($word_count >= $max_words) {
$markup_content .= $placeholder;
$word_count = 0;
}
}
}
}
}
}
}
do {
// Look for consecutive placeholder and closing tag. Eg. <!--pagebreak--></p>
$placeholder_regex = preg_quote($placeholder, '#');
preg_match_all("#({$placeholder_regex})([ \t\r\n]*)(</[a-zA-Z]+>)#", $markup_content, $match);
if (isset($match[1][0]) && isset($match[3][0])) {
// Move the placeholder to the end of closing tag. From the above example </p><!--pagebreak-->
$match_regex = preg_quote($match[1][0] . (isset($match[2][0]) ? $match[2][0] : '') . $match[3][0], '#');
$markup_content = preg_replace("#{$match_regex}#", (isset($match[2][0]) ? $match[2][0] : '') . $match[3][0] . $match[1][0], $markup_content);
}
} while (!empty($match[0]) && !empty($match[1]) && !empty($match[2]) && !empty($match[3]));
// Break HTML content properly and insert placeholder
$markup_content = smart_paging_break_insert_placeholder($markup_content);
// Check if last page is an empty tag
$pagebreak = array_filter(explode($placeholder, $markup_content));
$pagebreak_end = count($pagebreak) - 1;
$last_page = '';
if (isset($pagebreak[$pagebreak_end])) {
$last_page = strip_tags($pagebreak[$pagebreak_end]);
}
if (empty($last_page)) {
// Remove the last page with only an empty tag content
unset($pagebreak[$pagebreak_end]);
}
if (isset($use_autop)) {
// Use "Convert line breaks into HTML" filter
foreach ($pagebreak as $index => $content_value) {
$pagebreak[$index] = _filter_autop($content_value);
}
}
$markup_content = implode($placeholder, $pagebreak);
// Don't save to cache when node is in Preview mode
if (isset($context['entity']->op) && $context['entity']->op != 'Preview') {
// Save the processed page break content to cache
$cached_field = cache_get("field:{$entity_type}:{$entity_id}", 'cache_field');
$cached_field->data[$field_name][$language][$delta]['safe_value'] = '<!--smart_paging_filter_done-->' . $markup_content;
cache_set("field:{$entity_type}:{$entity_id}", $cached_field->data, 'cache_field');
}
// Set the field content output
$build[$field_name][$delta]['#markup'] = $markup_content;
}
if ($is_smart_paging_filter_found !== FALSE || $is_smart_paging_filter_done_found !== FALSE) {
// Remove the Smart Paging input filter done marker
$markup_content = str_replace('<!--smart_paging_filter_done-->', '', $markup_content);
if (empty($pagebreak)) {
// Break the content based on user's included page break placeholders
$pagebreak = array_filter(explode($placeholder, $markup_content));
}
$pagebreak_count = count($pagebreak);
if ($pagebreak_count > 1) {
if ($total_page) {
// At this point, we are in next succeeding fields. This field
// content will be shown at the last page of the previous field
$output_index = $current_page - $total_page;
}
$output = '';
if (isset($pagebreak[$output_index])) {
$output = $pagebreak[$output_index];
}
// Record total number of pages
$total_page += count($pagebreak);
// Delivers a "page not found" error to the browser for non-valid pages.
if ($current_page >= $total_page) {
drupal_not_found();
drupal_exit();
}
// Final field content output
$build[$field_name][$delta]['#markup'] = $output;
}
}
}
// Smart Paging as better SEO friendly targeting meta tags and URL (sub pages):
// Sample: <!--smartpagingmeta {"link_rel_canonical_href":"","meta_name_description_content":"Tips for breakfast facts and nutrition information","meta_name_keywords_content":"breakfast, breakfast nutrition, healthy, healthy eating habits"}-->
// Sample: <!--smartpagingurl "Breakfast-Facts-for-Nutrition"-->
if (is_array($build[$field_name][$delta]) && isset($build[$field_name][$delta]['#markup']) && isset($placeholder)) {
$content_break = explode($placeholder, $field_content['#markup']);
$custom_url_page = array();
foreach ($content_break as $page_num => $sub_page_content) {
preg_match_all('#<!--smartpagingurl [[:punct:][:alnum:][:space:]]*-->#', $sub_page_content, $matched_tags);
if (!empty($matched_tags[0])) {
$custom_url_page[$page_num] = preg_replace('#<!--smartpagingurl |-->|"|\'#', '', $matched_tags[0][0]);
}
}
smart_paging_get_url_fragment($custom_url_page);
$sub_content = $build[$field_name][$delta]['#markup'];
preg_match_all('#<!--smartpagingmeta [[:punct:][:alnum:][:space:]]*-->#', $sub_content, $matched_tags);
if (!empty($matched_tags[0])) {
$smart_paging_seo = preg_replace('#<!--smartpagingmeta |<!--smartpagingurl [[:punct:][:alnum:][:space:]]*-->|-->#', '', $matched_tags[0][0]);
if (!module_exists('metatag')) {
drupal_add_html_head(array(
'#attributes' => array(
'name' => 'Smart_Paging',
'content' => $smart_paging_seo,
),
'#tag' => 'meta',
), 'smart_paging_seo');
// Call this function to register the additional html head
drupal_get_html_head();
}
else {
$output =& drupal_static('smart_paging');
$output = json_decode($smart_paging_seo, TRUE);
}
}
}
}
}
if (!empty($total_page)) {
global $base_url;
$current_url = function_exists("path_alias_xt_get_path_alias") ? path_alias_xt_get_path_alias($_GET['q']) : drupal_get_path_alias($_GET['q']);
$current_url = preg_replace('#(^/)|(/$)#', '', $current_url);
$clean_url = variable_get('clean_url', 0);
$current_url = $clean_url ? $current_url : "?q={$current_url}";
$pager_details = array(
'first_element' => empty($pager_page_array[0]) ? 0 : $pager_page_array[0],
'current_page' => $current_page,
'base_url' => $base_url,
'current_url' => $current_url,
'path_prefix' => variable_get('smart_paging_path_prefix', 'page'),
'custom_url_page' => $custom_url_page,
);
$enable_clean_url = variable_get('smart_paging_enable_clean_url', TRUE);
if (variable_get('smart_paging_use_js_pager', TRUE) && $enable_clean_url) {
drupal_add_js(drupal_get_path('module', 'smart_paging') . '/js/smart_paging-pager.js');
drupal_add_js(array(
'smart_paging' => $pager_details,
), 'setting');
}
// Set up pager arguments.
$total_page_offset = $total_page - 1;
if ($enable_clean_url) {
$pager_prefix = $pager_details['path_prefix'] . '/' . $pager_details['first_element'];
}
else {
$pager_prefix = 'page=' . $pager_details['first_element'];
}
$get = drupal_get_query_parameters();
$q = $_GET['q'];
$path_prefix = variable_get('smart_paging_path_prefix', 'page');
// Do we want nopaging as canonical instead of current page?
if (variable_get('smart_paging_use_nopaging_canonical', FALSE) && !isset($_GET[$path_prefix])) {
$get['nopaging'] = 1;
}
elseif ($current_page != 0) {
// No. Make current paginated page canonical.
if ($enable_clean_url) {
$q .= "/{$pager_prefix}/{$current_page}";
}
else {
$get[$pager_prefix] = $current_page;
}
}
// Add canonical link if configured to do so.
if (variable_get('smart_paging_use_link_canonical', TRUE)) {
// Build url representation of current page. Using an absolute url allows outbound
// url hooks to modify the domain if necessary (domain module).
$link_current_page = url($_GET['q'], array(
'absolute' => TRUE,
'query' => $get,
));
// By default add a canonical head element here. We will clean up any duplicates in the hook.
drupal_add_html_head(array(
'#attributes' => array(
'rel' => 'canonical',
'href' => $link_current_page,
),
'#tag' => 'link',
'#attached' => array(
'drupal_add_http_header' => array(
array(
'Link',
'<' . $link_current_page . '>; rel="canonical"',
1,
),
),
),
), 'smart_paging_link_canonical');
}
if (variable_get('smart_paging_use_link_rel', TRUE)) {
// Pagination with rel="next" and rel="prev"
// Ref: http://googlewebmastercentral.blogspot.co.uk/2011/09/pagination-with-relnext-and-relprev.html
if ($current_page == 0) {
// We are on first page
$link_rel_next_page = $enable_clean_url ? "{$pager_prefix}/1" : "{$pager_prefix}%2C1";
}
else {
if ($current_page == $total_page_offset) {
// We are on last page
$link_rel_prev_page = $total_page_offset - 1;
if ($link_rel_prev_page) {
$link_rel_prev_page = $enable_clean_url ? "{$pager_prefix}/{$link_rel_prev_page}" : "{$pager_prefix}%2C{$link_rel_prev_page}";
}
}
else {
// We are on middle page
$link_rel_next_page = $current_page + 1;
if ($link_rel_next_page) {
$link_rel_next_page = $enable_clean_url ? "{$pager_prefix}/{$link_rel_next_page}" : "{$pager_prefix}%2C{$link_rel_next_page}";
}
$link_rel_prev_page = $current_page - 1;
if ($link_rel_prev_page) {
$link_rel_prev_page = $enable_clean_url ? "{$pager_prefix}/{$link_rel_prev_page}" : "{$pager_prefix}%2C{$link_rel_prev_page}";
}
}
}
if (isset($link_rel_prev_page)) {
if ($enable_clean_url) {
$href = $link_rel_prev_page ? "{$base_url}/{$current_url}/{$link_rel_prev_page}" : "{$base_url}/{$current_url}";
}
else {
$href = $link_rel_prev_page ? "{$base_url}/{$current_url}?{$link_rel_prev_page}" : "{$base_url}/{$current_url}";
}
drupal_add_html_head(array(
'#attributes' => array(
'rel' => 'prev',
'href' => $href,
),
'#tag' => 'link',
), 'smart_paging_link_rel_prev');
}
if (isset($link_rel_next_page)) {
if ($enable_clean_url) {
$href = $link_rel_next_page ? "{$base_url}/{$current_url}/{$link_rel_next_page}" : "{$base_url}/{$current_url}";
}
else {
$href = $link_rel_next_page ? "{$base_url}/{$current_url}?{$link_rel_next_page}" : "{$base_url}/{$current_url}";
}
drupal_add_html_head(array(
'#attributes' => array(
'rel' => 'next',
'href' => $href,
),
'#tag' => 'link',
), 'smart_paging_link_rel_next');
}
}
$pager_total[$pager_element] = $total_page;
if ($display_suffix && $current_page > 0) {
$title_suffix = theme('smart_paging_page_title_suffix', array(
'page' => array(
'suffix' => $suffix,
'current_page' => $current_page,
'total_page' => $total_page,
),
));
}
$variables['tags'] = array();
$variables['element'] = $pager_element;
$variables['quantity'] = 10;
if (!isset($pager_page_array[$pager_element])) {
$pager_page_array[$pager_element] = 0;
}
$build['smart_paging']['#markup'] = '<div class="smart-paging-pager">' . theme('pager', $variables) . '</div>';
$build['smart_paging']['#weight'] = isset($display_settings['weight']) ? $display_settings['weight'] : 0;
$build['smart_paging']['#access'] = isset($display_settings['visible']) ? $display_settings['visible'] : TRUE;
}
}
else {
foreach (element_children($build) as $field_name) {
foreach ($build[$field_name] as $delta => $field_content) {
if (is_numeric($delta)) {
// Check first if there's a Smart Paging filter placeholder
if (isset($field_content['#markup']) && strpos($field_content['#markup'], '<!--smart_paging_filter-->') !== FALSE) {
$markup_content = $field_content['#markup'];
// Remove the Smart Paging input filter marker and placeholder for comment entity
$markup_content = str_replace('<!--smart_paging_filter-->', '', $markup_content);
$markup_content = str_replace(variable_get('smart_paging_pagebreak', '<!--pagebreak-->'), '', $markup_content);
$build[$field_name][$delta]['#markup'] = $markup_content;
}
if (isset($field_content['#markup']) && strpos($field_content['#markup'], '<!--smart_paging_autop_filter-->') !== FALSE) {
$markup_content = $build[$field_name][$delta]['#markup'];
$markup_content = str_replace('<!--smart_paging_autop_filter-->', '', $markup_content);
$build[$field_name][$delta]['#markup'] = _filter_autop($markup_content);
}
}
}
}
}
}