Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

flux:field.file for TYPO3 11 and 12 #2139

Closed
ms-wa opened this issue Nov 9, 2023 · 6 comments
Closed

flux:field.file for TYPO3 11 and 12 #2139

ms-wa opened this issue Nov 9, 2023 · 6 comments

Comments

@ms-wa
Copy link

ms-wa commented Nov 9, 2023

Is flux:field.file now supported in TYPO3 11 or 12?

When I read the history of the viewhelper the comment was removed with deprecate.

@mdittberner
Copy link

mdittberner commented Dec 7, 2023

I also recognized that the deprecation hints were removed. The file field is still working. BUT:
Because the changes in TYPO3 TCA the browse button tries to display db records instead of files. This is caused by a change where the TCA config "appearance" in not evaluated anymore (see https://docs.typo3.org/m/typo3/reference-tca/12.4/en-us/ColumnsConfig/Type/Group/Properties/Appearance.html). The according data-mode attribute of the browsebutton is always set to "db". Only for "real" file relations it is possible to browse files. Since we cannot use inline relations inside sections this sucks. The current version of flux tries to change it to "file" in FluidTYPO3\Flux\Form\Field\File but as mentioned the appearance is ignored. I spent many hours to solve the problem (even a migration wizard to create file references and use them with an own viewhelper). But I found no solution for inherited images in page templates.

So i thought in another way and found a workaround writing a little XClass which restores the original behaviour of the element browser.

class ElementBrowser extends \TYPO3\CMS\Backend\Form\FieldControl\ElementBrowser
{
    /**
     * Modify result of the original render function if TCA config myFilebrowserFix is set.
     *
     * @return array
     */
    public function render(): array
    {
        $fieldConfig = $this->data['parameterArray']['fieldConf']['config'];
        if($fieldConfig['myFilebrowserFix']) {
            $configArray = parent::render();
            if(is_array($configArray)) {
                if(array_key_exists('linkAttributes', $configArray)) {
                    // This makes the folder button a file selector instead a db selector.
                    $configArray['linkAttributes']['data-mode'] = 'file';
                }
            }
            return $configArray;
        } else {
            return parent::render();
        }
    }

}

In this way I can restore the original behaviour of the file browser for a flux field by adding config="{myFilebrowserFix: 'true'}" to the flux:field.file in the template.
@NamelessCoder Maybe this could be worth a look to make flux file fields working again in TYPO3 12 LTS.

Regards,
Michael

@NamelessCoder
Copy link
Member

Is flux:field.file now supported in TYPO3 11 or 12?

It is supported, but there are limitations imposed by the TYPO3 core. Most notably that you cannot use it within sections / section objects. Historically this field has been a group with internal_type but TYPO3 no longer supports that - so it is now silently rewritten to become a file type which is supported on all TYPO3 versions.

The reason all the individual field types were initially deprecated in Flux was that heavy changes were being made to TCA constantly through all supported versions since 8.7, and keeping up with all of those changes to internally rewrite types on each version was becoming unfeasible. The substitute idea was to provide a more generic field ViewHelper where each editor was responsible for choosing the type, renderType and config (while being careful to select the right ones for their TYPO3 version) - but, since 10.4 the TCA specs seem to have at least partially stabilised enough that those deprecations did not need to be removed. So, the special field type ViewHelpers in Flux survive at least for now, but if the TCA specs are hit with drastic changes again, which would require heavy workarounds for multiple core versions, they may yet be deprecated and removed at some point. The safest option will always be flux:field with type and config specified in a way that's compatible with your TYPO3 version!

@mdittberner Thanks for posting your workaround. I know that this response won't be the one you (and many others) are looking for, but I should explain something about Flux that might help to explain why Flux won't be doing things like adding an XCLASS that overrides a core class to re-animate some feature that was (partially, incompletely) killed off by the TYPO3 core:

Flux fields are merely an abstraction over TCA. The purpose is to allow you to do literally anything that's possible to do with TCA, but with a proper object-and-ViewHelper API instead of a huge anonymous array. Flux is not, and never was, designed to change how TCA works and what is possible to do with TCA. This means that if the TYPO3 core decides that something is no longer possible (group with "file" type, wizards as sub-arrays, etc.) then Flux will simply follow suit and like with wizards straight up remove all of those ViewHelpers, or in some cases like with "file" choose the closest reasonably matching type of field and create a config array for that type instead (although sometimes that means some properties that were supported, are now ignored - like with appearance).

The mantra basically is: if you can do it with TCA, you can do it with Flux - and if you can do it with Flux, you can do it with TCA (but you'd need to write a hell of a lot more TCA than Flux code!). If you can't do it with TCA you also can't do it with Flux.

My advise will always be to migrate your implementations as soon as you discover that a certain thing - such as group with "file" type - will become impossible in the future. What this particular XCLASS will do, will just be to prolong the pain. The field type/combo is marked for death and it will die - it's only a coincidence that for some reason, the JS component is still capable of reading and using the data-mode="file" attribute; I can pretty much guarantee you that this will also be removed as soon as someone finds out it is still there. So while your XCLASS might allow you to keep going on v12 for now, you should fully expect that as soon as v13 is released, this too will break and it will become even more difficult, if not altogether impossible, to work around it. This is precisely the reason why Flux doesn't even begin to work around things this way: it starts a path towards regression and will inevitably end in a dead end, with each step making it more and more difficult for users to change their implementations to something that does work in TCA.

Lastly I should say that I do often strongly disagree with decisions made in the TYPO3 core especially concerning the removal of features or locking-in of API, but it's a reality that I've tried and failed to change many, many times with each attempt costing a lot of time and causing a lot of grief. Unfortunately, once it's decided to chop off parts of the API then nothing I can say or do will change it. Sometimes, an XCLASS re-animates what should be dead but inevitably it gets killed for good anyway. So it's best not to try, accept defeat and bite the migration bullet. I hate to say that, but it really is.

@mdittberner
Copy link

@NamelessCoder Have many thanks to Your detailed answer and your clear words. I supposed that there are good reasons for never touching core behaviour with an XClass. Your statements brought more light in the darkness. My favourite was " I can pretty much guarantee you that this will also be removed as soon as someone finds out it is still there.". Hart gefeiert! ^^

@NamelessCoder
Copy link
Member

You're most welcome, @mdittberner - and sorry I couldn't give you better news. It's not a fun situation this one, all the way around!

@grischpel
Copy link

grischpel commented Apr 19, 2024

I have a solution:

<?php

  namespace Vendor\Extensionname\ViewHelpers\Data;

  use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
  use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
  use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
  use TYPO3Fluid\Fluid\Core\ViewHelper\Exception;
  use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
  use TYPO3\CMS\Core\Utility\DebugUtility;

  class ImageconfigViewHelper extends AbstractViewHelper {

	use CompileWithRenderStatic;

	/**
	 * Output is escaped already. We must not escape children, to avoid double encoding.
	 *
	 * @var bool
	 */
	protected $escapeChildren = false;

	public function initializeArguments() {
	    $this->registerArgument('type', 'string', 'File type');
	}

	/**
	 * Return array element by key.
	 *
	 * @param array $arguments
	 * @param \Closure $renderChildrenClosure
	 * @param RenderingContextInterface $renderingContext
	 * @throws Exception
	 * @return string
	 */
	public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext) {
	  switch ($arguments['type']) {
		case "image":
		  $type = array("gif", "jpg", "jpeg", "tif", "tiff", "bmp", "tga", "png", "ai", "svg", "webp");
		  $title = "Image";
		  break;
		case "video":
		  $type = array("webm", "mp4", "mov", "asc", "youtube", "vimeo");
		  $title = "Video";
		  break;
		default:
		  $type = array("*");
		  $title = "File";
		  break;
	  }
	  $config = [
		'type' => 'link',
		'required' => false,
		'size' => 20,
		'nullable' => true,
		'allowedTypes' => array('file'),
		'appearance' => [
		  'browserTitle' => $title,
		  'enableBrowser' => true,
		  'allowedFileExtensions' => $type,
		],
	  ];
	  return $config;
	}
  }
  

and in configuration:

<flux:field.input name="image" label="Image" config="{g:data.imageconfig(type: 'image')}" />

Unfortunately, the restriction for the file extensions does not work as intended

@NamelessCoder
Copy link
Member

@grischpel Another problem with that solution is that if I am remembering things correctly, the data type stored by the field type you use is different from the data type stored by the old ViewHelper, to the point where they are incompatible. The field also (again, IIRC) does not support multiple values. The value it stores also isn't nice to work with when attempting to do anything except for linking to the file (does not store the file path or UID in raw format, cannot support f:image etc. and does not work with the transform="file" Flux data transformation).

As such it is most definitely not a drop-in replacement, but perhaps it can serve in some cases as an alternative, in particular for use cases with section containers.

By the way:

  • Since the file type restrictions don't apply correctly you can get the same result with flux:fieldnatively and a relatively smallconfig` array argument.
  • Custom fields may be better achieved by subclassing Flux's abstract field ViewHelper so you don't have to use two ViewHelpers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants