1: <?php
2:
3: namespace PHPixie\Database\Driver\Mongo\Parser;
4:
5: class Operator extends \PHPixie\Database\Parser\Operator
6: {
7: protected $operators = array(
8: 'generic' => array('<','<=','=','!=','ne', '>=','>','exists','type','mod','where','all','elemMatch','size' ),
9: 'between' => array('between', 'not between'),
10: 'in' => array('in', 'nin', 'not in'),
11: 'regex' => array('regex', 'not regex')
12: );
13:
14: protected $operatorMap = array(
15: '<' => 'lt',
16: '<=' => 'lte',
17: '!=' => 'ne',
18: '>=' => 'gte',
19: '>' => 'gt'
20: );
21:
22: protected $negationMap = array(
23: 'lt' => 'gte',
24: 'lte' => 'gt',
25: '=' => 'ne',
26: 'gt' => 'lte',
27: 'gte' => 'lt',
28: 'ne' => '=',
29: 'in' => 'nin',
30: 'nin' => 'in'
31: );
32:
33: protected $allowedIdOperators = array('<','<=','=','!=','ne', '>=','>', 'in', 'nin', 'not in', 'between', 'not between');
34:
35: public function parse($condition, $convertMongoId = true)
36: {
37: $field = $condition->field();
38: $operator = $condition->operator();
39: $method = $this->getMethodName($operator);
40:
41: if($convertMongoId && $field === '_id') {
42:
43: if(!in_array($operator, $this->allowedIdOperators, true)) {
44: throw new \PHPixie\Database\Exception\Parser("The '{$operator}' operator is not supported for _id field");
45: }
46:
47: return $this->$method(
48: $field,
49: $operator,
50: $condition->values(),
51: $condition->isNegated(),
52: true
53: );
54: }
55:
56: return $this->$method(
57: $field,
58: $operator,
59: $condition->values(),
60: $condition->isNegated()
61: );
62: }
63:
64: protected function parseRegex($field, $operator, $value, $negated)
65: {
66: if (count($value)!==1 && !is_string($value[0]))
67: throw new \PHPixie\Database\Exception\Parser("The '$operator' operator requires a single string parameter to be passed");
68:
69: $value[0] = new \MongoRegex($value[0]);
70:
71: if ($operator == 'not regex') {
72: $negated = !$negated;
73: $operator = 'regex';
74: }
75:
76: return $this->parseGeneric($field, $operator, $value, $negated);
77: }
78:
79: protected function parseIn($field, $operator, $value, $negated, $convertMongoId = false)
80: {
81: if (count($value)!==1 && !is_array($value[0]))
82: throw new \PHPixie\Database\Exception\Parser("The '$operator' operator requires a single array parameter to be passed");
83:
84: if($convertMongoId) {
85: foreach($value[0] as $key => $id) {
86: $value[0][$key] = new \MongoId($id);
87: }
88: }
89:
90: if ($operator == 'not in')
91: $operator = 'nin';
92:
93: return $this->parseGeneric($field, $operator, $value, $negated);
94: }
95:
96: protected function parseGeneric($field, $operator, $value, $negated, $convertMongoId = false)
97: {
98: if (!is_array($value) || count($value) !== 1)
99: throw new \PHPixie\Database\Exception\Parser("The '$operator' operator requires a single array parameter to be passed");
100:
101: if(isset($this->operatorMap[$operator]))
102: $operator = $this->operatorMap[$operator];
103: if ($negated && isset($this->negationMap[$operator])) {
104: $operator = $this->negationMap[$operator];
105: $negated = false;
106: }
107:
108: $value = $value[0];
109:
110: if($convertMongoId) {
111: $value = new \MongoId($value);
112: }
113:
114: if ($operator === '=') {
115: $condition = $value;
116: } else {
117: $condition = array(('$'.$operator) => $value);
118: if ($negated)
119: $condition = array('$not' => $condition);
120: }
121:
122: return array($field => $condition);
123: }
124:
125: protected function parseBetween($field, $operator, $range, $negated, $convertMongoId = false)
126: {
127: if (count($range) !== 2)
128: throw new \PHPixie\Database\Exception\Parser("The '$operator' operator requires two parameters to be passed");
129: if($operator === 'not between')
130: $negated = !$negated;
131:
132: if($convertMongoId) {
133: foreach($range as $key => $id) {
134: $range[$key] = new \MongoId($id);
135: }
136: }
137:
138: $left = !$negated ? '$gte' : '$lt';
139: $right = !$negated ? '$lte' : '$gt';
140:
141: return array(
142: $field => array(
143: $left => $range[0],
144: $right => $range[1]
145: )
146: );
147: }
148:
149: }
150: