Feature #21903 » 13135_core_v2.diff
t3lib/class.t3lib_sqlparser.php (working copy) | ||
---|---|---|
}
|
||
} else { // Outside parenthesis, looking for next field:
|
||
// Looking for a known function (only known functions supported)
|
||
$func = $this->nextPart($parseString,'^(count|max|min|floor|sum|avg)[[:space:]]*\(');
|
||
if ($func) {
|
||
$parseString = trim(substr($parseString,1)); // Strip of "("
|
||
$stack[$pnt]['type'] = 'function';
|
||
$stack[$pnt]['function'] = $func;
|
||
$level++; // increse parenthesis level counter.
|
||
// Looking for a flow-control construct (only known constructs supported)
|
||
if (preg_match('/^case([[:space:]][[:alnum:]\*._]+)?[[:space:]]when/i', $parseString)) {
|
||
$stack[$pnt]['type'] = 'flow-control';
|
||
$stack[$pnt]['flow-control'] = $this->parseCaseStatement($parseString);
|
||
// Looking for "AS" alias:
|
||
if ($as = $this->nextPart($parseString, '^(AS)[[:space:]]+')) {
|
||
$stack[$pnt]['as'] = $this->nextPart($parseString, '^([[:alnum:]_]+)(,|[[:space:]]+)');
|
||
$stack[$pnt]['as_keyword'] = $as;
|
||
}
|
||
} else {
|
||
$stack[$pnt]['distinct'] = $this->nextPart($parseString,'^(distinct[[:space:]]+)');
|
||
// Otherwise, look for regular fieldname:
|
||
if ($fieldName = $this->nextPart($parseString,'^([[:alnum:]\*._]+)(,|[[:space:]]+)')) {
|
||
$stack[$pnt]['type'] = 'field';
|
||
// Explode fieldname into field and table:
|
||
$tableField = explode('.',$fieldName,2);
|
||
if (count($tableField)==2) {
|
||
$stack[$pnt]['table'] = $tableField[0];
|
||
$stack[$pnt]['field'] = $tableField[1];
|
||
// Looking for a known function (only known functions supported)
|
||
$func = $this->nextPart($parseString,'^(count|max|min|floor|sum|avg)[[:space:]]*\(');
|
||
if ($func) {
|
||
$parseString = trim(substr($parseString,1)); // Strip of "("
|
||
$stack[$pnt]['type'] = 'function';
|
||
$stack[$pnt]['function'] = $func;
|
||
$level++; // increse parenthesis level counter.
|
||
} else {
|
||
$stack[$pnt]['distinct'] = $this->nextPart($parseString,'^(distinct[[:space:]]+)');
|
||
// Otherwise, look for regular fieldname:
|
||
if ($fieldName = $this->nextPart($parseString,'^([[:alnum:]\*._]+)(,|[[:space:]]+)')) {
|
||
$stack[$pnt]['type'] = 'field';
|
||
|
||
// Explode fieldname into field and table:
|
||
$tableField = explode('.',$fieldName,2);
|
||
if (count($tableField)==2) {
|
||
$stack[$pnt]['table'] = $tableField[0];
|
||
$stack[$pnt]['field'] = $tableField[1];
|
||
} else {
|
||
$stack[$pnt]['table'] = '';
|
||
$stack[$pnt]['field'] = $tableField[0];
|
||
}
|
||
} else {
|
||
$stack[$pnt]['table'] = '';
|
||
$stack[$pnt]['field'] = $tableField[0];
|
||
return $this->parseError('No field name found as expected in parseFieldList()',$parseString);
|
||
}
|
||
} else {
|
||
return $this->parseError('No field name found as expected in parseFieldList()',$parseString);
|
||
}
|
||
}
|
||
}
|
||
... | ... | |
}
|
||
/**
|
||
* Parsing a CASE ... WHEN flow-control construct.
|
||
* The output from this function can be compiled back with ->compileCaseStatement()
|
||
*
|
||
* @param string The string with the CASE ... WHEN construct, eg. "CASE field WHEN 1 THEN 0 ELSE ..." etc. NOTICE: passed by reference!
|
||
* @return array If successful parsing, returns an array, otherwise an error string.
|
||
* @see compileCaseConstruct()
|
||
*/
|
||
protected function parseCaseStatement(&$parseString) {
|
||
$result = array();
|
||
$result['type'] = $this->nextPart($parseString, '^(case)[[:space:]]+');
|
||
if (!preg_match('/^when[[:space:]]+/i', $parseString)) {
|
||
$value = $this->getValue($parseString);
|
||
if (!(isset($value[1]) || is_numeric($value[0]))) {
|
||
$result['case_field'] = $value[0];
|
||
} else {
|
||
$result['case_value'] = $value;
|
||
}
|
||
}
|
||
$result['when'] = array();
|
||
while ($this->nextPart($parseString, '^(when)[[:space:]]')) {
|
||
$when = array();
|
||
$when['when_value'] = $this->parseWhereClause($parseString, '^(then)[[:space:]]+');
|
||
$when['then_value'] = $this->getValue($parseString);
|
||
$result['when'][] = $when;
|
||
}
|
||
if ($this->nextPart($parseString, '^(else)[[:space:]]+')) {
|
||
$result['else'] = $this->getValue($parseString);
|
||
}
|
||
if (!$this->nextPart($parseString, '^(end)[[:space:]]+')) {
|
||
return $this->parseError('No "end" keyword found as expected in parseCaseStatement()', $parseString);
|
||
}
|
||
return $result;
|
||
}
|
||
/**
|
||
* Parsing the tablenames in the "FROM [$parseString] WHERE" part of a query into an array.
|
||
* The success of this parsing determines if that part of the query is supported by TYPO3.
|
||
*
|
||
... | ... | |
case 'function':
|
||
$outputParts[$k] = $v['function'].'('.$v['func_content'].')';
|
||
break;
|
||
case 'flow-control':
|
||
if ($v['flow-control']['type'] === 'CASE') {
|
||
$outputParts[$k] = $this->compileCaseStatement($v['flow-control']);
|
||
}
|
||
break;
|
||
case 'field':
|
||
$outputParts[$k] = ($v['distinct']?$v['distinct']:'').($v['table']?$v['table'].'.':'').$v['field'];
|
||
break;
|
||
... | ... | |
}
|
||
/**
|
||
* Compiles a CASE ... WHEN flow-control construct based on input array (made with ->parseCaseStatement())
|
||
*
|
||
* @param array Array of case components, (made with ->parseCaseStatement())
|
||
* @return string case when string
|
||
* @see parseCaseStatement()
|
||
*/
|
||
protected function compileCaseStatement(array $components) {
|
||
$statement = 'CASE';
|
||
if (isset($components['case_field'])) {
|
||
$statement .= ' ' . $components['case_field'];
|
||
} elseif (isset($components['case_value'])) {
|
||
$statement .= ' ' . $components['case_value'][1] . $components['case_value'][0] . $components['case_value'][1];
|
||
}
|
||
foreach ($components['when'] as $when) {
|
||
$statement .= ' WHEN ';
|
||
$statement .= $this->compileWhereClause($when['when_value']);
|
||
$statement .= ' THEN ';
|
||
$statement .= $when['then_value'][1] . $when['then_value'][0] . $when['then_value'][1];
|
||
}
|
||
if (isset($components['else'])) {
|
||
$statement .= ' ELSE ';
|
||
$statement .= $components['else'][1] . $components['else'][0] . $components['else'][1];
|
||
}
|
||
$statement .= ' END';
|
||
return $statement;
|
||
}
|
||
/**
|
||
* Compiles a "FROM [output] WHERE..:" table list based on input array (made with ->parseFromTables())
|
||
*
|
||
* @param array Array of table names, (made with ->parseFromTables())
|