public static function getClause($statement, $list, $clause, $type = 0, $skipFirst = true)
{
/**
* The index of the current clause.
*
* @var int $currIdx
*/
$currIdx = 0;
/**
* The count of brackets.
* We keep track of them so we won't insert the clause in a subquery.
*
* @var int $brackets
*/
$brackets = 0;
/**
* The string to be returned.
*
* @var string $ret
*/
$ret = '';
/**
* The clauses of this type of statement and their index.
*
* @var array $clauses
*/
$clauses = array_flip(array_keys($statement->getClauses()));
/**
* Lexer used for lexing the clause.
*
* @var Lexer $lexer
*/
$lexer = new Lexer($clause);
/**
* The type of this clause.
*
* @var string $clauseType
*/
$clauseType = $lexer->list->getNextOfType(Token::TYPE_KEYWORD)->value;
/**
* The index of this clause.
*
* @var int $clauseIdx
*/
$clauseIdx = $clauses[$clauseType];
$firstClauseIdx = $clauseIdx;
$lastClauseIdx = $clauseIdx + 1;
// Determining the behavior of this function.
if ($type === -1) {
$firstClauseIdx = -1;
// Something small enough.
$lastClauseIdx = $clauseIdx - 1;
} elseif ($type === 1) {
$firstClauseIdx = $clauseIdx + 1;
$lastClauseIdx = 10000;
// Something big enough.
} elseif (is_string($type)) {
if ($clauses[$type] > $clauseIdx) {
$firstClauseIdx = $clauseIdx + 1;
$lastClauseIdx = $clauses[$type] - 1;
} else {
$firstClauseIdx = $clauses[$type] + 1;
$lastClauseIdx = $clauseIdx - 1;
}
}
// This option is unavailable for multiple clauses.
if ($type !== 0) {
$skipFirst = false;
}
for ($i = $statement->first; $i <= $statement->last; ++$i) {
$token = $list->tokens[$i];
if ($token->type === Token::TYPE_COMMENT) {
continue;
}
if ($token->type === Token::TYPE_OPERATOR) {
if ($token->value === '(') {
++$brackets;
} elseif ($token->value === ')') {
--$brackets;
}
}
if ($brackets == 0) {
// Checking if the section was changed.
if ($token->type === Token::TYPE_KEYWORD && isset($clauses[$token->value]) && $clauses[$token->value] >= $currIdx) {
$currIdx = $clauses[$token->value];
if ($skipFirst && $currIdx == $clauseIdx) {
// This token is skipped (not added to the old
// clause) because it will be replaced.
continue;
}
}
}
if ($firstClauseIdx <= $currIdx && $currIdx <= $lastClauseIdx) {
$ret .= $token->token;
}
}
return trim($ret);
}