### Eclipse Workspace Patch 1.0
#P d7dev
Index: modules/search/search.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/search/search.module,v
retrieving revision 1.344
diff -u -r1.344 search.module
--- modules/search/search.module	11 Apr 2010 18:54:11 -0000	1.344
+++ modules/search/search.module	20 Apr 2010 16:09:24 -0000
@@ -382,8 +382,19 @@
 
 /**
  * Simplifies a string according to indexing rules.
+ *
+ * @param $text
+ *   Text to simplify.
+ * @param $truncate
+ *   TRUE to truncate all the words in the text to the maximum length; FALSE
+ *   to leave them alone.
+ *
+ * @return
+ *   Simplified text.
+ *
+ * @see hook_search_preprocess()
  */
-function search_simplify($text) {
+function search_simplify($text, $truncate = FALSE) {
   // Decode entities to UTF-8
   $text = decode_entities($text);
 
@@ -416,6 +427,13 @@
   // marks, spacers, etc, to be a word boundary.
   $text = preg_replace('/[' . PREG_CLASS_SEARCH_EXCLUDE . ']+/u', ' ', $text);
 
+  // Truncate everything to the maximum allowed length.
+  if ($truncate) {
+    $words = explode(' ', $text);
+    array_walk($words, '_search_index_truncate');
+    $text = implode(' ', $words);
+  }
+
   return $text;
 }
 
@@ -449,7 +467,7 @@
 }
 
 /**
- * Splits a string into tokens for indexing.
+ * Simplifies and splits a string into tokens for indexing.
  */
 function search_index_split($text) {
   $last = &drupal_static(__FUNCTION__);
@@ -459,9 +477,8 @@
     return $lastsplit;
   }
   // Process words
-  $text = search_simplify($text);
+  $text = search_simplify($text, TRUE);
   $words = explode(' ', $text);
-  array_walk($words, '_search_index_truncate');
 
   // Save last keyword result
   $last = $text;
@@ -474,6 +491,9 @@
  * Helper function for array_walk in search_index_split.
  */
 function _search_index_truncate(&$text) {
+  if (is_numeric($text)) {
+    $text = ltrim($text, '0');
+  }
   $text = truncate_utf8($text, 50);
 }
 
@@ -608,14 +628,8 @@
         foreach ($words as $word) {
           // Add word to accumulator
           $accum .= $word . ' ';
-          $num = is_numeric($word);
           // Check wordlength
-          if ($num || drupal_strlen($word) >= $minimum_word_size) {
-            // Normalize numbers
-            if ($num) {
-              $word = (int)ltrim($word, '-0');
-            }
-
+          if (is_numeric($word) || drupal_strlen($word) >= $minimum_word_size) {
             // Links score mainly for the target.
             if ($link) {
               if (!isset($results[$linknid])) {
Index: modules/search/search.extender.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/search/search.extender.inc,v
retrieving revision 1.4
diff -u -r1.4 search.extender.inc
--- modules/search/search.extender.inc	16 Apr 2010 13:53:43 -0000	1.4
+++ modules/search/search.extender.inc	20 Apr 2010 16:09:24 -0000
@@ -188,8 +188,10 @@
         $phrase = TRUE;
         $this->simple = FALSE;
       }
-      // Simplify keyword according to indexing rules and external preprocessors.
-      $words = search_simplify($match[2]);
+      // Simplify keyword according to indexing rules and external
+      // preprocessors. Use same process as during search indexing, so it
+      // will match search index.
+      $words = search_simplify($match[2], TRUE);
       // Re-explode in case simplification added more words, except when
       // matching a phrase.
       $words = $phrase ? array($words) : preg_split('/ /', $words, -1, PREG_SPLIT_NO_EMPTY);
@@ -290,7 +292,6 @@
     foreach ($split as $s) {
       $num = is_numeric($s);
       if ($num || drupal_strlen($s) >= variable_get('minimum_word_size', 3)) {
-        $s = $num ? ((int)ltrim($s, '-0')) : $s;
         if (!isset($this->words[$s])) {
           $this->words[$s] = $s;
           $num_new_scores++;
Index: modules/search/search.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/search/search.test,v
retrieving revision 1.59
diff -u -r1.59 search.test
--- modules/search/search.test	16 Apr 2010 13:53:43 -0000	1.59
+++ modules/search/search.test	20 Apr 2010 16:09:24 -0000
@@ -651,6 +651,176 @@
 }
 
 /**
+ * Tests that numbers can be searched.
+ */
+class SearchNumbersTestCase extends DrupalWebTestCase {
+  protected $test_user;
+  protected $numbers;
+  protected $nodes;
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Search numbers',
+      'description' => 'Check that numbers can be searched',
+      'group' => 'Search',
+    );
+  }
+
+  function setUp() {
+    parent::setUp('search');
+
+    $this->test_user = $this->drupalCreateUser(array('search content', 'access content', 'administer nodes', 'access site reports'));
+    $this->drupalLogin($this->test_user);
+
+    // Create content with various numbers in it.
+    // Note: 50 characters is the current limit of the search index's word
+    // field.
+    $this->numbers = array(
+      'ISBN' => '978-0446365383',
+      'UPC' => '036000 291452',
+      'EAN bar code' => '5901234123457',
+      'negative' => '-123456.7890',
+      'leading zero' => '0777777777',
+      'tiny' => '111',
+      'small' => '22222222222222',
+      'medium' => '333333333333333333333333333',
+      'large' => '444444444444444444444444444444444444444',
+      'gigantic' => '5555555555555555555555555555555555555555555555555',
+      'over fifty characters' => '666666666666666666666666666666666666666666666666666666666666',
+      'date', '01/02/2009',
+      'commas', '987,654,321',
+    );
+
+    foreach ($this->numbers as $doc => $num) {
+      $info = array(
+        'body' => array(LANGUAGE_NONE => array(array('value' => $num))),
+        'type' => 'page',
+        'language' => LANGUAGE_NONE,
+        'title' => $doc . ' number',
+      );
+      $this->nodes[$doc] = $this->drupalCreateNode($info);
+    }
+
+    // Run cron to ensure the content is indexed.
+    $this->cronRun();
+    $this->drupalGet('admin/reports/dblog');
+    $this->assertText(t('Cron run completed'), 'Log shows cron run completed');
+  }
+
+  /**
+   * Tests that all the numbers can be searched.
+   */
+  function testNumberSearching() {
+    $types = array_keys($this->numbers);
+
+    foreach ($types as $type) {
+      $number = $this->numbers[$type];
+      // If the number is negative, remove the - sign, because - indicates
+      // "not keyword" when searching.
+      $number = ltrim($number, '-');
+      $node = $this->nodes[$type];
+
+      // Verify that the node title does not appear on the search page
+      // with a dummy search.
+      $this->drupalPost('search/node',
+        array('keys' => 'foo'),
+        t('Search'));
+      $this->assertNoText($node->title, $type . ': node title not shown in dummy search');
+
+      // Verify that the node title does appear as a link on the search page
+      // when searching for the number.
+      $this->drupalPost('search/node',
+        array('keys' => $number),
+        t('Search'));
+      $this->assertText($node->title, $type . ': node title shown (search found the node) in search for number ' . $number);
+    }
+  }
+}
+
+/**
+ * Tests that numbers can be searched, with more complex matching.
+ */
+class SearchNumberMatchingTestCase extends DrupalWebTestCase {
+  protected $test_user;
+  protected $numbers;
+  protected $nodes;
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Search number matching',
+      'description' => 'Check that numbers can be searched with more complex matching',
+      'group' => 'Search',
+    );
+  }
+
+  function setUp() {
+    parent::setUp('search');
+
+    $this->test_user = $this->drupalCreateUser(array('search content', 'access content', 'administer nodes', 'access site reports'));
+    $this->drupalLogin($this->test_user);
+
+    // Define a group of numbers that should all match each other --
+    // numbers with internal punctuation should match each other, as well
+    // as numbers with and without leading zeros and leading/trailing
+    // . and -.
+    $this->numbers = array(
+      '123456789',
+      '12/34/56789',
+      '12.3456789',
+      '12-34-56789',
+      '123,456,789',
+      '-123456789',
+      '0123456789',
+    );
+
+    foreach ($this->numbers as $num) {
+      $info = array(
+        'body' => array(LANGUAGE_NONE => array(array('value' => $num))),
+        'type' => 'page',
+        'language' => LANGUAGE_NONE,
+      );
+      $this->nodes[] = $this->drupalCreateNode($info);
+    }
+
+    // Run cron to ensure the content is indexed.
+    $this->cronRun();
+    $this->drupalGet('admin/reports/dblog');
+    $this->assertText(t('Cron run completed'), 'Log shows cron run completed');
+  }
+
+  /**
+   * Tests that all the numbers can be searched.
+   */
+  function testNumberSearching() {
+    for ($i = 0; $i < count($this->numbers); $i++) {
+      $node = $this->nodes[$i];
+
+      // Verify that the node title does not appear on the search page
+      // with a dummy search.
+      $this->drupalPost('search/node',
+        array('keys' => 'foo'),
+        t('Search'));
+      $this->assertNoText($node->title, $i . ': node title not shown in dummy search');
+
+      // Now verify that we can find node i by searching for any of the
+      // numbers.
+      for ($j = 0; $j < count($this->numbers); $j++) {
+        $number = $this->numbers[$j];
+        // If the number is negative, remove the - sign, because - indicates
+        // "not keyword" when searching.
+        $number = ltrim($number, '-');
+
+        $this->drupalPost('search/node',
+          array('keys' => $number),
+          t('Search'));
+        $this->assertText($node->title, $i . ': node title shown (search found the node) in search for number ' . $number);
+      }
+    }
+
+  }
+}
+
+/**
  * Test config page.
  */
 class SearchConfigSettingsForm extends DrupalWebTestCase {
