routestypo3typo3-9.xrealurl

TYPO3: Migrating fe_users realurl configuration to routeEnhancers


TYPO3: Migrating fe_users realurl configuration to routeEnhancers

At the moment I am updating TYPO3 from version 8 to 9. Up to now I have used ext:realurl to generate speaking urls. Now I am struggeling to get the "old" urls to work with the new routeEnhancers.

I have extendend the fe_users table in an own extension with the field my_department. Now I am trying to get the URLs with the following routeEnhancers to work.

routeEnhancers:
  FeusersPlugin:
    type: Extbase
    extension: MyFeusers
    plugin: Users
    #limitToPages: [3,7]
    defaultController: 'FrontendUser::list'
    defaults:
      company_title: ''
      department_title: ''
    routes:
      # Detail view:
      -
        routePath: '/{employee_title}'
        _controller: 'FrontendUser::show'
        _arguments: {'employee_title': 'frontendUser'}
      # List view
      -
        routePath: '{company_title}'
        _controller: 'FrontendUser::list'
        _arguments: {'company_title': 'company'}
      -
        routePath: 'department/{department_title}'
        _controller: 'FrontendUser::list'
        _arguments: {'department_title': 'department'}
    aspects:
      employee_title:
        type: PersistedPatternMapper
        tableName: fe_users
        routeFieldPattern: '^(?P<first_name>.+)-(?P<last_name>\d+)$'
        routeFieldResult: '{first_name}-{last_name}'
      company_title:
        type: StaticValueMapper
        map:
          name-of-company: 'Name of company'
          name-of-other-company: 'Name of other company'
      department_title:
        type: PersistedAliasMapper
        tableName: 'fe_users'
        routeFieldName: 'my_department'

Not working part:
/?tx_myfeusers_users[action]=list&tx_myfeusers_users[company]=Name of company&tx_myfeusers_users[controller]=FrontendUser&tx_myfeusers_users[department]=My department

=> result: /department/My%20department/?tx_myfeusers_users[company]==Name%20of%20company
=> desired: name-of-company/department/My%20department/
=> or even better name-of-company/department/My-department/
=> or even much better name-of-company/My-department/

Working parts:
/?tx_myfeusers_users[action]=list&tx_myfeusers_users[company]=Name of company&tx_myfeusers_users[controller]=FrontendUser
=> result: /name-of-company/
=> desired: /name-of-company/ => perfect!

/?tx_myfeusers_users[action]=show&tx_myfeusers_users[controller]=FrontendUser&tx_myfeusers_users[frontendUser]=143
=> result: /firstname-lastname/
=> desired: /firstname-lastname/ => perfect!

This is my realurl config, which was working for me:

'fixedPostVars' => array(

  'userDetailConfiguration' => array(

    array(
      'GETvar' => 'tx_myfeusers_users[company]',
      'valueMap' => array(
        'name-of-company' => 'Name of company',
        'name-of-other-company' => 'Name of other company'
      ),
      'noMatch' => 'bypass'
    ),
    array(
      'GETvar' => 'tx_myfeusers_users[action]',
      'valueMap' => array(
        'show' => '',
        'list' => '',
        'edit' => 'edit',
        'update' => 'update',
      ),
      'noMatch' => 'bypass'
    ),
    array(
      'GETvar' => 'tx_myfeusers_users[controller]',
      'valueMap' => array(
        'FrontendUser' => '',
      ),
      'noMatch' => 'bypass'
    ),
    array(
      'GETvar' => 'tx_myfeusers_users[frontendUser]',
      'lookUpTable' => array(
        'table' => 'fe_users',
        'id_field' => 'uid',
        'alias_field' => 'CONCAT(first_name, "-", last_name)',
        'useUniqueCache' => 1,
        'useUniqueCache_conf' => array(
          'strtolower' => 1,
          'spaceCharacter' => '-',
        ),
      ),
    ),
  ),

  '3' => 'userDetailConfiguration',

),
'postVarSets' => array(
  '_DEFAULT' => array(

    'department' => array(
      array(
        'GETvar' => 'tx_myfeusers_users[department]',
      ),
    ),

  ),
),

Solution

  • As I couldn't find another way to get it working, I wrote my own mapper for the department:

    Register the mapper in ext_localconf.php:

    $GLOBALS['TYPO3_CONF_VARS']
            ['SYS']
            ['routing']
            ['aspects']
            ['DepartmentStaticMapper'] = \Vendor\Extension\Routing\Aspect\DepartmentStaticMapper::class;
    

    Add the file for the mapper class in Classes/Routing/Aspect/DepartmentStaticMapper.php. The mapper does nothing, but returns the given value:

    <?php
    namespace Vendor\Extension\Routing\Aspect;
    
    use TYPO3\CMS\Core\Routing\Aspect\StaticMappableAspectInterface;
    
    class DepartmentStaticMapper implements StaticMappableAspectInterface
    {
        /**
         * @var array
         */
        protected $settings;
    
        /**
         * @param array $settings
         * @throws \InvalidArgumentException
         */
        public function __construct(array $settings)
        {
            $this->settings = $settings;
        }
    
        /**
         * {@inheritdoc}
         */
        public function generate(string $value): ?string
        {
            return $value;
        }
    
        /**
         * {@inheritdoc}
         */
        public function resolve(string $value): ?string
        {
            return $value;
        }
    }
    

    And finally use the mapper DepartmentStaticMapper in the routeEnhancers of your site configuration (last line of the following config):

    routeEnhancers:
      FeusersPlugin:
        type: Extbase
        extension: MyFeusers
        plugin: Users
        #limitToPages: [3,7]
        defaultController: 'FrontendUser::list'
        defaults:
          company_title: ''
          department_title: ''
        routes:
          # Detail view:
          -
            routePath: '{employee_title}'
            _controller: 'FrontendUser::show'
            _arguments: {'employee_title': 'frontendUser'}
          # List view
          -
            routePath: '{company_title}'
            _controller: 'FrontendUser::list'
            _arguments: {'company_title': 'company'}
          -
            routePath: 'department/{department_title}'
            _controller: 'FrontendUser::list'
            _arguments: {'department_title': 'department'}
        aspects:
          employee_title:
            type: PersistedPatternMapper
            tableName: fe_users
            routeFieldPattern: '^(?P<first_name>.+)-(?P<last_name>.+)$'
            routeFieldResult: '{first_name}-{last_name}'
          company_title:
            type: StaticValueMapper
            map:
              name-of-company: 'Name of company'
              name-of-other-company: 'Name of other company'
          department_title:
            type: DepartmentStaticMapper