Bug #90624

Backend SiteResolver middleware is not able to resolve site when editing a record

Added by Markus Mächler 9 months ago. Updated 9 months ago.

Status:
Closed
Priority:
Should have
Assignee:
-
Category:
-
Target version:
-
Start date:
2020-03-03
Due date:
% Done:

0%

Estimated time:
TYPO3 Version:
9
PHP Version:
Tags:
Complexity:
medium
Is Regression:
Sprint Focus:

Description

When editing a record, the backend SiteResolver is not able to determine the current site because the id parameter is not set. This is for instance needed if you have a user function display condition where you want to show a field depending on a site configuration.

#1

Updated by Markus Mächler 9 months ago

We worked around this by using an XCLASS to extend the current SiteResolver implementation with the following. It would be nice if this fix or probably something more robust would find its way into the core!

SiteResolver

<?php
namespace Your\Ext\Xclass\TYPO3\CMS\Backend\Middleware;

/*
 * This file is part of the TYPO3 CMS project.
 *
 * It is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License, either version 2
 * of the License, or any later version.
 *
 * For the full copyright and license information, please read the
 * LICENSE.txt file that was distributed with this source code.
 *
 * The TYPO3 project - inspiring people to share!
 */

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Routing\SiteMatcher;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\MathUtility;

/**
 * SiteResolver, see https://forge.typo3.org/issues/90624
 */
class SiteResolver extends \TYPO3\CMS\Backend\Middleware\SiteResolver {
    /**
     * @inheritDoc
     */
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        $pageId = ($request->getQueryParams()['id'] ?? $request->getParsedBody()['id'] ?? 0);

        // BEGIN added code
        if ($pageId === 0) {
            $queryString = parse_url($request->getQueryParams()['returnUrl'], PHP_URL_QUERY);

            if ($queryString !== NULL) {
                parse_str($queryString, $parsedQueryString);
                $pageId = (int) $parsedQueryString['id'];
            } else {
                $queryString = parse_url(GeneralUtility::getIndpEnv('HTTP_REFERER'), PHP_URL_QUERY);

                parse_str($queryString, $parsedQueryString);
                parse_str($parsedQueryString['returnUrl'], $parsedString);

                $pageId = (int) $parsedString['id'];
            }
        }
        // END added code

        // Check if we have a numeric _GET/_POST parameter for "id", then a site information can be resolved based.
        if (MathUtility::canBeInterpretedAsInteger($pageId)) {
            $pageId = (int)$pageId;
            $rootLine = null;
            if ($pageId > 0) {
                $rootLine = BackendUtility::BEgetRootLine($pageId);
            }
            $site = GeneralUtility::makeInstance(SiteMatcher::class)->matchByPageId($pageId, $rootLine);
            $request = $request->withAttribute('site', $site);
            $GLOBALS['TYPO3_REQUEST'] = $request;
        }
        return $handler->handle($request);
    }
}

ext_localconf.php

$GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects'][\TYPO3\CMS\Backend\Middleware\SiteResolver::class] = [
    'className' => \Your\Ext\Xclass\TYPO3\CMS\Backend\Middleware\SiteResolver::class
];

#2

Updated by Georg Ringer 9 months ago

  • Status changed from New to Needs Feedback

thanks for creating the issue!

While I agree that the the Site can't be found in the middleware, what about using the Formengine to decide which field should be shown or not? \TYPO3\CMS\Backend\Form\FormDataProvider\SiteResolving will resolve the site and you will have the information available when building custom formengine elements?

#3

Updated by Markus Mächler 9 months ago

Thanks for your response! I was not aware of that possibility, using the Formengine is probably the better way to solve that particular issue. However I am not yet sure whether this is a valid issue nevertheless. I think it would be best if the SiteResolver could resolve the site in order for it to be available in any part of the code (including user functions). But on the other hand the site can always be easily resolved any time we have a data record and it's pid at hand.

#4

Updated by Benni Mack 9 months ago

  • Status changed from Needs Feedback to Closed

Yeah, there are parts where a site cannot be resolved (e.g. editing multiple records from the search in different sites), but for the time being this can't be addressed as a "Bug". There are a couple of more steps moving towards resolving the Site properly in the request (e.g. related to the ConditionMatcher), so this will be a bigger topic - probably for v11 then.

Also available in: Atom PDF