Fixed bug #14182: Multiple join conditions are not supported
authorXavier Perseguers <typo3@perseguers.ch>
Thu, 22 Apr 2010 14:25:53 +0000 (14:25 +0000)
committerXavier Perseguers <typo3@perseguers.ch>
Thu, 22 Apr 2010 14:25:53 +0000 (14:25 +0000)
git-svn-id: https://svn.typo3.org/TYPO3v4/Core/trunk@7426 709f56b5-9817-0410-a4d7-c38de5d9e867

ChangeLog
t3lib/class.t3lib_sqlparser.php

index cd744dd..90c23fc 100755 (executable)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2010-04-22  Xavier Perseguers  <typo3@perseguers.ch>
+
+       * Fixed bug #14182: Multiple join conditions are not supported
+
 2010-04-22 Jochen Rau <jochen.rau@typoplanet.de>
 
        * Fixed bug #14131: Styling of cookie warning is hardcoded (thanks to Jigal van Hemert)
index 1492bd6..7a96cc4 100644 (file)
@@ -938,32 +938,48 @@ class t3lib_sqlparser {
                                        if (!$this->nextPart($parseString, '^(ON[[:space:]]+)')) {
                                                return $this->parseError('No join condition found in parseFromTables()!', $parseString);
                                        }
-                                       $field1 = $this->nextPart($parseString,'^([[:alnum:]_.]+)[[:space:]]*=[[:space:]]*', 1);
-                                       $field2 = $this->nextPart($parseString,'^([[:alnum:]_.]+)[[:space:]]+');
-                                       if ($field1 && $field2) {
-
-                                               // Explode fields into field and table:
-                                               $tableField = explode('.', $field1, 2);
-                                               $field1 = array();
-                                               if (count($tableField) != 2) {
-                                                       $field1['table'] = '';
-                                                       $field1['field'] = $tableField[0];
+                                       $stack[$pnt]['JOIN'][$joinCnt]['ON'] = array();
+                                       $condition = array('operator' => '');
+                                       $parseCondition = TRUE;
+                                       while ($parseCondition) {
+                                               if (($fieldName = $this->nextPart($parseString, '^([[:alnum:]._]+)[[:space:]]*(<=|>=|<|>|=|!=)')) !== '') {
+                                                               // Parse field name into field and table:
+                                                       $tableField = explode('.', $fieldName, 2);
+                                                       $condition['left'] = array();
+                                                       if (count($tableField) == 2) {
+                                                               $condition['left']['table'] = $tableField[0];
+                                                               $condition['left']['field'] = $tableField[1];
+                                                       } else {
+                                                               $condition['left']['table'] = '';
+                                                               $condition['left']['field'] = $tableField[0];
+                                                       }
                                                } else {
-                                                       $field1['table'] = $tableField[0];
-                                                       $field1['field'] = $tableField[1];
+                                                       return $this->parseError('No join field found in parseFromTables()!', $parseString);
                                                }
-                                               $tableField = explode('.', $field2, 2);
-                                               $field2 = array();
-                                               if (count($tableField) != 2) {
-                                                       $field2['table'] = '';
-                                                       $field2['field'] = $tableField[0];
+                                                       // Find "comparator":
+                                               $condition['comparator'] = $this->nextPart($parseString, '^(<=|>=|<|>|=|!=)');
+                                               if (($fieldName = $this->nextPart($parseString, '^([[:alnum:]._]+)')) !== '') {
+                                                               // Parse field name into field and table:
+                                                       $tableField = explode('.', $fieldName, 2);
+                                                       $condition['right'] = array();
+                                                       if (count($tableField) == 2) {
+                                                               $condition['right']['table'] = $tableField[0];
+                                                               $condition['right']['field'] = $tableField[1];
+                                                       } else {
+                                                               $condition['right']['table'] = '';
+                                                               $condition['right']['field'] = $tableField[0];
+                                                       }
+                                               } else {
+                                                       return $this->parseError('No join field found in parseFromTables()!', $parseString);
+                                               }
+                                               $stack[$pnt]['JOIN'][$joinCnt]['ON'][] = $condition;
+                                               if (($operator = $this->nextPart($parseString, '^(AND|OR)')) !== '') {
+                                                       $condition = array('operator' => $operator);
                                                } else {
-                                                       $field2['table'] = $tableField[0];
-                                                       $field2['field'] = $tableField[1];
+                                                       $parseCondition = FALSE;
                                                }
-                                               $stack[$pnt]['JOIN'][$joinCnt]['ON'] = array($field1, $field2);
-                                               $joinCnt++;
-                                       } else return $this->parseError('No join fields found in parseFromTables()!', $parseString);
+                                       }
+                                       $joinCnt++;
                                } else return $this->parseError('No join table found in parseFromTables()!', $parseString);
                        }
 
@@ -1326,6 +1342,8 @@ class t3lib_sqlparser {
                        $parseString = ltrim(substr($parseString,strlen($reg[$trimAll?0:1])));
                        return $reg[1];
                }
+                       // No match found
+               return '';
        }
 
        /**
@@ -1862,11 +1880,16 @@ class t3lib_sqlparser {
                                                        $outputParts[$k] .= ' ' . $join['as_keyword'] . ' ' . $join['as'];
                                                }
                                                $outputParts[$k] .= ' ON ';
-                                               $outputParts[$k] .= ($join['ON'][0]['table']) ? $join['ON'][0]['table'] . '.' : '';
-                                               $outputParts[$k] .= $join['ON'][0]['field'];
-                                               $outputParts[$k] .= '=';
-                                               $outputParts[$k] .= ($join['ON'][1]['table']) ? $join['ON'][1]['table'] . '.' : '';
-                                               $outputParts[$k] .= $join['ON'][1]['field'];
+                                               foreach ($join['ON'] as $condition) {
+                                                       if ($condition['operator'] !== '') {
+                                                               $outputParts[$k] .= ' ' . $condition['operator'] . ' ';
+                                                       }
+                                                       $outputParts[$k] .= ($condition['left']['table']) ? $condition['left']['table'] . '.' : '';
+                                                       $outputParts[$k] .= $condition['left']['field'];
+                                                       $outputParts[$k] .= $condition['comparator'];
+                                                       $outputParts[$k] .= ($condition['right']['table']) ? $condition['right']['table'] . '.' : '';
+                                                       $outputParts[$k] .= $condition['right']['field'];
+                                               }
                                        }
                                }
                        }