Skip to content

Commit

Permalink
Merge pull request #59 from hoogi91/feature/more-table-options
Browse files Browse the repository at this point in the history
Feature/more table options
  • Loading branch information
hoogi91 authored Jan 27, 2022
2 parents f408e33 + 9d88580 commit a7003f9
Show file tree
Hide file tree
Showing 12 changed files with 354 additions and 97 deletions.
8 changes: 6 additions & 2 deletions Classes/DataProcessing/AbstractProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ public function process(
$this->fileRepository->findFileReferenceByUid($dsnValue->getFileReference())
);

$processedData[$targetVariableName] = $this->getTemplateData($dsnValue, $spreadsheet);
$processedData[$targetVariableName] = $this->getTemplateData($dsnValue, $spreadsheet, $processedData);
} catch (InvalidDataSourceNameException|ResourceDoesNotExistException|ReaderException $exception) {
// if DSN could not be parsed or is invalid the output is empty
// or the extraction failed
Expand All @@ -128,5 +128,9 @@ public function process(
return $processedData;
}

abstract protected function getTemplateData(DsnValueObject $dsn, Spreadsheet $spreadsheet): array;
abstract protected function getTemplateData(
DsnValueObject $dsn,
Spreadsheet $spreadsheet,
array $processedData
): array;
}
24 changes: 21 additions & 3 deletions Classes/DataProcessing/SpreadsheetProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,34 @@ class SpreadsheetProcessor extends AbstractProcessor
* Get template relevant data
* @param DsnValueObject $dsn DSN which is processed
* @param Spreadsheet $spreadsheet Spreadsheet that is processed
* @param array $processedData Processed data
* @return array
*/
protected function getTemplateData(DsnValueObject $dsn, Spreadsheet $spreadsheet): array
protected function getTemplateData(DsnValueObject $dsn, Spreadsheet $spreadsheet, array $processedData): array
{
$extraction = $this->getExtractorService()->getDataByDsnValueObject($dsn, true);
$headData = $extraction->getHeadData();
$bodyData = $extraction->getBodyData();

// check if first row of body data should be header
// 0 = "no header" | 1 = "top" | 2 = "left"
$tableHeaderPosition = (int)($processedData['data']['table_header_position'] ?? 0);
if (empty($headData) && !empty($bodyData) && $tableHeaderPosition === 1) {
$headData[] = array_shift($bodyData);
}

// check if last row of body data should be footer
$enableTableFooter = (bool)($processedData['data']['table_tfoot'] ?? 0);
if ($enableTableFooter === true && !empty($bodyData)) {
$footData[] = array_pop($bodyData);
}

return [
'sheetIndex' => $dsn->getSheetIndex(),
'headData' => $extraction->getHeadData(),
'bodyData' => $extraction->getBodyData(),
'firstColumnIsHeader' => empty($headData) && $tableHeaderPosition === 2,
'headData' => $headData,
'bodyData' => $bodyData,
'footData' => $footData ?? [],
];
}
}
3 changes: 2 additions & 1 deletion Classes/DataProcessing/TabsProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ class TabsProcessor extends AbstractProcessor
* Get template relevant data
* @param DsnValueObject $dsn DSN which is processed
* @param Spreadsheet $spreadsheet Spreadsheet that is processed
* @param array $processedData Processed data
* @return array
*/
protected function getTemplateData(DsnValueObject $dsn, Spreadsheet $spreadsheet): array
protected function getTemplateData(DsnValueObject $dsn, Spreadsheet $spreadsheet, array $processedData): array
{
$sheetData = [];
foreach ($spreadsheet->getAllSheets() as $worksheet) {
Expand Down
69 changes: 69 additions & 0 deletions Classes/ViewHelpers/Cell/RenderViewHelper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

namespace Hoogi91\Spreadsheets\ViewHelpers\Cell;

use Closure;
use Hoogi91\Spreadsheets\Domain\ValueObject\CellDataValueObject;
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;

/**
* Class RenderViewHelper
* @package Hoogi91\Spreadsheets\ViewHelpers\Cell
*/
class RenderViewHelper extends AbstractViewHelper
{
use CompileWithRenderStatic;

/**
* @var bool
*/
protected $escapeChildren = false;

/**
* @var bool
*/
protected $escapeOutput = false;

/**
* Initialize arguments.
*/
public function initializeArguments(): void
{
parent::initializeArguments();
$this->registerArgument(
'cell',
CellDataValueObject::class,
'Cell object for which table cell should be rendered',
true
);
$this->registerArgument('isHeader', 'bool', 'True to render <th> otherwise it will be <td>', false, false);
}

/**
* @param array $arguments
* @param Closure $renderChildrenClosure
* @param RenderingContextInterface $renderingContext
*
* @return string
*/
public static function renderStatic(
array $arguments,
Closure $renderChildrenClosure,
RenderingContextInterface $renderingContext
): string {
$cell = $arguments['cell'] ?? null;
if ($cell instanceof CellDataValueObject) {
$attributes = $cell->getClass() !== '' ? ' class="' . $cell->getClass() . '"' : '';
$attributes .= $cell->getRowspan() > 0 ? ' rowspan="' . $cell->getRowspan() . '"' : '';
$attributes .= $cell->getColspan() > 0 ? ' colspan="' . $cell->getColspan() . '"' : '';
}

return sprintf(
(bool)($arguments['isHeader'] ?? 0) === true ? '<th%s>%s</th>' : '<td%s>%s</td>',
$attributes ?? '',
$renderChildrenClosure()
);
}
}
16 changes: 9 additions & 7 deletions Configuration/TCA/Overrides/tt_content.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
[
'LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang.xlf:wizards.spreadsheets_tabs.title',
'spreadsheets_tabs',
'mimetypes-open-document-spreadsheet',
'mimetypes-open-document-database',
],
'after:spreadsheets_table'
);
Expand Down Expand Up @@ -59,7 +59,7 @@

// add own palettes
$GLOBALS['TCA'][$table]['palettes']['tableSpreadsheetLayout'] = [
'showitem' => 'tx_spreadsheets_ignore_styles;LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang.xlf:tca.tx_spreadsheets_ignore_styles, table_class',
'showitem' => 'tx_spreadsheets_ignore_styles;LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang.xlf:tca.tx_spreadsheets_ignore_styles, table_class, table_header_position, table_tfoot',
];

// Configure the default backend fields for the content element
Expand Down Expand Up @@ -88,6 +88,7 @@

'columnsOverrides' => [
'bodytext' => [
'displayCond' => 'FIELD:CType:=:spreadsheets_table',
'config' => [
'renderType' => 'spreadsheetInput',
'uploadField' => 'tx_spreadsheets_assets',
Expand All @@ -98,18 +99,19 @@
'table_class' => [
'displayCond' => 'FIELD:tx_spreadsheets_ignore_styles:>:0',
],
'table_header_position' => [
'displayCond' => 'FIELD:CType:=:spreadsheets_table',
],
'table_tfoot' => [
'displayCond' => 'FIELD:CType:=:spreadsheets_table',
],
],
];

if ($isTabsFeatureEnabled === true) {
// use same settings for tabs
$GLOBALS['TCA'][$table]['types']['spreadsheets_tabs'] = $GLOBALS['TCA'][$table]['types']['spreadsheets_table'];
$GLOBALS['TCA'][$table]['types']['spreadsheets_tabs']['columnsOverrides']['tx_spreadsheets_assets']['config']['maxitems'] = 1;
$GLOBALS['TCA'][$table]['types']['spreadsheets_tabs']['showitem'] = preg_replace(
'/bodytext;LLL.*bodytext,/',
'',
$GLOBALS['TCA'][$table]['types']['spreadsheets_tabs']['showitem']
);
}
})(
'spreadsheets',
Expand Down
30 changes: 0 additions & 30 deletions Resources/Private/Partials/Cell.html

This file was deleted.

13 changes: 8 additions & 5 deletions Resources/Private/Partials/Rows.html
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
xmlns:s="http://typo3.org/ns/Hoogi91/Spreadsheets/ViewHelpers"
data-namespace-typo3-fluid="true">

<f:section name="Main">
<f:for each="{rowsData}" key="row" as="rowData" iteration="rowIterator">
<f:for each="{rowsData}" as="rowData">
<tr>
<f:for each="{rowData}" key="column" as="value" iteration="columnIterator">
<f:render partial="Cell" section="Main"
arguments="{cell: value, row: row, column: column, rowIterator: rowIterator, columnIterator: columnIterator}"/>
<f:for each="{rowData}" as="value" iteration="columnIterator">
<s:cell.render cell="{value}" isHeader="{columnIterator.isFirst} && {firstColumnIsHeader}">
<s:cell.value.formatted cell="{value}"/>
</s:cell.render>
</f:for>
</tr>
</f:for>
Expand Down
8 changes: 7 additions & 1 deletion Resources/Private/Partials/Table.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,15 @@
</f:if>
<f:if condition="{spreadsheet.bodyData}">
<tbody>
<f:render partial="Rows" section="Main" arguments="{rowsData: spreadsheet.bodyData}"/>
<f:render partial="Rows" section="Main"
arguments="{rowsData: spreadsheet.bodyData, firstColumnIsHeader: spreadsheet.firstColumnIsHeader}"/>
</tbody>
</f:if>
<f:if condition="{spreadsheet.footData}">
<tfoot>
<f:render partial="Rows" section="Main" arguments="{rowsData: spreadsheet.footData}"/>
</tfoot>
</f:if>
</table>
</f:if>
</f:section>
Expand Down
83 changes: 83 additions & 0 deletions Tests/Functional/ViewHelpers/CellRenderViewHelperTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?php

namespace Hoogi91\Spreadsheets\Tests\Functional\ViewHelpers;

use Hoogi91\Spreadsheets\Domain\ValueObject\CellDataValueObject;

class CellRenderViewHelperTest extends AbstractViewHelperTestCase
{
private const CELL_DEFAULT_CONTENT = '<td%s>content</td>';
private const CELL_HEADER_CONTENT = '<th%s>content</th>';

/**
* @dataProvider cellProvider
*/
public function testRender(string $expectedAttributes, ?array $cellMock, bool $isHeader = false): void
{
if ($cellMock !== null) {
$cellValue = $this->createConfiguredMock(CellDataValueObject::class, $cellMock);
}

self::assertEquals(
sprintf(
$isHeader === false ? self::CELL_DEFAULT_CONTENT : self::CELL_HEADER_CONTENT,
$expectedAttributes !== '' ? ' ' . $expectedAttributes : ''
),
$this->getView(
'<test:cell.render cell="{cell}" isHeader="{isHeader}">content</test:cell.render>',
['cell' => $cellValue ?? null, 'isHeader' => $isHeader]
)->render()
);
}

/**
* @dataProvider cellProvider
*/
public function testRenderAsHeader(string $expectedAttributes, ?array $cellMock): void
{
$this->testRender($expectedAttributes, $cellMock, true);
}

/**
* Based on 01_fixture.xlsx cell coordinates
* @return array
*/
public function cellProvider(): array
{
return [
'no cell' => ['', null],
'no attributes' => [
'',
['getClass' => '', 'getRowspan' => 0, 'getColspan' => 0]
],
'only class' => [
'class="cell"',
['getClass' => 'cell', 'getRowspan' => 0, 'getColspan' => 0]
],
'only rowspan' => [
'rowspan="1"',
['getClass' => '', 'getRowspan' => 1, 'getColspan' => 0]
],
'only colspan' => [
'colspan="1"',
['getClass' => '', 'getRowspan' => 0, 'getColspan' => 1]
],
'class + rowspan' => [
'class="cell" rowspan="2"',
['getClass' => 'cell', 'getRowspan' => 2, 'getColspan' => 0]
],
'class + colspan' => [
'class="cell" colspan="2"',
['getClass' => 'cell', 'getRowspan' => 0, 'getColspan' => 2]
],
'rowspan + colspan' => [
'rowspan="3" colspan="3"',
['getClass' => '', 'getRowspan' => 3, 'getColspan' => 3]
],
'class + rowspan + colspan' => [
'class="cell" rowspan="4" colspan="4"',
['getClass' => 'cell', 'getRowspan' => 4, 'getColspan' => 4]
],
];
}
}
Loading

0 comments on commit a7003f9

Please sign in to comment.