itplusx / headless_gridelements

TYPO3 Headless Grid Elements (EXT:headless + EXT:gridelements)
4 stars 5 forks source link

GridChildrenProcessor#sortRecordsIntoMatrix never called #5

Closed jzscheile closed 3 years ago

jzscheile commented 3 years ago

I've setup a fresh Typo3 10.4LTS installation and inserted some content elements in a gridelement, but wasn't rendered and not part of the JSON output.

My environment: what version
PHP 7.4.13
Typo3 10.4.12
ext:headless 2.3.0
ext:headless_gridelements 1.0.4
ext:gridelements 10.0.0

The gridelement wasn't rendered to expected colPos[x] node, the content elements from the grid was rendered to colPos node and the output was the plain content from data property (data-record) from ContentObjectRenderer.

screenshot_9696

I've added following lines to Typoscript.

tt_content.gridelements_pi1. {
    fields < lib.contentElementWithHeader.fields
    fields {
        layout = TEXT
        layout {
            field = tx_gridelements_backend_layout
        }
        rows = JSON
        rows {
            dataProcessing {
                20 = ITplusX\HeadlessGridelements\DataProcessing\GridChildrenProcessor
            }
        }
    }
}

tt_content.gridelements_pi1.dataProcessing >

Now the gridelement was part of the JSON output but no nested content elements wasn't outputted.

screenshot_9697

I've modified Typoscript again:

rows {
            dataProcessing {
                20 = ITplusX\HeadlessGridelements\DataProcessing\GridChildrenProcessor
                20 {
                    default {
                        as = children
                        dataProcessing {
                            10 = ITplusX\HeadlessGridelements\DataProcessing\ContentProcessor
                        }
                    }
                }
            }
        }

Added an additional processor called ContentProcessor :

<?php

namespace ITplusX\HeadlessGridelements\DataProcessing;

use FriendsOfTYPO3\Headless\Json\JsonDecoder;
use TYPO3\CMS\Core\SingletonInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Configuration\ConfigurationManager;
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
use TYPO3\CMS\Frontend\ContentObject\DataProcessorInterface;

/**
 * Fetch records from the database, using the default .select syntax from TypoScript.
 */
class ContentProcessor implements DataProcessorInterface, SingletonInterface
{
    /** @var ConfigurationManager */
    private $configurationManager;

    /** @var JsonDecoder  */
    private $jsonDecoder;

    public function __construct()
    {
        $this->configurationManager = GeneralUtility::makeInstance(
            ConfigurationManager::class
        );

        $this->jsonDecoder = GeneralUtility::makeInstance(
            JsonDecoder::class
        );
    }

    /**
     * @param ContentObjectRenderer $cObj
     * @param array $contentObjectConfiguration
     * @param array $processorConfiguration
     * @param array $processedData
     * @return array|string|null
     * @throws \TYPO3\CMS\Extbase\Configuration\Exception\InvalidConfigurationTypeException
     */
    public function process(ContentObjectRenderer $cObj, array $contentObjectConfiguration, array $processorConfiguration, array $processedData)
    {
        if(!array_key_exists('data', $processedData) || !array_key_exists('CType', $processedData['data'])) {
            return null;
        }

        $conf = $this->getConfigurationManager()->getConfiguration(
            ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT
        )['tt_content.'];

        $key = $processedData['data']['CType'];

        $sdtClass = $this->getJsonDecoder()->decode(
            ['data' => $cObj->cObjGetSingle(
                $conf[$key],
                $conf[$key . '.'] ?? [],
                $key
            )]
        )['data'];

        $sdtClass->txGridelementsColumns = $processedData['data']['tx_gridelements_columns'];

        return $sdtClass;
    }

    private function getConfigurationManager() : ConfigurationManager
    {
        return $this->configurationManager;
    }

    private function getJsonDecoder() : JsonDecoder
    {
        return $this->jsonDecoder;
    }

}

And modified the GridChildrenProcessor:

diff --git a/web/typo3conf/ext/headless_gridelements/Classes/DataProcessing/GridChildrenProcessor.php b/web/typo3conf/ext/headless_gridelements/Classes/DataProcessing/GridChildrenProcessor.php
index 8f32d9b..feffbd1 100644
--- a/web/typo3conf/ext/headless_gridelements/Classes/DataProcessing/GridChildrenProcessor.php
+++ b/web/typo3conf/ext/headless_gridelements/Classes/DataProcessing/GridChildrenProcessor.php
@@ -19,15 +19,11 @@ class GridChildrenProcessor extends \GridElementsTeam\Gridelements\DataProcessin
                 foreach ($row['columns.'] as $column) {
                     $columns[] = [
                         'config' => $column,
-                        'elements' => array_map(
-                            'trim',
-                            (
-                                array_slice(
-                                    explode('###BREAK###', $this->processedData['data']['tx_gridelements_view_columns'][$column['colPos']]),
-                                    0,
-                                    -1
-                                )
-                            )
+                        'elements' => array_filter(
+                            $this->processedRecordVariables,
+                            function($record) use ($column) {
+                                return $record->txGridelementsColumns == $column['colPos'];
+                            }
                         )
                     ];
                 }

Then the nested elements was outputted to JSON as well:

screenshot_9698

Seems not the best solution, but is working for me.

I hope I have not overlooked anything and it is my fault.

Best, Jens

schloram commented 3 years ago

Hi @jzscheile, thanks for your issue.

Afaik this should have worked out of the box already after including the TypoScript. No special steps needed.

We just came back into office today so we will check what (and if) is the issue here this week and will get back to you soon.

regards, Ramón

jzscheile commented 3 years ago

Hi @schloram ,

Thanks for you feedback, maybe I've a mistake on my side.

I look forward to your response.

Cu,

Jens

schloram commented 3 years ago

Hi @jzscheile , I cannot reproduce this issue with the following prerequisites:

TYPO3 10.4.12 ext:headless 2.3.0 ext:headless_gridelements 1.0.4 ext:gridelements 10.0.0

Seems like everything works fine without the modifications you provided.

I hope I can assist you so we figure out where the problem is :)

regards, Ramón

jzscheile commented 3 years ago

Hello @schloram,

thanks for your fast response, will try to answer your questions best as possible.

Did you include the TypoScript that comes with the Extension? Without it it won't work. I'm pretty sure it does not make a difference but in which order do you include the TypoScript of headless, gridelements and headless_gridelements?

Yes, I've added the TS using Template > Includes

screenshot_9864

Did you apply any other modification to the gridelements or headless TypoScript?

No, I haven't modified the script or add any custom TS

Can you show me an excerpt of the tt_content.gridelements_pi1 TypoScript (from the TypoScript Object Browser prior to your above modifications)?

screenshot_9865

I hope I can assist you so we figure out where the problem is :)

Thanks for your assistent, attache the JSON output from the FE.

output.json.zip

Best, Jens

schloram commented 3 years ago

Hi @jzscheile , thanks for your detailed report.

I see whats the problem here. Our extension obviously only handles and overrides the output with the TypoScript Gridelements (deprecated) included. 🤦
Don't know why we didn't take the DataHandler variant into account. But since the old way is deprecated and the DataProcessor way is recommended we will probably change our extension to only use the DataHandler variant.

For a quick fix you could include the Gridelements (deprecated) instead of the Gridelements w/DataProcessing (recommended) TypoScript. Sounds odd, but right now this is the only way. 😬

In a future version we will change this.

@vjanoch fyi

regards, Ramón

jzscheile commented 3 years ago

Hi @schloram,

thanks for your feedback, so I'll go with your recommended way.

best, Jens

schloram commented 3 years ago

@jzscheile fyi we are planning to fix this in this or the next week. So the "workaround" doesn't have to be used very long :)

You will hear from us.

Thanks again for pointing it out.

jzscheile commented 3 years ago

@schloram you're very fast, sounds good thank you.

schloram commented 3 years ago

Good Morning @jzscheile , you can now update your extension to v2.0.0. With this version it's not necessary to include the TypoScript of EXT:gridelements anymore. Including the TypoScript of EXT:headless_gridelements is enough now.

regards, Ramón