-2

I'm trying to run DataHandler commands from multiple contexts (Frontend, Backend, etc.). From what I've read and tried, this has to be done within a Synfony command for it to work properly. Only then, within the command, code snippets like these can be run:

Bootstrap::initializeBackendAuthentication();
$data = [...]
$dataHandler = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\DataHandling\DataHandler::class);
$dataHandler->start($data, []);
$dataHandler->process_datamap();

And it's the _cli_ back-end user the one running these DataHandler commands.

I've created my Synfony command according to the docs. It's registered and I can call it like this and it works as expected:

$ vendor/bin/typo3 myext:rundatahandler

My question is: How can I run this within a PHP class? I can't find it anywere in the docs or online. I only find it for Synfony Controller classes, which behave differently and have different inputs and attributes than those of TYPO3.

Thanks a lot in advance!

9
  • What do you mean by "class"? What kind of class? Where would this call be executed? The example shown here would work just about anywhere. Where did you try that approach, and how did it fail? Commented Apr 5, 2022 at 5:33
  • Also, more often than not, if you find yourself wanting to execute the command from different contexts, you should extract its functionality to a service which then you could call either from the console command or from wherever you need it. Commented Apr 5, 2022 at 5:37
  • @yivi As the OP said, calling commands from the Symfony Controller doesn't suit him. That's why I suggested using Process, why did you find this solution not worthy? Commented Apr 5, 2022 at 5:52
  • @HarviDent If you meant the downvote, it wasn't mine. But in any case, I don't think much of the solution because: it was suggested elsewhere many times, it's a bad approach in any case since extracting the functionality to another service would be more intelligent, and more importantly because without understanding why the other approach does not work, is just simply giving advice blindly (which, as I just mentioned, is not only bad advice, but repeated advice). Commented Apr 5, 2022 at 5:54
  • Hey, thanks a lot for the answers! @yivi ., by "class" I meant, e.g. an Extbase Controller class. By extracting its functionality you mean using this core library: docs.typo3.org/m/typo3/reference-coreapi/10.4/en-us/ApiOverview/…? Commented Apr 5, 2022 at 8:03

1 Answer 1

4

You can use The Process Component to run commands in your class.

Installation

composer require symfony/process

Use in your PHP Class

use Symfony\Component\Process\Exception\ProcessFailedException;
use Symfony\Component\Process\Process;

class YouClass{

    public function someAction(){
        $process = new Process(['vendor/bin/typo3', 'myext:rundatahandler']);
        // set the working directory to the root of the project
        $process->setWorkingDirectory(getcwd() . "/../");
        $process->run();
    }
}

Note: Also, if your class does not have access to the vendor folder, then you must require the vendor/autoload.php

require 'vendor/autoload.php';
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the answer! In the end I followed your approach and created a Symfony Command class that accepts both $cmd and/or $data arrays as JSON strings and, upon successfully running the DataHandler call, returns the $copyMappingArray_merged also as a JSON string, to be able to get the UIDs of copied records. Then I created a static utility method to which you pass the $cmd and/or $data arrays that serializes them and calls the Symfony command synchronously. It also fetches and deserializes the $copyMappingArray_merged. Works like a charm!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.