typo3typoscriptfluidtypo3-11.x

How to nest SplitProcessors in TYPO3?


I need to split a string by line and then by |.

Initially, I used a CommaSeparatedValueProcessor with fieldDelimiter = | which works with simple strings, but now the strings contain " and ' for measurements which stops it from working.

I tried setting fieldEnclosure to something other than " but that doesnt seem to help.

So I thought I could fall back to a SplitProcessor. Is there a way nest it to get the 2 splits?

dataProcessing {
    10 = TYPO3\CMS\Frontend\DataProcessing\SplitProcessor
    10 {
        fieldName = data
        delimiter.char = 10
        as = myarray
    }
}

Solution

  • I don't think it's possible to nest SplitProcessors.
    So the only way is to implement a custom dataProcessor. But that's not a big thing.

    EXT:your_extension/Classes/DataProcessing/CustomSplitProcessor

    <?php
    
    namespace VENDOR\YourExtension\DataProcessing;
    
    use TYPO3\CMS\Core\Utility\GeneralUtility;
    use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
    use TYPO3\CMS\Frontend\ContentObject\DataProcessorInterface;
    
    class CustomSplitProcessor implements DataProcessorInterface
    {
    
        public function process(ContentObjectRenderer $cObj, array $contentObjectConfiguration, array $processorConfiguration, array $processedData)
        {
            if (isset($processorConfiguration['if.']) && !$cObj->checkIf($processorConfiguration['if.'])) {
                return $processedData;
            }
    
            // The field name to process
            $fieldName = $cObj->stdWrapValue('fieldName', $processorConfiguration);
            if (empty($fieldName)) {
                return $processedData;
            }
    
            $originalValue = (string)($cObj->data[$fieldName] ?? '');
    
            // Set the target variable
            $targetVariableName = $cObj->stdWrapValue('as', $processorConfiguration, $fieldName);
    
            // Remove empty entries
            $removeEmptyEntries = (bool)$cObj->stdWrapValue('removeEmptyEntries', $processorConfiguration, false);
    
            // Set the firstDelimiter which is "LF" by default
            // Set the secondDelimiter which is "|" by default
            $firstDelimiter = (string)$cObj->stdWrapValue('firstDelimiter', $processorConfiguration, LF);
            $secondDelimiter = (string)$cObj->stdWrapValue('secondDelimiter', $processorConfiguration, '|');
    
            $splitArray = GeneralUtility::trimExplode($firstDelimiter, $originalValue, $removeEmptyEntries);
    
            foreach ($splitArray as $splitItem)
            {
                $processedData[$targetVariableName][$splitItem] = GeneralUtility::trimExplode($secondDelimiter, $splitItem, $removeEmptyEntries);
            }
    
            return $processedData;
        }
    }
    

    In this example the first delimiter is LF (new-Line) and the second delimiter is | . So you don't need to set the delimiter in your TypoScript for your case.

    You can then use the DataProcessor like:

    dataProcessing {
      10 = VENDOR\YourExtension\DataProcessing\CustomSplitProcessor
      10 {
        fieldName = data
        as = myarray
      }
    }