diff --git a/extension/Documentation/Manual.rst b/extension/Documentation/Manual.rst index 1a39d0a9a21a2f656d82911a68bd4db020ea2eee..12a3b62d2a8013a5a1f2391562b2f4bc7ce0562c 100644 --- a/extension/Documentation/Manual.rst +++ b/extension/Documentation/Manual.rst @@ -757,6 +757,10 @@ QFQ Keywords (Bodytext) +-------------------+---------------------------------------------------------------------------------+ | <level>.fend | End token for every field (=column) | +-------------------+---------------------------------------------------------------------------------+ + | <level>.fsep | Separator token between fields (=columns) | + +-------------------+---------------------------------------------------------------------------------+ + | <level>.fskipwrap | Comma separated list of column id's. Skip wrapping of indexed columns. | + +-------------------+---------------------------------------------------------------------------------+ | <level>.shead | Static start token for whole <level>, independent if records are selected | | | Shown before `head`. | +-------------------+---------------------------------------------------------------------------------+ @@ -777,8 +781,6 @@ QFQ Keywords (Bodytext) +-------------------+---------------------------------------------------------------------------------+ | <level>.rsep | Seperator token between rows | +-------------------+---------------------------------------------------------------------------------+ - | <level>.fsep | Seperator token between fields (=columns) | - +-------------------+---------------------------------------------------------------------------------+ | <level>.sql | SQL Query | +-------------------+---------------------------------------------------------------------------------+ | <level>.althead | If <level>.sql is empty, these token will be rendered. | @@ -5452,15 +5454,20 @@ Report Example 1:: Wrapping rows and columns: Level -------------------------------- -Order and nesting of queries, will be defined with a typoscript-like syntax: level.sublevel1.subsublevel2. ... -Each 'level' directive needs a final key, e.g: 20.30.10. **sql**. A key **sql** is necessary in order to process a level. +Order and nesting of queries, will be defined with a TypoScript-alike syntax:: + + level.sublevel1.subsublevel2. ... + +* Each 'level' directive needs a final key, e.g: 20.30.10. **sql**. +* A key **sql** is necessary in order to process a level. + See all `QFQ Keywords (Bodytext)`_. Processing of columns in the SQL result --------------------------------------- -* The content of all columns of all rows will be printed sequentially, without separator. -* Rows with `special-column-names`_ will be processed in a special way. +* The content of all columns of all rows will be printed sequentially, without separator (except one is defined). +* Rows with `special-column-names`_ will be rendered first and the output is taken as content. .. _special-column-names: @@ -7151,17 +7158,31 @@ Result:: Diana Ross -One column 'rend':: +One column 'rend' as linebreak - no extra column '<br>' needed:: - 10.sql = SELECT p.firstName, " " , p.lastName FROM exp_person AS p + 10.sql = SELECT p.firstName, " " , p.lastName, " ", p.country FROM exp_person AS p 10.rend = <br> Result:: - Billie Holiday - Elvis Presley - Louis Armstrong - Diana Ross + Billie Holiday USA + Elvis Presley USA + Louis Armstrong USA + Diana Ross USA + +Same with 'fsep' (column " " removed): + + 10.sql = SELECT p.firstName, p.lastName, p.country FROM exp_person AS p + 10.rend = <br> + 10.fsep = " " + +Result:: + + Billie Holiday USA + Elvis Presley USA + Louis Armstrong USA + Diana Ross USA + More HTML:: @@ -7255,6 +7276,55 @@ Best practice *recommendation* for using parameter - see `access-column-values`_ } } +Create HTML tables:: + + 10 { + sql = SELECT p.firstName, p.lastName, p.country FROM Person AS p + head = <table class="table"> + tail = </table> + rbeg = <tr> + rend = </tr> + fbeg = <td> + fend = </td> + } + +Maybe a few columns belongs together and should be in one column. + +Joining columns, variant A: firstName and lastName in one column:: + + 10 { + sql = SELECT CONCAT(p.firstName, ' ', p.lastName), p.country FROM Person AS p + head = <table class="table"> + tail = </table> + rbeg = <tr> + rend = </tr> + fbeg = <td> + fend = </td> + } + +Joining columns, variant B: firstName and lastName in one column:: + + 10 { + sql = SELECT '<td>', p.firstName, ' ', p.lastName, '</td><td>', p.country, '</td>' FROM Person AS p + head = <table class="table"> + tail = </table> + rbeg = <tr> + rend = </tr> + } + +Joining columns, variant C: firstName and lastName in one column:: + + 10 { + sql = SELECT '<td>', p.firstName, ' ', p.lastName, '</td>', p.country FROM Person AS p + head = <table class="table"> + tail = </table> + rbeg = <tr> + rend = </tr> + fbeg = <td> + fend = </td> + fskipwrap = 1,2,3,4,5 + } + * Columns starting with a '_' won't be printed but can be accessed as regular columns. diff --git a/extension/Source/core/Constants.php b/extension/Source/core/Constants.php index 80245673346b1c4b0be0846dbbb420f21069cccf..2c2c250a7b19829b096b615db06fd28b3e04ff36 100644 --- a/extension/Source/core/Constants.php +++ b/extension/Source/core/Constants.php @@ -1437,6 +1437,7 @@ const TOKEN_RSEP = 'rsep'; const TOKEN_FBEG = 'fbeg'; const TOKEN_FEND = 'fend'; const TOKEN_FSEP = 'fsep'; +const TOKEN_FSKIPWRAP = 'fskipwrap'; const TOKEN_RBGD = 'rbgd'; const TOKEN_DEBUG = 'debug'; const TOKEN_FORM = CLIENT_FORM; @@ -1445,7 +1446,7 @@ const TOKEN_DEBUG_BODYTEXT = TYPO3_DEBUG_SHOW_BODY_TEXT; const TOKEN_DB_INDEX = F_DB_INDEX; const TOKEN_CONTENT = 'content'; -const TOKEN_VALID_LIST = 'sql|head|althead|altsql|tail|shead|stail|rbeg|rend|renr|rsep|fbeg|fend|fsep|rbgd|debug|form|r|debugShowBodyText|dbIndex|sqlLog|sqlLogMode|content'; +const TOKEN_VALID_LIST = 'sql|head|althead|altsql|tail|shead|stail|rbeg|rend|renr|rsep|fbeg|fend|fsep|fskipwrap|rbgd|debug|form|r|debugShowBodyText|dbIndex|sqlLog|sqlLogMode|content'; const TOKEN_COLUMN_CTRL = '_'; diff --git a/extension/Source/core/report/Report.php b/extension/Source/core/report/Report.php index b472874f85b628db8190c9b216c887d4d253aa19..5dc0dc7635d6b4cabcf93c59c73e27b3dc31bf79 100644 --- a/extension/Source/core/report/Report.php +++ b/extension/Source/core/report/Report.php @@ -518,10 +518,18 @@ class Report { $arrRbgd[] = ''; } + $fSkipWrap = array(); + if ('' != ($str = ($this->frArray[$fullLevel . "." . TOKEN_FSKIPWRAP]) ?? '')) { + $str = str_replace(' ', '', $str); + $fSkipWrap = explode(',', $str); + $fSkipWrap = array_flip($fSkipWrap); + } + //--------------------------------- - // Process each row of resultset + // Process each row of result set $columnValueSeparator = ""; $rowIndex = 0; + foreach ($result as $row) { // record number counter $this->variables->resultArray[$fullLevel . ".line."][LINE_COUNT] = ++$rowIndex; @@ -544,7 +552,7 @@ class Report { //----------------------------- // COLUMNS: Collect all columns - $contentLevel .= $this->collectRow($row, $keys, $fullLevel, $rowIndex); + $contentLevel .= $this->collectRow($row, $keys, $fullLevel, $rowIndex, $fSkipWrap); // REND $contentLevel .= $this->variables->doVariables($this->frArray[$fullLevel . "." . TOKEN_REND]); @@ -575,7 +583,7 @@ class Report { if (is_array($result)) { foreach ($result as $row) { $rowIndex = 0; - $contentLevel .= $this->collectRow($row, $keys, $fullLevel, $rowIndex); + $contentLevel .= $this->collectRow($row, $keys, $fullLevel, $rowIndex, array()); } } } @@ -664,11 +672,12 @@ class Report { * @throws \PhpOffice\PhpSpreadsheet\Reader\Exception * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception */ - private function collectRow(array $row, array $keys, $full_level, $rowIndex) { + private function collectRow(array $row, array $keys, $full_level, $rowIndex, array $fSkipWrap) { $content = ""; $assoc = array(); $fsep = ''; + for ($ii = 0; $ii < count($keys); $ii++) { // Debugging @@ -688,10 +697,18 @@ class Report { if ($flagOutput) { //prints - $content .= $this->variables->doVariables($fsep); - $content .= $this->variables->doVariables($this->frArray[$full_level . "." . TOKEN_FBEG]); + + if (!isset($fSkipWrap[$ii + 1])) { + $content .= $this->variables->doVariables($fsep); + $content .= $this->variables->doVariables($this->frArray[$full_level . "." . TOKEN_FBEG]); + } + $content .= $renderedColumn; - $content .= $this->variables->doVariables($this->frArray[$full_level . "." . TOKEN_FEND]); + + if (!isset($fSkipWrap[$ii + 1])) { + $content .= $this->variables->doVariables($this->frArray[$full_level . "." . TOKEN_FEND]); + } + $fsep = $this->frArray[$full_level . "." . TOKEN_FSEP]; } }