Subversion-Projekte lars-tiefland.prado

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/**
3
 * Zend Framework
4
 *
5
 * LICENSE
6
 *
7
 * This source file is subject to version 1.0 of the Zend Framework
8
 * license, that is bundled with this package in the file LICENSE, and
9
 * is available through the world-wide-web at the following URL:
10
 * http://www.zend.com/license/framework/1_0.txt. If you did not receive
11
 * a copy of the Zend Framework license and are unable to obtain it
12
 * through the world-wide-web, please send a note to license@zend.com
13
 * so we can mail you a copy immediately.
14
 *
15
 * @package    Zend_Search_Lucene
16
 * @subpackage Search
17
 * @copyright  Copyright (c) 2005-2006 Zend Technologies USA Inc. (http://www.zend.com)
18
 * @license    http://www.zend.com/license/framework/1_0.txt Zend Framework License version 1.0
19
 */
20
 
21
 
22
/** Zend_Search_Lucene_Search_QueryTokenizer */
23
require_once 'Zend/Search/Lucene/Search/QueryTokenizer.php';
24
 
25
/** Zend_Search_Lucene_Index_Term */
26
require_once 'Zend/Search/Lucene/Index/Term.php';
27
 
28
/** Zend_Search_Lucene_Search_Query_Term */
29
require_once 'Zend/Search/Lucene/Search/Query/Term.php';
30
 
31
/** Zend_Search_Lucene_Search_Query_MultiTerm */
32
require_once 'Zend/Search/Lucene/Search/Query/MultiTerm.php';
33
 
34
/** Zend_Search_Lucene_Search_Query_Phrase */
35
require_once 'Zend/Search/Lucene/Search/Query/Phrase.php';
36
 
37
 
38
/** Zend_Search_Lucene_Exception */
39
require_once 'Zend/Search/Lucene/Exception.php';
40
 
41
 
42
/**
43
 * @package    Zend_Search_Lucene
44
 * @subpackage Search
45
 * @copyright  Copyright (c) 2005-2006 Zend Technologies USA Inc. (http://www.zend.com)
46
 * @license    http://www.zend.com/license/framework/1_0.txt Zend Framework License version 1.0
47
 */
48
class Zend_Search_Lucene_Search_QueryParser
49
{
50
 
51
    /**
52
     * Parses a query string, returning a Zend_Search_Lucene_Search_Query
53
     *
54
     * @param string $strQuery
55
     * @return Zend_Search_Lucene_Search_Query
56
     */
57
    static public function parse($strQuery)
58
    {
59
        $tokens = new Zend_Search_Lucene_Search_QueryTokenizer($strQuery);
60
 
61
        // Empty query
62
        if (!$tokens->count()) {
63
            throw new Zend_Search_Lucene_Exception('Syntax error: query string cannot be empty.');
64
        }
65
 
66
        // Term query
67
        if ($tokens->count() == 1) {
68
            if ($tokens->current()->type == Zend_Search_Lucene_Search_QueryToken::TOKTYPE_WORD) {
69
                return new Zend_Search_Lucene_Search_Query_Term(new Zend_Search_Lucene_Index_Term($tokens->current()->text, 'contents'));
70
            } else {
71
                throw new Zend_Search_Lucene_Exception('Syntax error: query string must contain at least one word.');
72
            }
73
        }
74
 
75
 
76
        /**
77
         * MultiTerm Query
78
         *
79
         * Process each token that was returned by the tokenizer.
80
         */
81
        $terms = array();
82
        $signs = array();
83
        $prevToken = null;
84
        $openBrackets = 0;
85
        $field = 'contents';
86
        foreach ($tokens as $token) {
87
            switch ($token->type) {
88
                case Zend_Search_Lucene_Search_QueryToken::TOKTYPE_WORD:
89
                    $terms[] = new Zend_Search_Lucene_Index_Term($token->text, $field);
90
                    $field = 'contents';
91
                    if ($prevToken !== null &&
92
                        $prevToken->type == Zend_Search_Lucene_Search_QueryToken::TOKTYPE_SIGN) {
93
                            if ($prevToken->text == "+") {
94
                                $signs[] = true;
95
                            } else {
96
                                $signs[] = false;
97
                            }
98
                    } else {
99
                        $signs[] = null;
100
                    }
101
                    break;
102
                case Zend_Search_Lucene_Search_QueryToken::TOKTYPE_SIGN:
103
                    if ($prevToken !== null &&
104
                        $prevToken->type == Zend_Search_Lucene_Search_QueryToken::TOKTYPE_SIGN) {
105
                            throw new Zend_Search_Lucene_Exception('Syntax error: sign operator must be followed by a word.');
106
                    }
107
                    break;
108
                case Zend_Search_Lucene_Search_QueryToken::TOKTYPE_FIELD:
109
                    $field = $token->text;
110
                    // let previous token to be signed as next $prevToken
111
                    $token = $prevToken;
112
                    break;
113
                case Zend_Search_Lucene_Search_QueryToken::TOKTYPE_BRACKET:
114
                    $token->text=='(' ? $openBrackets++ : $openBrackets--;
115
            }
116
            $prevToken = $token;
117
        }
118
 
119
        // Finish up parsing: check the last token in the query for an opening sign or parenthesis.
120
        if ($prevToken->type == Zend_Search_Lucene_Search_QueryToken::TOKTYPE_SIGN) {
121
            throw new Zend_Search_Lucene_Exception('Syntax Error: sign operator must be followed by a word.');
122
        }
123
 
124
        // Finish up parsing: check that every opening bracket has a matching closing bracket.
125
        if ($openBrackets != 0) {
126
            throw new Zend_Search_Lucene_Exception('Syntax Error: mismatched parentheses, every opening must have closing.');
127
        }
128
 
129
        switch (count($terms)) {
130
            case 0:
131
                throw new Zend_Search_Lucene_Exception('Syntax error: bad term count.');
132
            case 1:
133
                return new Zend_Search_Lucene_Search_Query_Term($terms[0],$signs[0] !== false);
134
            default:
135
                return new Zend_Search_Lucene_Search_Query_MultiTerm($terms,$signs);
136
        }
137
    }
138
 
139
}
140