/** * Find next and previous articles relative to a provided threshold level * * @param int $id The "pivot" article's id; use zero (0) to indicate $thisarticle * @param scalar $threshold The value to compare against if $id != 0 * @param string $s string Optional section restriction if $id != 0 * @return array An array populated with article data from the next and previous article */ function getNextPrev($id = 0, $threshold = null, $s = '') { if ($id !== 0) { // Pivot is specific article by ID: In lack of further information, revert to default sort order 'Posted desc' $atts = filterAtts(array('sortby' => 'Posted', 'sortdir' => 'desc')); } else { // Pivot is $thisarticle: Use article attributes to find its neighbours assert_article(); global $thisarticle; if (!is_array($thisarticle)) { return array(); } $atts = filterAtts(); $m = preg_split('/\\s+/', $atts['sort']); if (empty($m[0]) || count($m) > 2 || preg_match('/[),]/', $m[0])) { // Either no explicit sort order or a complex clause, e.g. 'foo asc, bar desc' or 'FUNC(foo,bar) asc' // Fall back to chronologically descending order $atts['sortby'] = 'Posted'; $atts['sortdir'] = 'desc'; } else { // sort is like 'foo asc' $atts['sortby'] = $m[0]; $atts['sortdir'] = isset($m[1]) && strtolower($m[1]) == 'desc' ? 'desc' : 'asc'; } // atts w/ special treatment switch ($atts['sortby']) { case 'Posted': $threshold = 'from_unixtime(' . doSlash($thisarticle['posted']) . ')'; $threshold_type = 'cooked'; break; case 'Expires': $threshold = 'from_unixtime(' . doSlash($thisarticle['expires']) . ')'; $threshold_type = 'cooked'; break; case 'LastMod': $threshold = 'from_unixtime(' . doSlash($thisarticle['modified']) . ')'; $threshold_type = 'cooked'; break; default: // retrieve current threshold value per sort column from $thisarticle $acm = array_flip(article_column_map()); $key = $acm[$atts['sortby']]; $threshold = $thisarticle[$key]; $threshold_type = 'raw'; break; } $s = $thisarticle['section']; } $thenext = getNeighbour($threshold, $s, '>', $atts, $threshold_type); $out['next_id'] = $thenext ? $thenext['ID'] : ''; $out['next_title'] = $thenext ? $thenext['Title'] : ''; $out['next_utitle'] = $thenext ? $thenext['url_title'] : ''; $out['next_posted'] = $thenext ? $thenext['uposted'] : ''; $theprev = getNeighbour($threshold, $s, '<', $atts, $threshold_type); $out['prev_id'] = $theprev ? $theprev['ID'] : ''; $out['prev_title'] = $theprev ? $theprev['Title'] : ''; $out['prev_utitle'] = $theprev ? $theprev['url_title'] : ''; $out['prev_posted'] = $theprev ? $theprev['uposted'] : ''; return $out; }
/** * Find next and previous articles relative to a provided threshold level. * * @param int $id The "pivot" article's id; use zero (0) to indicate $thisarticle * @param scalar $threshold The value to compare against if $id != 0 * @param string $s Optional section restriction if $id != 0 * @return array An array populated with article data */ function getNextPrev($id = 0, $threshold = null, $s = '') { if ($id !== 0) { // Pivot is specific article by ID: In lack of further information, // revert to default sort order 'Posted desc'. $atts = filterAtts(array('sortby' => "Posted", 'sortdir' => "DESC")); } else { // Pivot is $thisarticle: Use article attributes to find its neighbours. assert_article(); global $thisarticle; if (!is_array($thisarticle)) { return array(); } $atts = filterAtts(); $m = preg_split('/\\s+/', $atts['sort']); // If in doubt, fall back to chronologically descending order. if (empty($m[0]) || count($m) > 2 || !preg_match('/^(?:[0-9a-zA-Z$_\\x{0080}-\\x{FFFF}]+|`[\\x{0001}-\\x{FFFF}]+`)$/u', $m[0])) { $atts['sortby'] = "Posted"; $atts['sortdir'] = "DESC"; } else { // Sort is like 'foo asc'. $atts['sortby'] = $m[0]; $atts['sortdir'] = isset($m[1]) && strtolower($m[1]) == 'desc' ? "DESC" : "ASC"; } // Attributes with special treatment. switch ($atts['sortby']) { case 'Posted': $threshold = "FROM_UNIXTIME(" . doSlash($thisarticle['posted']) . ")"; $threshold_type = 'cooked'; break; case 'Expires': $threshold = "FROM_UNIXTIME(" . doSlash($thisarticle['expires']) . ")"; $threshold_type = 'cooked'; break; case 'LastMod': $threshold = "FROM_UNIXTIME(" . doSlash($thisarticle['modified']) . ")"; $threshold_type = 'cooked'; break; default: // Retrieve current threshold value per sort column from $thisarticle. $acm = array_flip(article_column_map()); $key = $acm[$atts['sortby']]; $threshold = $thisarticle[$key]; $threshold_type = 'raw'; break; } $s = $thisarticle['section']; } $out['next'] = getNeighbour($threshold, $s, '>', $atts, $threshold_type); $out['prev'] = getNeighbour($threshold, $s, '<', $atts, $threshold_type); return $out; }