Commit 6366b902 authored by Benni Mack's avatar Benni Mack Committed by Wouter Wolters
Browse files

[TASK] Deprecate internal_type=file and file_reference

TCA "type=group" with "internal_type=file" and "internal_type=file_reference"
are the last parts of content related file handling that circumvent FAL.

All usages in the core have been changed since TYPO3 v6 until TYPO3 v9.

To prepare and unlock further file system related works in v10, it is
important we finally get rid of these parts that low level handles
uploads/ and other legacy functionality.

The patch finds any usages via TcaMigration, notes them as
deprecated and adds a series of hints to core places that can be
removed in v10. Note there is probably some hidden handling
left in the core, this is partially hard to find. We may stumble
upon more details in v10, but will have the freedom to remove
them then.

Resolves: #86406
Releases: master
Change-Id: I94f2fa6364277497e85e513f1bfd34cc0acf1390
Reviewed-on: https://review.typo3.org/58414

Tested-by: default avatarTYPO3com <no-reply@typo3.com>
Reviewed-by: Christian Kuhn's avatarChristian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn's avatarChristian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Wouter Wolters's avatarWouter Wolters <typo3@wouterwolters.nl>
Tested-by: Wouter Wolters's avatarWouter Wolters <typo3@wouterwolters.nl>
parent 3523a860
......@@ -146,6 +146,7 @@ class GroupElement extends AbstractFormElement
$listOfSelectedValues = [];
$selectorOptionsHtml = [];
if ($internalType === 'file_reference' || $internalType === 'file') {
// @deprecated since TYPO3 v9, will be removed in TYPO3 v10. Deprecation logged by TcaMigration class.
foreach ($selectedItems as $selectedItem) {
$uidOrPath = $selectedItem['uidOrPath'];
$listOfSelectedValues[] = $uidOrPath;
......
......@@ -50,6 +50,7 @@ class InsertClipboard extends AbstractNode
$title = '';
$clipboardOnClick = [];
if ($internalType === 'file_reference' || $internalType === 'file') {
// @deprecated since TYPO3 v9, will be removed in TYPO3 v10. Deprecation logged by TcaMigration class.
$title = sprintf($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.clipInsert_file'), count($clipboardElements));
foreach ($clipboardElements as $clipboardElement) {
$value = $clipboardElement['value'];
......
......@@ -49,6 +49,7 @@ class FileThumbnails extends AbstractNode
if (!isset($config['internal_type'])
|| ($config['internal_type'] !== 'file' && $config['internal_type'] !== 'file_reference')
) {
// @deprecated since TYPO3 v9, will be removed in TYPO3 v10. Deprecation logged by TcaMigration class.
// Thumbnails only make sense on file and file_reference
return $result;
}
......
......@@ -39,6 +39,7 @@ class FileTypeList extends AbstractNode
if (!isset($config['allowed']) || !is_string($config['allowed']) || empty($config['allowed'])
|| !isset($config['internal_type']) || $config['internal_type'] !== 'file'
) {
// @deprecated since TYPO3 v9, will be removed in TYPO3 v10. Deprecation logged by TcaMigration class.
// No handling if the field has no, or funny "allowed" setting, and if internal_type is not "file"
return $result;
}
......
......@@ -47,6 +47,7 @@ class FileUpload extends AbstractNode
|| !$isDirectFileUploadEnabled
|| empty($config['uploadfolder'])
) {
// @deprecated since TYPO3 v9, will be removed in TYPO3 v10. Deprecation logged by TcaMigration class.
// No upload if disabled for user or upload folder missing
return $result;
}
......
......@@ -103,6 +103,7 @@ class OtherLanguageContent extends AbstractNode
*/
protected function previewFieldValue($value, $config, $field = '')
{
// @deprecated since TYPO3 v9, will be removed in TYPO3 v10. Deprecation logged by TcaMigration class.
$value = (string)$value;
if ($config['config']['type'] === 'group'
&& ($config['config']['internal_type'] === 'file' || $config['config']['internal_type'] === 'file_reference')
......
......@@ -67,6 +67,7 @@ class TcaGroup implements FormDataProviderInterface
$internalType = $fieldConfig['config']['internal_type'];
if ($internalType === 'file_reference' || $internalType === 'file') {
// @deprecated since TYPO3 v9, will be removed in TYPO3 v10. Deprecation logged by TcaMigration class.
// Set 'allowed' config to "*" if not set
if (empty($fieldConfig['config']['allowed'])) {
$result['processedTca']['columns'][$fieldName]['config']['allowed'] = '*';
......
......@@ -411,6 +411,7 @@ class RecordHistory
*/
protected function removeFilefields($table, $dataArray)
{
// @deprecated since TYPO3 v9, will be removed in TYPO3 v10. Deprecation logged by TcaMigration class.
if ($GLOBALS['TCA'][$table]) {
foreach ($GLOBALS['TCA'][$table]['columns'] as $field => $config) {
if ($config['config']['type'] === 'group' && $config['config']['internal_type'] === 'file') {
......
......@@ -1685,6 +1685,7 @@ class DataHandler implements LoggerAwareInterface
$tcaFieldConf['type'] === 'flex'
|| $tcaFieldConf['type'] === 'group' && ($tcaFieldConf['internal_type'] === 'file' || $tcaFieldConf['internal_type'] === 'file_reference')
) {
// @deprecated since TYPO3 v9, will be removed in TYPO3 v10. Deprecation logged by TcaMigration class. Remove type=group handling.
$recFID = $table . ':' . $id . ':' . $field;
} else {
$recFID = null;
......@@ -2176,6 +2177,7 @@ class DataHandler implements LoggerAwareInterface
// For group types:
if ($tcaFieldConf['type'] === 'group'
&& in_array($tcaFieldConf['internal_type'], ['file', 'file_reference'], true)) {
// @deprecated since TYPO3 v9, will be removed in TYPO3 v10. Deprecation logged by TcaMigration class.
$valueArray = $this->checkValue_group_select_file($valueArray, $tcaFieldConf, $curValue, $uploadedFiles, $status, $table, $id, $recFID);
}
// For select types which has a foreign table attached:
......@@ -2250,6 +2252,7 @@ class DataHandler implements LoggerAwareInterface
* @return array Modified value array
*
* @throws \RuntimeException
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10. Deprecation logged by TcaMigration class.
*/
public function checkValue_group_select_file($valueArray, $tcaFieldConf, $curValue, $uploadedFileArray, $status, $table, $id, $recFID)
{
......@@ -4195,6 +4198,7 @@ class DataHandler implements LoggerAwareInterface
* @param string $value Field value (eg. list of files)
* @return string The (possibly modified) value
* @see copyRecord(), copyRecord_flexFormCallBack()
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10. Deprecation logged by TcaMigration class.
*/
public function copyRecord_procFilesRefs($conf, $uid, $value)
{
......@@ -5426,6 +5430,7 @@ class DataHandler implements LoggerAwareInterface
$files = $refIndexObj->getRelations_procFiles($dataValue, $dsArr['TCEforms']['config'], $PA['uid']);
// Traverse files and delete them if the field is a regular file field (and not a file_reference field)
if (is_array($files) && $dsArr['TCEforms']['config']['internal_type'] === 'file') {
// @deprecated since TYPO3 v9, will be removed in TYPO3 v10. Deprecation logged by TcaMigration class.
foreach ($files as $dat) {
if (@is_file($dat['ID_absFile'])) {
$file = $this->getResourceFactory()->retrieveFileOrFolderObject($dat['ID_absFile']);
......@@ -8302,6 +8307,7 @@ class DataHandler implements LoggerAwareInterface
*
* @param string $table Table name
* @return array Array of fieldnames that are either "group" or "file" types.
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10. Deprecation logged by TcaMigration class.
*/
public function extFileFields($table)
{
......@@ -8482,6 +8488,7 @@ class DataHandler implements LoggerAwareInterface
* @param string $table Table name
* @param string $field Field name
* @param string $filelist List of files to work on from field
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10. Deprecation logged by TcaMigration class.
*/
public function extFileFunctions($table, $field, $filelist)
{
......
......@@ -29,7 +29,15 @@ final class TableColumnSubType extends Enumeration
const DEFAULT_TYPE = '';
const DB = 'DB';
/**
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10. Deprecation logged by TcaMigration class.
*/
const FILE = 'FILE';
/**
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10. Deprecation logged by TcaMigration class.
*/
const FILE_REFERENCE = 'FILE_REFERENCE';
const FOLDER = 'FOLDER';
......
......@@ -871,6 +871,7 @@ class ReferenceIndex implements LoggerAwareInterface
* @param array $conf Field configuration array of type "TCA/columns
* @param int $uid Field uid
* @return bool|array If field type is OK it will return an array with the files inside. Else FALSE
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10. Deprecation logged by TcaMigration class.
*/
public function getRelations_procFiles($value, $conf, $uid)
{
......
......@@ -172,6 +172,7 @@ class SoftReferenceIndex
// If it looks like a local image, continue. Otherwise ignore it.
$absPath = GeneralUtility::getFileAbsFileName(Environment::getPublicPath() . '/' . $srcRef);
if (!$pI['scheme'] && !$pI['query'] && $absPath && $srcRef !== 'clear.gif') {
// @deprecated since TYPO3 v9, will be removed in TYPO3 v10. Deprecation logged by TcaMigration class.
// Initialize the element entry with info text here:
$tokenID = $this->makeTokenID($k);
$elements[$k] = [];
......
......@@ -379,6 +379,7 @@ class DatabaseIntegrityCheck
foreach ($cols as $field => $config) {
if ($config['config']['type'] === 'group') {
if ((!$mode || $mode === 'file') && $config['config']['internal_type'] === 'file' || (!$mode || $mode === 'db') && $config['config']['internal_type'] === 'db') {
// @deprecated since TYPO3 v9, will be removed in TYPO3 v10. Deprecation logged by TcaMigration class. Remove the type=file specific code.
$result[$table][] = $field;
}
}
......@@ -398,6 +399,7 @@ class DatabaseIntegrityCheck
*
* @param string $uploadfolder Path to uploadfolder
* @return array An array with all fields listed that have references to files in the $uploadfolder
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10. Deprecation logged by TcaMigration class.
*/
public function getFileFields($uploadfolder)
{
......@@ -516,6 +518,7 @@ class DatabaseIntegrityCheck
$fieldConf = $GLOBALS['TCA'][$table]['columns'][$field]['config'];
if ($fieldConf['type'] === 'group') {
if ($fieldConf['internal_type'] === 'file') {
// @deprecated since TYPO3 v9, will be removed in TYPO3 v10. Deprecation logged by TcaMigration class.
// Files...
if ($fieldConf['MM']) {
$tempArr = [];
......
......@@ -91,6 +91,7 @@ class TcaMigration
$tca = $this->migrateInlineOverrideChildTca($tca);
$tca = $this->migrateLocalizeChildrenAtParentLocalization($tca);
$tca = $this->migratePagesLanguageOverlayRemoval($tca);
$tca = $this->deprecateTypeGroupInternalTypeFile($tca);
return $tca;
}
......@@ -2575,4 +2576,33 @@ class TcaMigration
}
return $tca;
}
/**
* type=group with internal_type=file and internal_type=file_reference have
* been deprecated in TYPO3 v9 and will be removed in v10. This method scans
* for usages. This methods does not modify TCA.
*
* @param array $tca
* @return array
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.
*/
protected function deprecateTypeGroupInternalTypeFile(array $tca): array
{
foreach ($tca as $table => $tableDefinition) {
if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
continue;
}
foreach ($tableDefinition['columns'] as $fieldName => $fieldConfig) {
if (isset($fieldConfig['config']['type'], $fieldConfig['config']['internal_type'])
&& $fieldConfig['config']['type'] === 'group'
&& ($fieldConfig['config']['internal_type'] === 'file' || $fieldConfig['config']['internal_type'] === 'file_reference')
) {
$this->messages[] = 'The \'internal_type\' = \'' . $fieldConfig['config']['internal_type'] . '\' property value'
. ' from TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'] is deprecated. It will continue'
. ' to work is TYPO3 v9, but the functionality will be removed in TYPO3 v10. Switch to inline FAL instead.';
}
}
}
return $tca;
}
}
......@@ -91,7 +91,7 @@ class TreeDataProviderFactory
throw new \InvalidArgumentException('TCA Tree configuration is invalid: neither "childrenField" nor "parentField" is set', 1288215889);
}
} elseif ($tcaConfiguration['internal_type'] === 'file' && $dataProvider === null) {
// @todo Not implemented yet
// @deprecated since TYPO3 v9, will be removed in TYPO3 v10. Deprecation logged by TcaMigration class.
throw new \InvalidArgumentException('TCA Tree configuration is invalid: tree for "internal_type=file" not implemented yet', 1288215891);
} elseif ($dataProvider === null) {
throw new \InvalidArgumentException('TCA Tree configuration is invalid: tree for "internal_type=' . $tcaConfiguration['internal_type'] . '" not implemented yet', 1288215892);
......
.. include:: ../../Includes.txt
==========================================================================
Deprecation: #86406 - TCA type group internal_type file and file_reference
==========================================================================
See :issue:`86406`
Description
===========
The :php`TCA` property values :php:`internal_type="file"` and :php:`internal_type="file_reference"`
for columns config :php:`type="group"` have been marked as deprecated.
A series of related methods have been marked as deprecated:
* :php:`TYPO3\CMS\Core\DataHandling\DataHandler->checkValue_group_select_file()
* :php:`TYPO3\CMS\Core\DataHandling\DataHandler->copyRecord_procFilesRefs()
* :php:`TYPO3\CMS\Core\DataHandling\DataHandler->extFileFields()
* :php:`TYPO3\CMS\Core\DataHandling\DataHandler->extFileFunctions()
* :php:`TYPO3\CMS\Core\Database\ReferenceIndex->getRelations_procFiles()
* :php:`TYPO3\CMS\Core\Integrity\DatabaseIntegrityCheck->getFileFields()
Some constants have bee marked as deprecated:
* :php:`TYPO3\CMS\Core\DataHandling\TableColumnSubType::FILE`
* :php:`TYPO3\CMS\Core\DataHandling\TableColumnSubType::FILE_REFERENCE`
The "internal_type" functionality has been superseded by the File Abstraction Layer (FAL) since TYPO3 6.0
and has several drawbacks within TYPO3 (e.g. multiple copies of files based on a file name, no flexibility
for moving data to a different storage, no metadata functionality, no cropping functionality).
Impact
======
The Backend module "Upgrade" > "Check TCA migrations" shows them as deprecated, and triggers a
:php:`E_USER_DEPRECATED` error.
Using the TCA property values mentioned above will also trigger a deprecation message when the cache is cleared.
Affected Installations
======================
Installations still using the methods or constants, or TYPO3 installations with extensions registering custom
TCA fields with the mentioned TCA properties.
Migration
=========
It is rather unlikely instances use one of the above methods or constants. The extension scanner will find possible
usages, though.
It's more likely that extensions use :php:`type=group` with :php:`internal_type=file` or
:php:`internal_type=file_reference`. Those should switch to use FAL references based on
:php:`type=inline` instead.
The core code changed one last :php:`internal_type=file` usage in TYPO3 v9 and moved it to FAL. Several use-cases
within the last TYPO3 major versions have shown how to migrate a legacy file field to FAL (e.g. "fe_users.image"
or "tt_content.image" including automatic upgrade wizards for the database - an example of the last migration can be
found online_. These previous changes give some insight on how a file relation could be changed to FAL and comes
with an upgrade wizard that can be a helpful example if existing extension data needs to be migrated.
.. _online: https://review.typo3.org/#/c/54830/
.. index:: Backend, PHP-API, TCA, PartiallyScanned
......@@ -6565,4 +6565,48 @@ class TcaMigrationTest extends UnitTestCase
$subject = new TcaMigration();
$this->assertEquals($expected, $subject->migrate($input));
}
/**
* @test
*/
public function migrateLogsDeprecationWithGroupInternalTypeFile()
{
$input = [
'aTable' => [
'columns' => [
'foo' => [
'config' => [
'type' => 'group',
'internal_type' => 'file',
],
],
],
],
];
$subject = new TcaMigration();
$subject->migrate($input);
$this->assertNotEmpty($subject->getMessages());
}
/**
* @test
*/
public function migrateLogsDeprecationWithGroupInternalTypeFileReference()
{
$input = [
'aTable' => [
'columns' => [
'foo' => [
'config' => [
'type' => 'group',
'internal_type' => 'file_reference',
],
],
],
],
];
$subject = new TcaMigration();
$subject->migrate($input);
$this->assertNotEmpty($subject->getMessages());
}
}
......@@ -120,4 +120,14 @@ return [
'Deprecation-85804-SaltedPasswordHashClassDeprecations.rst',
],
],
'TYPO3\CMS\Core\DataHandling\TableColumnSubType::FILE' => [
'restFiles' => [
'Deprecation-86406-TCATypeGroupInternal_typeFileAndFile_reference.rst',
],
],
'TYPO3\CMS\Core\DataHandling\TableColumnSubType::FILE_REFERENCE' => [
'restFiles' => [
'Deprecation-86406-TCATypeGroupInternal_typeFileAndFile_reference.rst',
],
],
];
......@@ -3530,4 +3530,46 @@ return [
'Deprecation-86389-GeneralUtility_GETsetAndTSFE-mergingWithGetVars.rst',
],
],
'TYPO3\CMS\Core\DataHandling\DataHandler->checkValue_group_select_file' => [
'numberOfMandatoryArguments' => 8,
'maximumNumberOfArguments' => 8,
'restFiles' => [
'Deprecation-86406-TCATypeGroupInternal_typeFileAndFile_reference.rst',
],
],
'TYPO3\CMS\Core\DataHandling\DataHandler->copyRecord_procFilesRefs' => [
'numberOfMandatoryArguments' => 3,
'maximumNumberOfArguments' => 3,
'restFiles' => [
'Deprecation-86406-TCATypeGroupInternal_typeFileAndFile_reference.rst',
],
],
'TYPO3\CMS\Core\DataHandling\DataHandler->extFileFields' => [
'numberOfMandatoryArguments' => 1,
'maximumNumberOfArguments' => 1,
'restFiles' => [
'Deprecation-86406-TCATypeGroupInternal_typeFileAndFile_reference.rst',
],
],
'TYPO3\CMS\Core\DataHandling\DataHandler->extFileFunctions' => [
'numberOfMandatoryArguments' => 3,
'maximumNumberOfArguments' => 3,
'restFiles' => [
'Deprecation-86406-TCATypeGroupInternal_typeFileAndFile_reference.rst',
],
],
'TYPO3\CMS\Core\Database\ReferenceIndex->getRelations_procFiles' => [
'numberOfMandatoryArguments' => 3,
'maximumNumberOfArguments' => 3,
'restFiles' => [
'Deprecation-86406-TCATypeGroupInternal_typeFileAndFile_reference.rst',
],
],
'TYPO3\CMS\Core\Integrity\DatabaseIntegrityCheck->getFileFields' => [
'numberOfMandatoryArguments' => 1,
'maximumNumberOfArguments' => 1,
'restFiles' => [
'Deprecation-86406-TCATypeGroupInternal_typeFileAndFile_reference.rst',
],
],
];
......@@ -168,6 +168,7 @@ class CleanerTask extends AbstractTask
* Checks if the table has fields for uploaded files and removes those files.
*
* @param string $table
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10. Deprecation logged by TcaMigration class. Remove caller, too.
*/
protected function checkFileResourceFieldsBeforeDeletion($table)
{
......@@ -225,6 +226,7 @@ class CleanerTask extends AbstractTask
*
* @param string $table
* @return array
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10. Deprecation logged by TcaMigration class.
*/
protected function getFileResourceFields($table)
{
......
Supports Markdown
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