/** * Create a query tree node representing the given query and using the field given as * $leftOperand as the attribute (left leaf of the tree) * * @param String $query The query to create the node from * @param String $leftOperand The attribute use for the node * @return Node|null */ public function createTreeNode($query, $leftOperand) { list($operator, $timeQuery) = $this->getOperatorAndTimeStringFromQuery($query); if ($operator === null || $timeQuery === null) { return null; } $node = Node::createOperatorNode($operator, $leftOperand, $timeQuery); $node->context = Node::CONTEXT_TIMESTRING; return $node; }
/** * Parse a backend specific filter expression and return a Query\Node object * * @param $expression The expression to parse * @param $parameters Optional parameters for the expression * * @return Node A query node or null if it's an invalid expression */ protected function parseFilterExpression($expression, $parameter = null) { $splitted = explode(' ', $expression, 3); if (count($splitted) === 1 && $parameter) { return Node::createOperatorNode(Node::OPERATOR_EQUALS, $splitted[0], $parameter); } elseif (count($splitted) === 2 && $parameter) { Node::createOperatorNode($splitted[0], $splitted[1], is_string($parameter)); return Node::createOperatorNode(Node::OPERATOR_EQUALS, $splitted[0], $parameter); } elseif (count($splitted) === 3) { if (trim($splitted[2]) === '?') { return Node::createOperatorNode($splitted[1], $splitted[0], $parameter); } else { return Node::createOperatorNode($splitted[1], $splitted[0], $splitted[2]); } } return null; }
/** * Create a query tree containing this filter * * Query parts that couldn't be parsed can be retrieved with Filter::getIgnoredQueryParts * * @param String $query The query string to parse into a query tree * @return Tree The resulting query tree (empty for invalid queries) */ public function createQueryTreeForFilter($query) { $this->ignoredQueryParts = array(); $right = $query; $domain = null; $tree = new Tree(); do { list($left, $conjunction, $right) = $this->splitQueryAtNextConjunction($right); $domain = $this->getFirstDomainForQuery($left); if ($domain === null) { $this->ignoredQueryParts[] = $left; continue; } $node = $domain->convertToTreeNode($left); if (!$node) { $this->ignoredQueryParts[] = $left; continue; } $tree->insert($node); if ($conjunction === 'AND') { $tree->insert(Node::createAndNode()); } elseif ($conjunction === 'OR') { $tree->insert(Node::createOrNode()); } } while ($right !== null); return $tree; }
/** * Create a query tree node representing the given query and using the field given as * $leftOperand as the attribute (left leaf of the tree) * * @param String $query The query to create the node from * @param String $leftOperand The attribute use for the node * @return Node|null */ public function createTreeNode($query, $leftOperand) { list($field, $value, $subQuery) = $this->getFieldValueForQuery($query); if ($field === null || $value === null) { return null; } $node = Node::createOperatorNode(Node::OPERATOR_EQUALS, $field, $value); if ($this->subFilter && $subQuery && $this->subFilter->isValidQuery($subQuery)) { $subNode = $this->subFilter->createTreeNode($subQuery, $this->timeField); $conjunctionNode = Node::createAndNode(); $conjunctionNode->left = $subNode; $conjunctionNode->right = $node; $node = $conjunctionNode; } return $node; }
/** * Copy the given node or branch into the given tree * * @param Node $node The node to copy * @param Tree $tree The tree to insert the copied node and it's subnodes to */ private function copyBranch(Node $node, Tree &$tree) { if ($node->type === Node::TYPE_OPERATOR) { $copy = Node::createOperatorNode($node->operator, $node->left, $node->right); $copy->context = $node->context; $tree->insert($copy); } else { if ($node->left) { $this->copyBranch($node->left, $tree); } $tree->insert($node->type === Node::TYPE_OR ? Node::createOrNode() : Node::createAndNode()); if ($node->right) { $this->copyBranch($node->right, $tree); } } }