typo3typo3-extensions

TYPO3 Get started with an ActionController


I want to achieve something like that: A diagram where the site communicates via an ActionController, that uses Repo-Pattern to communicate with the database

But I am struggling with the first milestone already. I want to request the ActionController that should return the status code 200.

That is my code so far:

<?php

use Psr\Http\Message\ResponseInterface;
use T3docs\BlogExample\Domain\Model\Blog;
use T3docs\BlogExample\Exception\NoBlogAdminAccessException;
use TYPO3\CMS\Extbase\Annotation\Validate;

class PbiController extends AbstractController
{
    public function GetAction(): ResponseInterface
    {
        return $this->responseFactory
            ->createResponse()
            ->withStatus(200, "ok");
    }
}

I started from this: https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ExtensionArchitecture/Extbase/Reference/Controller/ActionController.html

The first problem is that I have no idea what the URL looks like. And I have no idea if I have to register it myself or if it is done by naming convention.

Edit

I forgot to mention I used the sitepackage-builder to have the default template.

Thank you for being so helpful.

Best regards

peni4142


Solution

  • First you must let your controller extend:

    \TYPO3\CMS\Extbase\Mvc\Controller\ActionController
    

    Seems like you copied the code directly. The blogexample controller extends from an own abstract controller.

    So your controller should look like:

    <?php
    namespace MyVendor\MyExt\Controller;
    
    use Psr\Http\Message\ResponseInterface;
    use TYPO3\CMS\Extbase\Mvc\Controller\ActionController
    
    class PbiController extends ActionController
    {
        public function getAction(): ResponseInterface
        {
            return $this->responseFactory
                ->createResponse()
                ->withStatus(200, "ok");
        }
    }
    

    Then you need either a plugin or an eid so you can call the action in your controller. If you register a plugin, then you must add the plugin on a page in your project. I suggest it would be better to register an eid. For that implement following in your ext_localconf.php:

    $GLOBALS['TYPO3_CONF_VARS']['FE']['eID_include']['myCoolPbiEid'] = \MyVendor\MyExt\Controller\PbiController::class . '::getAction';
    

    Now you should be able to call your controller with following URL:

    https://www.domain.tld/index.php?eID=myCoolPbiEid
    

    Edit:

    Be aware of: When implementing the plugin and adressing it via a page, then TYPO3 is rendering the whole page and not only the code of your controller action. So now your action doesn't make really sence any more. If you want your plugin to deliver data, let's say in JSON format i.e., the better way is to use the eID approach.

    If you want to add a plugin you can follow the description of the blogexample:

    https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ExtensionArchitecture/Extbase/Reference/FrontendPlugins.html

    In your case you must:

    1.Configure your plugin in your ext_localconf.php

    <?php
    
    declare(strict_types=1);
    
    use MyVendor\MyExt\Controller\PbiController
    use TYPO3\CMS\Extbase\Utility\ExtensionUtility;
    
    defined('TYPO3') or die();
    
    ExtensionUtility::configurePlugin(
        // extension name, matching the PHP namespaces (but without the vendor)
        'MyExt',
        // arbitrary, but unique plugin name (not visible in the backend)
        'PbiPlugin',
        // all actions
        [PbiController::class => 'get'],
        // non-cacheable actions (Only needed if you want uncached output)
        [PbiController::class => 'get']
    );
    

    2.Register your plugin in /Configuration/TCA/Overrides/tt_content.php

    <?php
    
    defined('TYPO3') or die();
    
    (static function (): void {
        \TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
            // extension name, matching the PHP namespaces (but without the vendor)
            'MyExt',
            // arbitrary, but unique plugin name (not visible in the backend)
            'PbiPlugin',
            // plugin title, as visible in the drop-down in the backend, use "LLL:" for localization
            'My cool plugin'
        );
    })();
    

    After clearing the cache you should now be able to implement the plugin as contentelement on one of your pages. For that add a new contentelement plugins->generalplugin. In the plugin tab of the contentelement you should see your plugin in the dropdown.

    To address the plugin in the frontend you can call:

    https://www.domain.tld/my-page/index.php?tx_myext_pbiplugin[controller]=Pbi&tx_myext_pbiplugin[action]=get
    

    Edit:

    If you use the eID approach the ResponseFactory isn't initialized in the controller. A good way is to return your data in JSON format. You could achive this as follows:

    <?php
    namespace MyVendor\MyExt\Controller;
    
    use Psr\Http\Message\ResponseInterface;
    use TYPO3\CMS\Extbase\Mvc\Controller\ActionController
    use TYPO3\CMS\Core\Http\JsonResponse;
    use TYPO3\CMS\Core\Utility\GeneralUtility;
    
    class PbiController extends ActionController
    {
        public function getAction(): ResponseInterface
        {
            $data = [
                'MyCoolArrayKey' => 'MyCoolValue'
            ];
    
            return GeneralUtility::makeInstance(JsonResponse::class, array_values($data));
        }
    }