Commit fb59fbc9 authored by Benni Mack's avatar Benni Mack Committed by Oliver Bartsch
Browse files

[TASK] Use DependencyInjection in FileController

This change registers FileController as backend
controller in Services.yaml and allows to inject
all needed dependency via constructor DI.

Resolves: #94696
Releases: master
Change-Id: Idc14d1ef86bcbd5c4da77f3101b5a97f2a6aa6c3
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/70188

Tested-by: core-ci's avatarcore-ci <typo3@b13.com>
Tested-by: Jochen's avatarJochen <rothjochen@gmail.com>
Tested-by: Oliver Bartsch's avatarOliver Bartsch <bo@cedev.de>
Reviewed-by: Jochen's avatarJochen <rothjochen@gmail.com>
Reviewed-by: Oliver Bartsch's avatarOliver Bartsch <bo@cedev.de>
parent 65cc0bfd
......@@ -23,7 +23,6 @@ use TYPO3\CMS\Backend\Clipboard\Clipboard;
use TYPO3\CMS\Backend\Routing\Exception\RouteNotFoundException;
use TYPO3\CMS\Backend\Routing\UriBuilder;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
use TYPO3\CMS\Core\Http\HtmlResponse;
use TYPO3\CMS\Core\Http\JsonResponse;
use TYPO3\CMS\Core\Http\RedirectResponse;
......@@ -66,7 +65,7 @@ class FileController
* Defines behaviour when uploading files with names that already exist; possible values are
* the values of the \TYPO3\CMS\Core\Resource\DuplicationBehavior enumeration
*
* @var \TYPO3\CMS\Core\Resource\DuplicationBehavior
* @var DuplicationBehavior
*/
protected $overwriteExistingFiles;
......@@ -77,14 +76,6 @@ class FileController
*/
protected $redirect;
/**
* Internal, dynamic:
* File processor object
*
* @var ExtendedFileUtility
*/
protected $fileProcessor;
/**
* The result array from the file processor
*
......@@ -92,13 +83,26 @@ class FileController
*/
protected $fileData;
protected ExtendedFileUtility $fileProcessor;
protected ResourceFactory $fileFactory;
protected IconFactory $iconFactory;
protected UriBuilder $uriBuilder;
public function __construct(ResourceFactory $resourceFactory, ExtendedFileUtility $fileProcessor, IconFactory $iconFactory, UriBuilder $uriBuilder)
{
$this->fileFactory = $resourceFactory;
$this->fileProcessor = $fileProcessor;
$this->iconFactory = $iconFactory;
$this->uriBuilder = $uriBuilder;
}
/**
* Injects the request object for the current request or subrequest
* As this controller goes only through the main() method, it just redirects to the given URL afterwards.
*
* @param ServerRequestInterface $request the current request
* @return ResponseInterface the response with the content
* @throws \TYPO3\CMS\Backend\Routing\Exception\RouteNotFoundException
* @throws RouteNotFoundException
*/
public function mainAction(ServerRequestInterface $request): ResponseInterface
{
......@@ -186,8 +190,7 @@ class FileController
$fileName = $request->getParsedBody()['fileName'] ?? $request->getQueryParams()['fileName'] ?? null;
$fileTarget = $request->getParsedBody()['fileTarget'] ?? $request->getQueryParams()['fileTarget'] ?? null;
$fileFactory = GeneralUtility::makeInstance(ResourceFactory::class);
$fileTargetObject = $fileFactory->retrieveFileOrFolderObject($fileTarget);
$fileTargetObject = $this->fileFactory->retrieveFileOrFolderObject($fileTarget);
$processedFileName = $fileTargetObject->getStorage()->sanitizeFileName($fileName, $fileTargetObject);
$result = [];
......@@ -232,7 +235,6 @@ class FileController
$this->overwriteExistingFiles = DuplicationBehavior::cast($parsedBody['overwriteExistingFiles'] ?? $queryParams['overwriteExistingFiles'] ?? null);
}
$this->initClipboard();
$this->fileProcessor = GeneralUtility::makeInstance(ExtendedFileUtility::class);
}
/**
......@@ -260,7 +262,6 @@ class FileController
*/
protected function main(): void
{
// Initializing:
$this->fileProcessor->setActionPermissions();
$this->fileProcessor->setExistingFilesConflictMode($this->overwriteExistingFiles);
$this->fileProcessor->start($this->file);
......@@ -272,7 +273,7 @@ class FileController
*
* @param File $file to be edited
* @return string|null URI to be redirected to
* @throws \TYPO3\CMS\Backend\Routing\Exception\RouteNotFoundException
* @throws RouteNotFoundException
*/
protected function getFileEditRedirect(File $file): ?string
{
......@@ -286,9 +287,8 @@ class FileController
if ($this->redirect) {
$urlParameters['returnUrl'] = $this->redirect;
}
$uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
try {
return (string)$uriBuilder->buildUriFromRoute('file_edit', $urlParameters);
return (string)$this->uriBuilder->buildUriFromRoute('file_edit', $urlParameters);
} catch (RouteNotFoundException $exception) {
// no route for editing files available
return '';
......@@ -314,12 +314,11 @@ class FileController
$thumbUrl = PathUtility::getAbsoluteWebPath($processedFile->getPublicUrl() ?? '');
}
}
$iconFactory = GeneralUtility::makeInstance(IconFactory::class);
$result = array_merge(
$result->toArray(),
[
'date' => BackendUtility::date($result->getModificationTime()),
'icon' => $iconFactory->getIconForFileExtension($result->getExtension(), Icon::SIZE_SMALL)->render(),
'icon' => $this->iconFactory->getIconForFileExtension($result->getExtension(), Icon::SIZE_SMALL)->render(),
'thumbUrl' => $thumbUrl
]
);
......@@ -329,14 +328,4 @@ class FileController
return $result;
}
/**
* Returns the current BE user.
*
* @return BackendUserAuthentication
*/
protected function getBackendUser(): BackendUserAuthentication
{
return $GLOBALS['BE_USER'];
}
}
......@@ -119,6 +119,9 @@ services:
TYPO3\CMS\Backend\Controller\ContentElement\NewContentElementController:
tags: ['backend.controller']
TYPO3\CMS\Backend\Controller\File\FileController:
tags: ['backend.controller']
TYPO3\CMS\Backend\Form\FormDataProvider\SiteDatabaseEditRow:
public: true
......
......@@ -18,14 +18,11 @@ namespace TYPO3\CMS\Backend\Tests\Unit\Controller\File;
use Prophecy\Argument;
use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Backend\Controller\File\FileController;
use TYPO3\CMS\Core\Http\Response;
use TYPO3\CMS\Core\Http\ServerRequest;
use TYPO3\CMS\Core\Imaging\Icon;
use TYPO3\CMS\Core\Imaging\IconFactory;
use TYPO3\CMS\Core\Resource\File;
use TYPO3\CMS\Core\Resource\Folder;
use TYPO3\CMS\Core\Utility\File\ExtendedFileUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
/**
......@@ -34,30 +31,25 @@ use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
class FileControllerTest extends UnitTestCase
{
/**
* @var \TYPO3\CMS\Core\Resource\File|\PHPUnit\Framework\MockObject\MockObject
* @var File|\PHPUnit\Framework\MockObject\MockObject
*/
protected $fileResourceMock;
/**
* @var \TYPO3\CMS\Core\Resource\Folder|\PHPUnit\Framework\MockObject\MockObject
* @var Folder|\PHPUnit\Framework\MockObject\MockObject
*/
protected $folderResourceMock;
/**
* @var \TYPO3\CMS\Core\Utility\File\ExtendedFileUtility|\PHPUnit\Framework\MockObject\MockObject
* @var ExtendedFileUtility|\PHPUnit\Framework\MockObject\MockObject
*/
protected $mockFileProcessor;
/**
* @var ServerRequest|\PHPUnit\Framework\MockObject\MockObject
* @var ServerRequestInterface
*/
protected $request;
/**
* @var Response|\PHPUnit\Framework\MockObject\MockObject
*/
protected $response;
/**
* Sets up this test case.
*/
......@@ -81,10 +73,7 @@ class FileControllerTest extends UnitTestCase
$this->fileResourceMock->expects(self::any())->method('getExtension')->willReturn('html');
$serverRequest = $this->prophesize(ServerRequestInterface::class);
$GLOBALS['TYPO3_REQUEST'] = $serverRequest->reveal();
$this->request = new ServerRequest();
$this->response = new Response();
$this->request = $serverRequest->reveal();
}
/**
......@@ -92,7 +81,7 @@ class FileControllerTest extends UnitTestCase
*/
public function flattenResultDataValueReturnsAnythingElseAsIs()
{
$subject = $this->getAccessibleMock(FileController::class, ['dummy']);
$subject = $this->getAccessibleMock(FileController::class, ['init', 'main'], [], '', false);
self::assertTrue($subject->_call('flattenResultDataValue', true));
self::assertSame([], $subject->_call('flattenResultDataValue', []));
}
......@@ -102,13 +91,12 @@ class FileControllerTest extends UnitTestCase
*/
public function flattenResultDataValueFlattensFile()
{
$subject = $this->getAccessibleMock(FileController::class, ['dummy']);
$subject = $this->getAccessibleMock(FileController::class, ['init', 'main'], [], '', false);
$iconFactoryProphecy = $this->prophesize(IconFactory::class);
GeneralUtility::addInstance(IconFactory::class, $iconFactoryProphecy->reveal());
$iconProphecy = $this->prophesize(Icon::class);
$iconProphecy->render()->shouldBeCalled()->willReturn('');
$iconFactoryProphecy->getIconForFileExtension(Argument::cetera())->willReturn($iconProphecy->reveal());
$subject->_set('iconFactory', $iconFactoryProphecy->reveal());
$result = $subject->_call('flattenResultDataValue', $this->fileResourceMock);
self::assertSame(
......@@ -127,16 +115,13 @@ class FileControllerTest extends UnitTestCase
*/
public function processAjaxRequestDeleteProcessActuallyDoesNotChangeFileData()
{
$subject = $this->getAccessibleMock(FileController::class, ['init', 'main']);
$subject = $this->getAccessibleMock(FileController::class, ['init', 'main'], [], '', false);
$fileData = ['delete' => [true]];
$subject->_set('fileProcessor', $this->mockFileProcessor);
$subject->_set('fileData', $fileData);
$subject->_set('redirect', false);
$subject->expects(self::once())->method('main');
$subject->processAjaxRequest($this->request, $this->response);
$subject->processAjaxRequest($this->request);
}
/**
......@@ -144,16 +129,13 @@ class FileControllerTest extends UnitTestCase
*/
public function processAjaxRequestEditFileProcessActuallyDoesNotChangeFileData()
{
$subject = $this->getAccessibleMock(FileController::class, ['init', 'main']);
$subject = $this->getAccessibleMock(FileController::class, ['init', 'main'], [], '', false);
$fileData = ['editfile' => [true]];
$subject->_set('fileProcessor', $this->mockFileProcessor);
$subject->_set('fileData', $fileData);
$subject->_set('redirect', false);
$subject->expects(self::once())->method('main');
$subject->processAjaxRequest($this->request, $this->response);
$subject->processAjaxRequest($this->request);
}
/**
......@@ -161,15 +143,13 @@ class FileControllerTest extends UnitTestCase
*/
public function processAjaxRequestReturnsStatus200IfNoErrorOccurs()
{
$subject = $this->getAccessibleMock(FileController::class, ['init', 'main']);
$subject = $this->getAccessibleMock(FileController::class, ['init', 'main'], [], '', false);
$fileData = ['editfile' => [true]];
$subject->_set('fileProcessor', $this->mockFileProcessor);
$subject->_set('fileData', $fileData);
$subject->_set('redirect', false);
$result = $subject->processAjaxRequest($this->request, $this->response);
self::assertEquals(200, $result->getStatusCode());
$response = $subject->processAjaxRequest($this->request);
self::assertEquals(200, $response->getStatusCode());
}
/**
......@@ -177,10 +157,10 @@ class FileControllerTest extends UnitTestCase
*/
public function processAjaxRequestReturnsStatus500IfErrorOccurs()
{
$subject = $this->getAccessibleMock(FileController::class, ['init', 'main']);
$this->mockFileProcessor->expects(self::any())->method('getErrorMessages')->willReturn(['error occurred']);
$subject = $this->getAccessibleMock(FileController::class, ['init', 'main'], [], '', false);
$subject->_set('fileProcessor', $this->mockFileProcessor);
$result = $subject->processAjaxRequest($this->request, $this->response);
self::assertEquals(500, $result->getStatusCode());
$response = $subject->processAjaxRequest($this->request);
self::assertEquals(500, $response->getStatusCode());
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment