Coverage for Doctrine_Hook

Back to coverage report

1 <?php
2 /*
3  *  $Id: Hook.php 3189 2007-11-18 20:37:44Z meus $
4  *
5  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
6  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
7  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
8  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
9  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
10  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
11  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
12  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
13  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
14  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
15  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16  *
17  * This software consists of voluntary contributions made by many individuals
18  * and is licensed under the LGPL. For more information, see
19  * <http://www.phpdoctrine.org>.
20  */
21
22 /**
23  * Doctrine_Hook
24  *
25  * @package     Doctrine
26  * @subpackage  Hook
27  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
28  * @link        www.phpdoctrine.org
29  * @since       1.0
30  * @version     $Revision: 3189 $
31  * @author      Konsta Vesterinen <kvesteri@cc.hut.fi>
32  */
33 class Doctrine_Hook
34 {
35     /**
36      * @var Doctrine_Query $query           the base query
37      */
38     protected $query;
39
40     /**
41      * @var array $joins                    the optional joins of the base query
42      */
43     protected $joins;
44
45     /**
46      * @var array $hooks                    hooks array
47      */
48     protected $hooks        = array(
49                              'where',
50                              'orderby',
51                              'limit',
52                              'offset'
53                               );
54
55     /**
56      * @var array $fieldParsers             custom field parsers array
57      *                                      keys as field names in the format componentAlias.FieldName
58      *                                      values as parser names / objects
59      */
60     protected $fieldParsers = array();
61
62     /**
63      * @var array $typeParsers              type parsers array
64      *                                      keys as type names and values as parser names / objects
65      */
66     protected $typeParsers  = array(
67                               'char'      => 'Doctrine_Hook_WordLike',
68                               'string'    => 'Doctrine_Hook_WordLike',
69                               'varchar'   => 'Doctrine_Hook_WordLike',
70                               'integer'   => 'Doctrine_Hook_Integer',
71                               'enum'      => 'Doctrine_Hook_Integer',
72                               'time'      => 'Doctrine_Hook_Time',
73                               'date'      => 'Doctrine_Hook_Date',
74                               );
75
76     /**
77      * @param Doctrine_Query $query         the base query
78      */
79     public function __construct($query)
80     {
81         if (is_string($query)) {
82             $this->query = new Doctrine_Query();
83             $this->query->parseQuery($query);
84         } elseif ($query instanceof Doctrine_Query) {
85             $this->query = $query;
86         } else {
87             throw new Doctrine_Exception('Constructor argument should be either Doctrine_Query object or valid DQL query');          
88         }
89         
90         $this->query->getQuery();
91     }
92
93     /**
94      * getQuery
95      *
96      * @return Doctrine_Query       returns the query object associated with this hook
97      */
98     public function getQuery()
99     {
100         return $this->query;
101     }
102
103     /**
104      * setTypeParser
105      *
106      * @param string $type              type name
107      * @param string|object $parser     parser name or custom parser object
108      */
109     public function setTypeParser($type, $parser) 
110     {
111         $this->typeParsers[$type] = $parser;
112     }
113
114     /**
115      * setFieldParser
116      *
117      * @param string $field             field name
118      * @param string|object $parser     parser name or custom parser object
119      */
120     public function setFieldParser($field, $parser)
121     {
122         $this->fieldParsers[$field] = $parser;
123     }
124
125     /**
126      * hookWhere
127      * builds DQL query where part from given parameter array
128      *
129      * @param array $params         an associative array containing field
130      *                              names and their values
131      * @return boolean              whether or not the hooking was
132      */
133     public function hookWhere($params)
134     {
135         if ( ! is_array($params)) {
136             return false;
137         }
138         foreach ($params as $name => $value) {
139             if ($value === '' || $value === '-') {
140                 continue;
141             }
142             $e = explode('.', $name);
143
144             if (count($e) == 2) {
145                 list($alias, $column) = $e;
146
147                 $map   = $this->query->getAliasDeclaration($alias);
148                 $table = $map['table'];
149
150                 if ( ! $table) {
151                     throw new Doctrine_Exception('Unknown alias ' . $alias);
152                 }
153
154                 if ($def = $table->getDefinitionOf($column)) {
155
156                 $def[0] = gettype($value);
157                     if (isset($this->typeParsers[$def[0]])) {
158                         $name   = $this->typeParsers[$def[0]];
159                         $parser = new $name;
160                     }
161
162                     $parser->parse($alias, $column, $value);
163
164                     $this->query->addWhere($parser->getCondition(), $parser->getParams());
165                 }
166             }
167         }
168
169         return true;
170     }
171
172     /**
173      * hookOrderBy
174      * builds DQL query orderby part from given parameter array
175      *
176      * @param array $params         an array containing all fields which the built query
177      *                              should be ordered by
178      * @return boolean              whether or not the hooking was successful
179      */
180     public function hookOrderby($params)
181     {
182         if ( ! is_array($params)) {
183             return false;
184         }
185         foreach ($params as $name) {
186             $e = explode(' ', $name);
187
188             $order = 'ASC';
189
190             if (count($e) > 1) {
191                 $order = ($e[1] == 'DESC') ? 'DESC' : 'ASC';
192             }
193
194             $e = explode('.', $e[0]);
195
196             if (count($e) == 2) {
197                 list($alias, $column) = $e;
198
199                 $map   = $this->query->getAliasDeclaration($alias);
200                 $table = $map['table'];
201
202                 if ($def = $table->getDefinitionOf($column)) {   
203                     $this->query->addOrderBy($alias . '.' . $column . ' ' . $order);
204                 }
205             }
206         }
207         return true;
208     }
209
210     /**
211      * set the hook limit 
212      * 
213      * @param integer $limit 
214      * @return void
215      */
216     public function hookLimit($limit)
217     {
218         $this->query->limit((int) $limit);
219     }
220
221     /**
222      * set the hook offset
223      *
224      * @param integer $offset
225      */
226     public function hookOffset($offset)
227     {
228         $this->query->offset((int) $offset);
229     }
230 }