Alexander Grein
Alexander Grein

Reputation: 133

How to extend femanager controller under php 7

Since using PHP 7.0 and higher, the strict mode of php generates warnings like this:

PHP Warning: Declaration of In2code\Femanagerextended\Controller\EditController::updateAction(In2code\Femanagerextended\Domain\Model\User $user) should be compatible with In2code\Femanager\Controller\EditController::updateAction(In2code\Femanager\Domain\Model\User $user) in ($PATH)\typo3conf\ext\femanagerextended\Classes\Controller\EditController.php line 17

when trying to extend an existing controller of the TYPO3 Extension femanager using the described way in the best practice section of the manual:

<?php
namespace In2code\Femanagerextended\Controller;
use In2code\Femanager\Controller\EditController as EditControllerFemanager;
use In2code\Femanagerextended\Domain\Model\User;
/**
 * Class EditController
 *
 * @package In2code\Femanagerextended\Controller
 */
class EditController extends EditControllerFemanager
{
    /**
     * action update
     *
     * @param User $user
     * @validate $user In2code\Femanager\Domain\Validator\ServersideValidator
     * @validate $user In2code\Femanager\Domain\Validator\PasswordValidator
     * @return void
     */
     public function updateAction(User $user)
     {
         parent::updateAction($user);
     }
}

Upvotes: 2

Views: 3951

Answers (2)

user2310852
user2310852

Reputation: 1674

Full answer/tutorial ...

You can extend TYPO3 femanager with the following tutorial. The old extension femanagerextended is not necessary. This works fine with TYPO3 and PHP 5.x. Here's the workaround for PHP 7.x:

Add a new XCLASS-file f.e. typo3conf/ext/yourext/Classes/Xclass/Extbase/Mvc/Controller/Argument.php:

namespace Yournamespace\Yourext\Xclass\Extbase\Mvc\Controller;
class Argument extends \TYPO3\CMS\Extbase\Mvc\Controller\Argument

{
    /**
     * Set data type for femanager workaround.
     * Workaround to avoid php7 warnings of wrong type hint.
     *
     * @param $dataType
     * @return $this
     */
    public function setDataType($dataType) {
        $this->dataType = $dataType;
        return $this;
    }
}

Change the file typo3conf/ext/yourext/Classes/Controller/EditController.php:

namespace Yournamespace\Yourext\Controller;
use \Yournamespace\Yourext\Domain\Model\User;
class EditController extends \In2code\Femanager\Controller\EditController {

    /**
     * @return void
     */
    public function initializeUpdateAction()
    {
        if ($this->arguments->hasArgument('user')) {
            // Workaround to avoid php7 warnings of wrong type hint.
            /** @var \Yournamespace\Yourext\Xclass\Extbase\Mvc\Controller\Argument $user */
            $user = $this->arguments['user'];
            $user->setDataType(\Yournamespace\yourext\Domain\Model\User::class);
        }
    }

    /**
     * action update
     *
     * @param User $user
     * @validate $user In2code\Femanager\Domain\Validator\ServersideValidator
     * @validate $user In2code\Femanager\Domain\Validator\PasswordValidator
     * @validate $user In2code\Femanager\Domain\Validator\CaptchaValidator
     * @return void
     */
    public function updateAction(\In2code\Femanager\Domain\Model\User $user) {
        parent::updateAction($user);
    }
}

Change the file typo3conf/ext/yourext/Classes/Controller/NewController.php:

namespace Yournamespace\Yourext\Controller;
use Yournamespace\Yourext\Domain\Model\User;
class NewController extends \In2code\Femanager\Controller\NewController {

    /**
     * Initialize create action for setting the right custom data type for the user.
     */
    public function initializeCreateAction() {
        if ($this->arguments->hasArgument('user')) {
            // Workaround to avoid php7 warnings of wrong type hint.
            /** @var \Yournamespace\Yourext\Xclass\Extbase\Mvc\Controller\Argument $user */
            $user = $this->arguments['user'];
            $user->setDataType(\Yournamespace\Yourext\Domain\Model\User::class);
        }
    }


    /**
     * action create
     *
     * @param User $user
     * @validate $user In2code\Femanager\Domain\Validator\ServersideValidator
     * @validate $user In2code\Femanager\Domain\Validator\PasswordValidator
     * @return void
     */
    public function createAction(User $user)
    {
        parent::createAction($user);
    }
}

Register your XCLASS into ext_localconf.php: $GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects']['TYPO3\\CMS\\Extbase\\Mvc\\Controller\\Argument'] = array('className' => 'Yournamespace\\Yourext\\Xclass\\Extbase\\Mvc\\Controller\\Argument');

Clear Cache & clear autoloader via install tool!

This issue also helps.

Upvotes: 5

Alexander Grein
Alexander Grein

Reputation: 133

A possible solution, worked out by Wolfgang Klinger, is to XClass the \TYPO3\CMS\Extbase\Mvc\Controller\Argument class.

This class has a protected property "dataType", which usually has no setter.

Using the XClass mechanism of TYPO3 it is possible to add a setDataType method to enable the manual overriding of this property.

Armed with this, it's now possible to overwrite the usually automatic detected data type inside the (magic) initialize actions of the extending edit/invitation/new-controller.

The important thing is, not to change the type hints and annotations of the "normal" Actions (newAction, createAction ...), but add something like this to the corresponding initialize actions:

public function initializeNewAction()
{
    if ($this->arguments->hasArgument('user')) {
        // Workaround to avoid php7 warnings of wrong type hint.
        /** @var \Mediagear\Jdcompetition\Xclass\Extbase\Mvc\Controller\Argument $user */
        $user = $this->arguments['user'];
        $user->setDataType(\Vendor\Extension\Domain\Model\User::class);
    }
}

Upvotes: 8

Related Questions