Where.php 3.92 KB
Newer Older
doctrine's avatar
doctrine committed
1 2 3 4 5
<?php
require_once("Condition.php");

class Doctrine_Query_Where extends Doctrine_Query_Condition {
    /**
6
     * load
doctrine's avatar
doctrine committed
7 8 9 10 11 12
     * returns the parsed query part
     *
     * @param string $where
     * @return string
     */
    final public function load($where) {
13

doctrine's avatar
doctrine committed
14 15 16 17 18 19 20
        $e = explode(" ",$where);
        $r = array_shift($e);
        $a = explode(".",$r);


        if(count($a) > 1) {
            $field     = array_pop($a);
21 22 23 24 25 26 27
            $count     = count($e);
            $slice     = array_slice($e, 0, ($count - 1));
            $operator  = implode(' ', $slice);

            $slice     = array_slice($e, -1, 1);
            $value     = implode('', $slice);

doctrine's avatar
doctrine committed
28 29 30
            $reference = implode(".",$a);
            $count     = count($a);

31

32

zYne's avatar
zYne committed
33
            $pos       = strpos($field, "(");
34

zYne's avatar
zYne committed
35
            if($pos !== false) {
36 37 38 39 40 41 42 43
                $func   = substr($field, 0, $pos);
                $value  = substr($field, ($pos + 1), -1);

                $values = Doctrine_Query::sqlExplode($value, ',');

                $field      = array_pop($a);
                $reference  = implode(".",$a);
                $table      = $this->query->load($reference, false);
zYne's avatar
zYne committed
44 45
                array_pop($a);
                $reference2 = implode('.', $a);
46
                $alias      = $this->query->getTableAlias($reference2);
47

zYne's avatar
zYne committed
48 49 50 51 52 53
                $stack      = $this->query->getRelationStack();
                $relation   = end($stack);
                
                $stack      = $this->query->getTableStack();

                switch($func) {
54 55 56
                    case 'contains':
                    case 'regexp':
                    case 'like':
57
                        $operator = $this->getOperator($func);
zYne's avatar
zYne committed
58

59 60 61 62 63 64
                        if(empty($relation))
                            throw new Doctrine_Query_Exception('DQL functions contains/regexp/like can only be used for fields of related components');
                        
                        $where = array();
                        foreach($values as $value) {
                            $where[] = $alias.'.'.$relation->getLocal().
zYne's avatar
zYne committed
65
                              ' IN (SELECT '.$relation->getForeign().
66 67 68
                              ' FROM '.$relation->getTable()->getTableName().' WHERE '.$field.$operator.$value.')';
                        }
                        $where = implode(' AND ', $where);
zYne's avatar
zYne committed
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
                    break;
                    default:
                        throw new Doctrine_Query_Exception('Unknown DQL function: '.$func);
                }
            } else {
                $table     = $this->query->load($reference, false);
                $enumIndex = $table->enumIndex($field, trim($value,"'"));
                $alias     = $this->query->getTableAlias($reference);
                $table     = $this->query->getTable($alias);

                switch($operator) {
                    case '<':
                    case '>':
                    case '=':
                        if($enumIndex !== false)
                            $value  = $enumIndex;

                        $where      = $alias.'.'.$field.' '.$operator.' '.$value;
                    break;
                    default:
                        $where      = $this->query->getTableAlias($reference).'.'.$field.' '.$operator.' '.$value;
                }
91
            }
92
        } 
doctrine's avatar
doctrine committed
93 94 95
        return $where;
    }

96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
    public function getOperator($func) {
        switch($func) {
            case 'contains':
                $operator = ' = ';
            break;
            case 'regexp':
                $operator = $this->query->getConnection()->getRegexpOperator();
            break;
            case 'like':
                $operator = ' LIKE ';
            break;
        }
        return $operator;
    }

doctrine's avatar
doctrine committed
111 112 113 114
    public function __toString() {
        return ( ! empty($this->parts))?implode(" AND ", $this->parts):'';
    }
}
115