Commit aa4709d6 authored by generalredneck's avatar generalredneck

Merge branch 'DanChadwicks-work' into 7.x-1.x

parents 97c45335 df73767c
......@@ -61,3 +61,13 @@ function views_natural_sort_enable() {
*/
function views_natural_sort_uninstall() {
}
/**
* Impliments hook_update_N().
*
* Rebuild the sorting index after changes made for numerical data.
*/
function views_natural_sort_update_7001() {
module_load_include('inc', 'views_natural_sort', 'views_natural_sort.admin');
views_natural_sort_rebuild_index_submit();
}
......@@ -91,24 +91,85 @@ function _views_natural_sort_store_node($node) {
->fields(array(
'nid' => $node->nid,
'field' => 'title',
'content' => _views_natural_sort_filter_content($node->title)
'content' => views_natural_sort_encode($node->title)
))
->execute();
}
/**
* Helper function for filtering out what the value we should sort on is.
* @param $content
* Original content.
* @return
* Filtered value.
* Encodes a string into an ascii-sortable such:
* - Leading articles in common languages are ingored: The A An El La Le Il
* - Unimportant punctuation is ignored: # ' " ( )
* - Unimportant words are ignored: and of or
* - Embeded numbers will sort in numerical order. The following possiblities
* are supported
* - A leading dash indicates a negative number, unless it is preceded by a
* non-whitespace character, which case it is considered just a dash.
* - Leading zeros are properly ignored so as to not influence sort order
* - Decimal numbers are supported using a period as the decimal character
* - Thousands separates are ignored, using the comma as the thous. character
* - Numbers may be up to 99 digits before the decimal, up to the precision
* of the processor.
*
* @param $string string
* The string to be encoded
*
* @return string
* The encoded string
*/
function _views_natural_sort_filter_content($content) {
return preg_replace(array(
'/^(The|A|An|Le|La|L\'|Un|Une)\s/i',
'/\s(and|of|or)\s/i',
function views_natural_sort_encode($string) {
$string = preg_replace(array(
'/^(The|A|An|El|La|Le|Il)\s+/i',
'/[\#\'\"\(\)]/',
'/\s(and|of|or)\s+/i',
), array(
'',
'',
' ',
), $content);
), $string);
// Find an optional leading dash (either preceded by whitespace or the first character) followed
// by either:
// - an optional series of digits (with optional imbedded commas), then a period, then an optional series of digits OR
// - a series of digits (with optional imbedded commas)
$string = preg_replace_callback(
'/(\s-|^-)?(?:(\d[\d,]*)?\.(\d+)|(\d[\d,]*))/',
'_views_natural_sort_number_encode_match_callback',
$string
);
return $string;
}
/**
* Encodes a string representing numbers into a special format that can be sorted alphanumerically.
*
* @param array $match
* array of matches passed from preg_replace_callback
* $match[0] is the entire matching string
* $match[1] if present, is the optional dash, preceded by optional whitespace
* $match[2] if present, is whole number portion of the decimal number
* $match[3] if present, is the fractional portion of the decimal number
* $match[4] if present, is the integer (when no fraction is matched)
*
* @return string
* String representing a numerical value that will sort numerically in an
* alphanumeric search.
*/
function _views_natural_sort_number_encode_match_callback($match) {
// Remove commas and leading zeros from whole number
$whole = (string)(int)str_replace(',', '', (isset($match[4]) && strlen($match[4]) > 0) ? $match[4] : $match[2]);
// Remove traililng 0's from fraction, then add the decimal and one trailing 0
$fraction = trim('.' . $match[3], '0') . '0';
$encode = sprintf('%02u', strlen($whole)) . $whole . $fraction;
if (strlen($match[1])) {
// Negative number. Make 10's complement. Put back any leading white space and the dash
// Requires intermediate to avoid double-replacing the same digit. str_replace seems to
// work by copying the source to the result, then successively replacing within it,
// rather than replacing from the source to the result.
$digits = array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9');
$intermediate = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j');
$rev_digits = array('9', '8', '7', '6', '5', '4', '3', '2', '1', '0');
$encode = $match[1] . str_replace($intermediate, $rev_digits, str_replace($digits, $intermediate, $encode));
}
return $encode;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment