Code Monkey home page Code Monkey logo

Comments (6)

NamelessCoder avatar NamelessCoder commented on June 29, 2024

@svewap since I don't have an implementation with dataprocessing ready at hand: would you mind checking if instead of redefining $record, doing an array_merge to overwrite the individual properties on $record with the localized versions would solve the issue? This would only work if your dataProcessors assign new virtual columns and doesn't overwrite existing ones - but TBH I'm not sure if overwriting existing columns is considered bad practice in which case we could defend a decision to only preserve new virtual columns and overwrite any existing ones with localized data.

from flux.

svewap avatar svewap commented on June 29, 2024

@NamelessCoder I can confirm that the merge workaround

if ($record['_LOCALIZED_UID'] ?? false) {
  $record = array_merge($record,
    $this->recordService->getSingle(
      (string)$this->getFluxTableName(),
      '*',
      $record['_LOCALIZED_UID']
    ) ?? $record
  );
}

works for data processors that add data with new data array keys.

from flux.

NamelessCoder avatar NamelessCoder commented on June 29, 2024

@svewap I've implemented the array_merge solution but it may just be a temporary fix to at least support new, virtual columns added by dataProcessors. I'm still not entirely clear on what would be a possible way to support this also for dataProcessors which override columns which also exist in DB. If you have any suggestions (maybe the TS config for the dataProcessors is available sowhere within context?) then I'd be happy to consider them.

from flux.

svewap avatar svewap commented on June 29, 2024

Once again, I took the problem as an opportunity to look into the matter. I think TYPO3 has a structural problem here. By automatically defining it as a plugin, TYPO3 wraps the Flux Controller using FLUIDTEMPLATE. This means that the defined dataProcessors can no longer be passed to the USER object set to 10. . However, this is very important because the dataProcessors in a template are often set to the lib.contentElement so that they are globally available on every element.

I would have one question in this context: why is fetching the localized dataset necessary? I have removed this so that flux only uses the $contentObject->data. I could not see any disadvantages. The data/record array modified by dataProcessors is still available then.

For new variables by dataProcessors
To be able to use a DataProcessor correctly, I built the following bridge. This is often necessary because default dataProcessors are not able to write back to data/record array but create a new variable passing them to the view.

  1. I wrote a ProcessedDataToRegisterProcessor which is appended with a very high number at lib.contentElement.dataProcessing.
class ProcessedDataToRegisterProcessor implements DataProcessorInterface
{
    /**
     *
     *
     * @param ContentObjectRenderer $cObj The data of the content element or page
     * @param array $contentObjectConfiguration The configuration of Content Object
     * @param array $processorConfiguration The configuration of this processor
     * @param array $processedData Key/value store of processed data (e.g. to be passed to a Fluid View)
     * @return array the processed data as key/value store
     */
    public function process(ContentObjectRenderer $cObj, array $contentObjectConfiguration, array $processorConfiguration, array $processedData)
    {
        if (isset($processorConfiguration['if.']) && !$cObj->checkIf($processorConfiguration['if.'])) {
            return $processedData;
        }

        $GLOBALS['TSFE']->register['processedData'] = $processedData;

        return $processedData;
    }
}
  1. A hook fetches this again from the register and adds it to the view

$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['flux']['hooks'][HookHandler::CONTROLLER_VIEW_INITIALIZED][] = \WapplerSystems\WsT3bootstrap\Hooks\FluxHooks::class;

class FluxHooks implements HookSubscriberInterface
{
    public function trigger($hook, $data): array
    {
        if ($GLOBALS['TSFE']->register['processedData'] ?? false) {
            /** @var TemplateView $view */
            $view = $data['view'];
            if (is_array($GLOBALS['TSFE']->register['processedData'])) {
                foreach ($GLOBALS['TSFE']->register['processedData'] as $key => $value) {
                    $view->assign($key, $value);
                }
            }
            $data['view'] = $view;
        }
        return $data;
    }
}

from flux.

NamelessCoder avatar NamelessCoder commented on June 29, 2024

TYPO3 wraps the Flux Controller using FLUIDTEMPLATE.

I believe this is FSC's doing. I'm not a fan of that approach either.

This means that the defined dataProcessors can no longer be passed to the USER object set to 10

They technically can, but they aren't ;)

I would have one question in this context: why is fetching the localized dataset necessary?

Without that, the context within templates and the Provider would all receive a record whcih when used to resolve e.g. FAL references would always return the results of the original, not the translated version. Rather than having to fetch the translated version over and over again in every single context affected by this problem, substituting the record data in controller and using that result throughout seems like a better approach.

The deeper problem here though is with the ContentObject data: it both is and isn't a record. All the initial values within it come from the content record, but then it is decorated and manipulated - essentially, it's a big bucket where content objects can throw anything they like or mangle the properties of the record. There is no isolated storage for the record, no dedicated place for new properties. It's a big mess based on ancient legacy approaches that were never cleaned up and formalised.

from flux.

NamelessCoder avatar NamelessCoder commented on June 29, 2024

The new patch linked right above here will assign two new variables, data and contentObject which contain the untouched content object data and the instance of ContentObjectRenderer to allow you to call the parameterless getter methods on that object.

Although you'd need to use the data variable in your templates instead of record, the new variable would be safe in those use cases where existing record columns are overwritten by output of a DataProcessor - and should mean that you no longer would need a register-based workaround.

from flux.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.