Skip to content

Commit

Permalink
Add support for Symfony autowiring
Browse files Browse the repository at this point in the history
* new registry for repository classes
* load actions and views based on AbstractAction and AbstractView as
services
  • Loading branch information
digedag committed Oct 6, 2024
1 parent f61d584 commit c8f7049
Show file tree
Hide file tree
Showing 16 changed files with 286 additions and 16 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ Changelog
v1.19.0 (??.10.2024)
* Use Doctrine and QueryBuilder for insert, update and delete statements
* new delete()-method for PersistanceRepository
* Possible BC: moved tx_rnbase_controller to PSR-4 and declared some underscore-methods private
* Action and View-classes based on AbstractAction and AbstractView can use autowiring from TYPO3 10 and higher

v1.18.2 (11.07.2024)
* Fix PHP warnings
Expand Down
30 changes: 30 additions & 0 deletions Classes/DependencyInjection/DomainRepositoryPass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace Sys25\RnBase\DependencyInjection;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Sys25\RnBase\Domain\Repository\AbstractRepository;
use Sys25\RnBase\Domain\Repository\RepositoryRegistry;

class DomainRepositoryPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container): void
{
// always first check if the primary service is defined
if (!$container->has(RepositoryRegistry::class)) {
return;
}

$definition = $container->findDefinition(RepositoryRegistry::class);

// find all service IDs with the t3sports.stats.indexer tag
$taggedServices = $container->findTaggedServiceIds(AbstractRepository::SERVICE_TAG);

foreach ($taggedServices as $id => $tags) {
// add the indexer to the IndexerProvider service
$definition->addMethodCall('addRepository', [new Reference($id)]);
}
}
}
39 changes: 39 additions & 0 deletions Classes/DependencyInjection/FrontendServicePass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

namespace Sys25\RnBase\DependencyInjection;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Sys25\RnBase\Frontend\Controller\AbstractAction;
use Sys25\RnBase\Frontend\Service\FrontendServiceProvider;
use Sys25\RnBase\Frontend\View\AbstractView;

class FrontendServicePass implements CompilerPassInterface
{
public function process(ContainerBuilder $container): void
{
// always first check if the primary service is defined
if (!$container->has(FrontendServiceProvider::class)) {
return;
}

$definition = $container->findDefinition(FrontendServiceProvider::class);

// find all tagged service IDs
$taggedServices = $container->findTaggedServiceIds(AbstractAction::SERVICE_TAG);

foreach ($taggedServices as $id => $tags) {
// add the service to the ServiceProvider service
$definition->addMethodCall('addFrontendAction', [new Reference($id)]);
}

// find all tagged service IDs
$taggedServices = $container->findTaggedServiceIds(AbstractView::SERVICE_TAG);

foreach ($taggedServices as $id => $tags) {
// add the service to the ServiceProvider service
$definition->addMethodCall('addFrontendView', [new Reference($id)]);
}
}
}
2 changes: 2 additions & 0 deletions Classes/Domain/Repository/AbstractRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
*/
abstract class AbstractRepository implements SearchInterface, SingletonInterface
{
public const SERVICE_TAG = 'sys25.domain.repository';

/**
* Liefert den Namen der Suchklasse.
*
Expand Down
50 changes: 50 additions & 0 deletions Classes/Domain/Repository/RepositoryRegistry.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

namespace Sys25\RnBase\Domain\Repository;

use tx_rnbase;

/***************************************************************
* Copyright notice
*
* (c) 2015-2023 René Nitzsche <[email protected]>
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/

/**
* An verschiedenen Stellen werden Repos in Klassen benötigt, bei denen DI noch
* nicht möglich ist. Damit die Repos deswegen nicht public deklariert werden müssen,
* werden sie in dieser Registry gesammmelt und können static angerufen werden.
*/
class RepositoryRegistry
{
private static $repos = [];

public function addRepository(AbstractRepository $repository): void
{
self::$repos[get_class($repository->getEmptyModel())] = $repository;
}

public static function getRepositoryForClass(string $modelClass): ?AbstractRepository
{
$instance = tx_rnbase::makeInstance(self::class);

return $instance::$repos[$modelClass] ?? null;
}
}
2 changes: 2 additions & 0 deletions Classes/Frontend/Controller/AbstractAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
*/
abstract class AbstractAction
{
public const SERVICE_TAG = 'sys25.frontend.action';

/**
* This method is called by base controller.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,29 @@
<?php

namespace Sys25\RnBase\Frontend\Controller;

use Sys25\RnBase\Configuration\ConfigurationInterface;
use Sys25\RnBase\Configuration\Processor;
use Sys25\RnBase\Exception\ExceptionHandler;
use Sys25\RnBase\Exception\ExceptionHandlerInterface;
use Sys25\RnBase\Exception\PageNotFound404;
use Sys25\RnBase\Exception\SkipActionException;
use Sys25\RnBase\Frontend\Request\Parameters;
use Sys25\RnBase\Frontend\Request\ParametersInterface;
use Sys25\RnBase\Frontend\Service\FrontendServiceProvider;
use Sys25\RnBase\Utility\Arrays;
use Sys25\RnBase\Utility\Logger;
use Sys25\RnBase\Utility\Misc;
use Sys25\RnBase\Utility\Strings;
use Sys25\RnBase\Utility\TYPO3;
use Throwable;
use tx_rnbase;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;

/***************************************************************
* Copyright notice
*
* (c) 2007-2013 René Nitzsche
* (c) 2007-2024 René Nitzsche
* All rights reserved
*
* Based on code by Elmar Hinz Contact: [email protected]
Expand Down Expand Up @@ -112,7 +118,7 @@
* FIXME: move to PSR-4
*/

class tx_rnbase_controller
class MainController
{
public $configurationsClassName = Processor::class; // You may overwrite this in your subclass with an own configurations class.

Expand All @@ -130,6 +136,13 @@ class tx_rnbase_controller

private $errors = [];

private $frontendServiceProvider;

public function __construct(?FrontendServiceProvider $frontendServiceProvider = null)
{
$this->frontendServiceProvider = $frontendServiceProvider ?: null;
}

public function setContentObjectRenderer(ContentObjectRenderer $cObj): void
{
$this->cObj = $cObj;
Expand Down Expand Up @@ -212,7 +225,7 @@ public function main($out, $configurationArray)

// Making the configurations object
Misc::pushTT('init configuration', '');
/** @var $configurations Processor */
/** @var Processor $configurations */
$configurations = $this->_makeConfigurationsObject($configurationArray);
Misc::pullTT();

Expand Down Expand Up @@ -260,22 +273,42 @@ public function main($out, $configurationArray)
return $out;
}

/**
* @param mixed $actionName
* @return AbstractAction
*/
private function lookupActionService($actionName)
{
// Zuerst im DI-Container suchen
$action = null;
if ($this->frontendServiceProvider) {
$action = $this->frontendServiceProvider->getActionForClass($actionName);
}

if (!$action) {
// Fallback auf alte Services. In T3 8 und 9 müssen sich die Extension ggf. selber kümmern.
$action = tx_rnbase::makeInstance($actionName);
}

return $action;
}

/**
* Call a single action.
*
* @param string $actionName class name
* @param tx_rnbase_IParams $parameters
* @param Tx_Rnbase_Configuration_ProcessorInterface $configurations
* @param string $actionName class name
* @param ParametersInterface $parameters
* @param ConfigurationInterface $configurations
*
* @return string
*/
public function doAction($actionName, &$parameters, &$configurations)
public function doAction(string $actionName, ParametersInterface $parameters, ConfigurationInterface $configurations)
{
$ret = '';

try {
// Creating the responsible Action
$action = tx_rnbase::makeInstance($actionName);
$action = $this->lookupActionService($actionName);
if (is_object($action)) {
$ret = $action->execute($parameters, $configurations);
}
Expand Down Expand Up @@ -433,7 +466,7 @@ protected function _findAction($parameters, $configurations)
*
* @return string the action value
*/
public function _getParameterAction($parameters)
private function _getParameterAction($parameters)
{
$action = $parameters->offsetExists('action') ? $parameters->offsetGet('action') : '';
if (!is_array($action)) {
Expand All @@ -450,9 +483,9 @@ public function _getParameterAction($parameters)
*
* @param array $configurationArray the local configuration array
*
* @return Tx_Rnbase_Configuration_ProcessorInterface the configurations
* @return ConfigurationInterface the configurations
*/
public function _makeConfigurationsObject($configurationArray)
private function _makeConfigurationsObject($configurationArray)
{
// TODO, die Configklasse sollte über TS variabel gehalten werden
// Make configurations object
Expand Down
2 changes: 1 addition & 1 deletion Classes/Frontend/Filter/BaseFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
/***************************************************************
* Copyright notice
*
* (c) 2009-2023 Rene Nitzsche
* (c) 2009-2024 Rene Nitzsche
* Contact: [email protected]
* All rights reserved
*
Expand Down
2 changes: 1 addition & 1 deletion Classes/Frontend/Filter/FilterInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
/***************************************************************
* Copyright notice
*
* (c) 2009 Rene Nitzsche
* (c) 2009-2024 Rene Nitzsche
* Contact: [email protected]
* All rights reserved
*
Expand Down
64 changes: 64 additions & 0 deletions Classes/Frontend/Service/FrontendServiceProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

namespace Sys25\RnBase\Frontend\Service;

use ReflectionClass;
use Sys25\RnBase\Frontend\Controller\AbstractAction;
use Sys25\RnBase\Frontend\View\AbstractView;

/***************************************************************
* Copyright notice
*
* (c) 2007-2024 Rene Nitzsche <[email protected]>
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/

class FrontendServiceProvider
{
private $actions = [];
private $views = [];
private $filters = [];

public function addFrontendAction(AbstractAction $action): void
{
$this->actions[get_class($action)] = $action;
}

public function getActionForClass(string $actionClass): ?AbstractAction
{
if (!array_key_exists($actionClass, $this->actions) && class_exists($actionClass)) {
// Hier werden häufig aliases verwendet.
$reflection = new ReflectionClass($actionClass);
$action = $reflection->getName();
$this->actions[$actionClass] = $this->actions[$action] ?? null;
}

return $this->actions[$actionClass] ?? null;
}

public function addFrontendView(AbstractView $view): void
{
$this->views[get_class($view)] = $view;
}

public function getViewForClass(string $viewClass): ?AbstractView
{
return $this->views[$viewClass] ?? null;
}
}
4 changes: 3 additions & 1 deletion Classes/Frontend/View/AbstractView.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
/***************************************************************
* Copyright notice
*
* (c) 2007-2019 René Nitzsche <[email protected]>
* (c) 2007-2024 René Nitzsche <[email protected]>
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
Expand All @@ -29,6 +29,8 @@

abstract class AbstractView
{
public const SERVICE_TAG = 'sys25.frontend.view';

protected $pathToTemplates;

protected $templateFile;
Expand Down
Loading

0 comments on commit c8f7049

Please sign in to comment.