From 8832da28085d0600b5a2d1732b8d05e1d4dba7f7 Mon Sep 17 00:00:00 2001
From: Oliver Bartsch <bo@cedev.de>
Date: Mon, 29 Nov 2021 19:14:32 +0100
Subject: [PATCH] [BUGFIX] UploadedResourceViewHelper does not extend
 UploadViewHelper

With #95486, the UploadViewHelper got extended
for a new tag attribute "accept", which can be used
to limit the allowed file types for an upload field. The
EXT:form UploadedResourceViewHelper, which extends
the UploadViewHelper, registers the "accept" argument
and if given, implodes the value and adds it as attribute
to the tag. This however now led to an exception since
the "accept" attribute got already added by the parent
class.

This is fixed by no longer extending UploadViewHelper,
but implementing the required logic directly in the
UploadedResourceViewHelper.

This step would have been necessary in v12 anyways,
see #95298.

Resolves: #96146
Related: #95298
Related: #95486
Releases: main
Change-Id: Idbc1e284d9a7097fd7397562e566d32debc5f030
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/72383
Tested-by: core-ci <typo3@b13.com>
Tested-by: Benni Mack <benni@typo3.org>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Oliver Bartsch <bo@cedev.de>
Reviewed-by: Benni Mack <benni@typo3.org>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Oliver Bartsch <bo@cedev.de>
---
 .../Form/UploadedResourceViewHelper.php       | 28 ++++++++++--
 .../UploadedResourceViewHelperTest.php        | 44 +++++++++++++++++++
 2 files changed, 69 insertions(+), 3 deletions(-)
 create mode 100644 typo3/sysext/form/Tests/Functional/ViewHelpers/UploadedResourceViewHelperTest.php

diff --git a/typo3/sysext/form/Classes/ViewHelpers/Form/UploadedResourceViewHelper.php b/typo3/sysext/form/Classes/ViewHelpers/Form/UploadedResourceViewHelper.php
index bd20e6d04340..ca1c5d67a860 100644
--- a/typo3/sysext/form/Classes/ViewHelpers/Form/UploadedResourceViewHelper.php
+++ b/typo3/sysext/form/Classes/ViewHelpers/Form/UploadedResourceViewHelper.php
@@ -20,7 +20,7 @@ namespace TYPO3\CMS\Form\ViewHelpers\Form;
 use TYPO3\CMS\Extbase\Domain\Model\FileReference;
 use TYPO3\CMS\Extbase\Property\PropertyMapper;
 use TYPO3\CMS\Extbase\Security\Cryptography\HashService;
-use TYPO3\CMS\Fluid\ViewHelpers\Form\UploadViewHelper;
+use TYPO3\CMS\Fluid\ViewHelpers\Form\AbstractFormFieldViewHelper;
 
 /**
  * This ViewHelper makes the specified Image object available for its
@@ -30,8 +30,12 @@ use TYPO3\CMS\Fluid\ViewHelpers\Form\UploadViewHelper;
  *
  * Scope: frontend
  */
-class UploadedResourceViewHelper extends UploadViewHelper
+class UploadedResourceViewHelper extends AbstractFormFieldViewHelper
 {
+    /**
+     * @var string
+     */
+    protected $tagName = 'input';
 
     /**
      * @var HashService
@@ -71,6 +75,10 @@ class UploadedResourceViewHelper extends UploadViewHelper
         parent::initializeArguments();
         $this->registerArgument('as', 'string', '');
         $this->registerArgument('accept', 'array', 'Values for the accept attribute', false, []);
+        $this->registerArgument('errorClass', 'string', 'CSS class to set if there are errors for this ViewHelper', false, 'f3-form-error');
+        $this->registerTagAttribute('disabled', 'string', 'Specifies that the input element should be disabled when the page loads');
+        $this->registerTagAttribute('multiple', 'string', 'Specifies that the file input element should allow multiple selection of files');
+        $this->registerUniversalTagAttributes();
     }
 
     /**
@@ -80,6 +88,7 @@ class UploadedResourceViewHelper extends UploadViewHelper
     {
         $output = '';
 
+        $name = $this->getName();
         $as = $this->arguments['as'];
         $accept = $this->arguments['accept'];
         $resource = $this->getUploadedResource();
@@ -106,7 +115,20 @@ class UploadedResourceViewHelper extends UploadViewHelper
             $this->templateVariableContainer->remove($as);
         }
 
-        $output .= parent::render();
+        foreach (['name', 'type', 'tmp_name', 'error', 'size'] as $fieldName) {
+            $this->registerFieldNameForFormTokenGeneration($name . '[' . $fieldName . ']');
+        }
+        $this->tag->addAttribute('type', 'file');
+
+        if (isset($this->arguments['multiple'])) {
+            $this->tag->addAttribute('name', $name . '[]');
+        } else {
+            $this->tag->addAttribute('name', $name);
+        }
+
+        $this->setErrorClassAttribute();
+        $output .= $this->tag->render();
+
         return $output;
     }
 
diff --git a/typo3/sysext/form/Tests/Functional/ViewHelpers/UploadedResourceViewHelperTest.php b/typo3/sysext/form/Tests/Functional/ViewHelpers/UploadedResourceViewHelperTest.php
new file mode 100644
index 000000000000..d1df55ca3279
--- /dev/null
+++ b/typo3/sysext/form/Tests/Functional/ViewHelpers/UploadedResourceViewHelperTest.php
@@ -0,0 +1,44 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * 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!
+ */
+
+namespace TYPO3\CMS\Form\Tests\Functional\ViewHelpers;
+
+use TYPO3\CMS\Fluid\View\StandaloneView;
+use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
+
+class UploadedResourceViewHelperTest extends FunctionalTestCase
+{
+    /**
+     * @var string[]
+     */
+    protected $coreExtensionsToLoad = ['form'];
+
+    /**
+     * @var bool Speed up this test case, it needs no database
+     */
+    protected $initializeDatabase = false;
+
+    /**
+     * @test
+     */
+    public function accpetAttributeIsAdded(): void
+    {
+        $view = new StandaloneView();
+        $view->setTemplateSource('<formvh:form.uploadedResource accept="{0: \'image/jpeg\', 1: \'image/png\'}"/>');
+        self::assertSame('<input accept="image/jpeg,image/png" type="file" name="" />', $view->render());
+    }
+}
-- 
GitLab