[ Index ]
 

Code source de Horde 3.1.3

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/lib/Horde/SQL/ -> Keywords.php (source)

   1  <?php
   2  /**
   3   * This class provides a parser which can construct an SQL WHERE
   4   * clause from a Google-like search expression.
   5   *
   6   * $Horde: framework/SQL/SQL/Keywords.php,v 1.2.10.4 2006/01/01 21:28:33 jan Exp $
   7   *
   8   * Copyright 2004-2006 Cronosys, LLC <http://www.cronosys.com/>
   9   *
  10   * See the enclosed file COPYING for license information (LGPL).  If you
  11   * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
  12   *
  13   * The expression recognizes boolean "AND", "OR", and "NOT" (providing
  14   * no operator between keywords implies "AND"), like so:
  15   *
  16   *   cat and dog
  17   *   cat or dog
  18   *   cat and not dog
  19   *
  20   * If no operator appears between keywords or quoted strings, "AND" is
  21   * assumed.  A comma can be used instead of "OR":
  22   *
  23   *   cat dog
  24   *   cat, dog
  25   *   cat not dog
  26   *
  27   * The parser recognizes parentheses, so complex expressions can be
  28   * created:
  29   *
  30   *   cat and not (dog or puppy)
  31   *
  32   * Quoted strings are also recognized, and are taken as literal
  33   * keywords:
  34   *
  35   *   "cat and dog"
  36   *
  37   * Parsing is designed to be as fuzzy as possible, so it shouldn't
  38   * error unless people search for "AND", "OR", or "NOT" without
  39   * quoting it or use unbalanced parentheses.
  40   *
  41   * @author  Jason M. Felice <jfelice@cronosys.com>
  42   * @since   Horde 3.0
  43   * @package Horde_SQL
  44   */
  45  class Horde_SQL_Keywords {
  46  
  47      /**
  48       * Parse a keyword expression.
  49       *
  50       * @param string $column        This is the SQL field name the resulting
  51       *                              expression should test against.
  52       * @param string $expr          This is the keyword expression we want to
  53       *                              parse.
  54       * @return mixed the query expression or a PEAR_Error on failure.
  55       */
  56      function parse($column, $expr)
  57      {
  58          /* First pass - scan the string for tokens.  Bare words are
  59           * tokens, or the user can quote strings to have embedded
  60           * spaces, keywords, or parentheses.  Parentheses can be used
  61           * for grouping boolean operators, and the boolean operators
  62           * AND, OR, and NOT are all recognized.
  63           *
  64           * The tokens are returned in the $tokens array -- an array of
  65           * strings.  Each string in the array starts with either a `!'
  66           * or a `='.  `=' is a bare word or quoted string we are
  67           * searching for, and `!' indicates a boolean operator or
  68           * parenthesis.  A token that starts with a '.'  indicates a
  69           * PostgreSQL word boundary search. */
  70          $tokens = array();
  71          while (!empty($expr)) {
  72              $expr = preg_replace("/^\s+/", "", $expr);
  73              if (empty($expr)) {
  74                  break;
  75              }
  76              if (substr($expr,0,1) == '(') {
  77                  $expr = substr($expr, 1);
  78                  $token = '!(';
  79              } elseif (substr($expr, 0, 1) == ')') {
  80                  $expr = substr($expr, 1);
  81                  $token = '!)';
  82              } elseif (substr($expr, 0, 1) == ',') {
  83                  $expr = substr($expr, 1);
  84                  $token = '!OR';
  85              } elseif (preg_match("/^(AND|OR|NOT)([^a-z].*)?$/i", $expr,
  86                                   $matches)) {
  87                  $token = '!' . strtoupper($matches[1]);
  88                  $expr = substr($expr, strlen($matches[1]));
  89              } elseif (preg_match("/^\"(([^\"]|\\[0-7]+|\\[Xx][0-9a-fA-F]+|\\[^Xx0-7])*)\"/",
  90                                   $expr, $matches)) {
  91                  $token = '=' . stripcslashes($matches[1]);
  92                  $expr = substr($expr, strlen($matches[0]));
  93              } elseif (preg_match("/^[^\\s\\(\\),]+/", $expr, $matches)) {
  94                  $token = '=' . $matches[0];
  95                  $expr = substr($expr,strlen($token)-1);
  96              } else {
  97                  return PEAR::raiseError(_("Syntax error in search terms"));
  98              }
  99              if ($token == '!AND') {
 100                  /* !AND is implied by concatenation. */
 101                  continue;
 102              }
 103              $tokens[] = $token;
 104          }
 105  
 106          /* Call the expression parser. */
 107          return Horde_SQL_Keywords::_parseKeywords1($column, $tokens);
 108      }
 109  
 110      function _parseKeywords1($column, &$tokens)
 111      {
 112          if (count($tokens) == 0) {
 113              return PEAR::raiseError(_("Empty search terms"));
 114          }
 115          $lhs = Horde_SQL_Keywords::_parseKeywords2($column, $tokens);
 116          if (is_a($lhs, 'PEAR_Error')) {
 117              return $lhs;
 118          }
 119          if (count($tokens) == 0 || $tokens[0] != '!OR') {
 120              return $lhs;
 121          }
 122          array_shift($tokens);
 123          $rhs = Horde_SQL_Keywords::_parseKeywords1($column, $tokens);
 124          if (is_a($rhs, 'PEAR_Error')) {
 125              return $rhs;
 126          }
 127          return "( $lhs OR $rhs )";
 128      }
 129  
 130      function _parseKeywords2($column, &$tokens)
 131      {
 132          $lhs = Horde_SQL_Keywords::_parseKeywords3($column, $tokens);
 133          if (is_a($lhs, 'PEAR_Error')) {
 134              return $lhs;
 135          }
 136          if (sizeof($tokens) == 0 || $tokens[0] == '!)' || $tokens[0] == '!OR') {
 137              return $lhs;
 138          }
 139          $rhs = Horde_SQL_Keywords::_parseKeywords2($column, $tokens);
 140          if (is_a($rhs, 'PEAR_Error')) {
 141              return $rhs;
 142          }
 143          return "( $lhs AND $rhs )";
 144      }
 145  
 146      function _parseKeywords3($column, &$tokens)
 147      {
 148          if ($tokens[0] == '!NOT') {
 149              array_shift($tokens);
 150              $lhs = Horde_SQL_Keywords::_parseKeywords4($column, $tokens);
 151              if (is_a($lhs, 'PEAR_Error')) {
 152                  return $lhs;
 153              }
 154              return "( NOT $lhs )";
 155          }
 156          return Horde_SQL_Keywords::_parseKeywords4($column, $tokens);
 157      }
 158  
 159      function _parseKeywords4($column, &$tokens)
 160      {
 161          if ( $tokens[0] == '!(' ) {
 162              array_shift($tokens);
 163              $lhs = Horde_SQL_Keywords::_parseKeywords1($column, $tokens);
 164              if (is_a($lhs, 'PEAR_Error')) {
 165                  return $lhs;
 166              }
 167              if (sizeof($tokens) == 0 || $tokens[0] != '!)') {
 168                  return PEAR::raiseError(_("Expected ')'"));
 169              }
 170              array_shift($tokens);
 171              return $lhs;
 172          }
 173          if (substr($tokens[0], 0, 1) != '=' &&
 174              substr($tokens[0], 0, 2) != '=.') {
 175              return PEAR::raiseError(_("Expected bare word or quoted search term"));
 176          }
 177          $val = strtolower(substr(array_shift($tokens), 1));
 178          $val = addslashes(ereg_replace("([\\%])", "\\\\1", $val));
 179          return "( LOWER($column) LIKE '%$val%' )";
 180      }
 181  
 182  }


Généré le : Sun Feb 25 18:01:28 2007 par Balluche grâce à PHPXref 0.7