Skip to content
Snippets Groups Projects
Commit 3adf7835 authored by Steffen Ritter's avatar Steffen Ritter Committed by Benni Mack
Browse files

[TASK] FrontendContentAdapterService processes record repeatedly

The FrontendContentAdapterService rewrites records so legacy
TypoScript is able to work on the files to. To do so it queries
the objects regarding the relations and fills the properties of
the record new line separated as known from pre-6.x records.

This change adds a runtime cache, so already processed records
of are not processed again, if the next cObject for the same
record is started.

Resolves: #54953
Releases: 6.2, 6.1
Change-Id: I1f632f175075c9d85079ea83e343e35867a1fcca
Reviewed-on: https://review.typo3.org/26786
Reviewed-by: Oliver Hader
Tested-by: Oliver Hader
Reviewed-by: Benjamin Mack
Tested-by: Benjamin Mack
parent 2750c6ab
No related branches found
No related tags found
No related merge requests found
......@@ -65,6 +65,11 @@ class FrontendContentAdapterService {
)
);
/**
* @var array
*/
protected static $migrationCache = array();
/**
* Modifies the DB row in the CONTENT cObj of tslib_content for supplying
* backwards compatibility for some file fields which have switched to using
......@@ -78,62 +83,77 @@ class FrontendContentAdapterService {
* @return void
*/
static public function modifyDBRow(&$row, $table) {
if (isset($row['_MIGRATED']) && $row['_MIGRATED'] === TRUE) {
// Only consider records with uid set, that have
// not been processed yet ("migrated")
if (!isset($row['uid']) || isset($row['_MIGRATED']) && $row['_MIGRATED'] === TRUE) {
return;
}
if (array_key_exists($table, static::$migrateFields)) {
foreach (static::$migrateFields[$table] as $migrateFieldName => $oldFieldNames) {
if ($row !== NULL && isset($row[$migrateFieldName]) && self::fieldIsInType($migrateFieldName, $table, $row)) {
/** @var $fileRepository \TYPO3\CMS\Core\Resource\FileRepository */
$fileRepository = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\FileRepository');
if ($table === 'pages' && isset($row['_LOCALIZED_UID']) && intval($row['sys_language_uid']) > 0) {
$table = 'pages_language_overlay';
}
$files = $fileRepository->findByRelation($table, $migrateFieldName, isset($row['_LOCALIZED_UID']) ? intval($row['_LOCALIZED_UID']) : intval($row['uid']));
$fileFieldContents = array(
'paths' => array(),
'titleTexts' => array(),
'captions' => array(),
'links' => array(),
'alternativeTexts' => array(),
$migrateFieldName . '_fileUids' => array(),
$migrateFieldName . '_fileReferenceUids' => array(),
);
$oldFieldNames[$migrateFieldName . '_fileUids'] = $migrateFieldName . '_fileUids';
$oldFieldNames[$migrateFieldName . '_fileReferenceUids'] = $migrateFieldName . '_fileReferenceUids';
// Only consider records of table pages and tt_content
if ($table !== 'pages' && $table !== 'tt_content') {
return;
}
// Use cached result, if available
if (!empty(static::$migrationCache[$table][$row['uid']])) {
$row = static::$migrationCache[$table][$row['uid']];
return;
}
// Process fields and execute "migration"
if (!isset(static::$migrationCache[$table])) {
static::$migrationCache[$table] = array();
}
foreach (static::$migrateFields[$table] as $migrateFieldName => $oldFieldNames) {
if (isset($row[$migrateFieldName]) && self::fieldIsInType($migrateFieldName, $table, $row)) {
/** @var $fileRepository \TYPO3\CMS\Core\Resource\FileRepository */
$fileRepository = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\FileRepository');
if ($table === 'pages' && isset($row['_LOCALIZED_UID']) && intval($row['sys_language_uid']) > 0) {
$table = 'pages_language_overlay';
}
$files = $fileRepository->findByRelation($table, $migrateFieldName, isset($row['_LOCALIZED_UID']) ? intval($row['_LOCALIZED_UID']) : intval($row['uid']));
$fileFieldContents = array(
'paths' => array(),
'titleTexts' => array(),
'captions' => array(),
'links' => array(),
'alternativeTexts' => array(),
$migrateFieldName . '_fileUids' => array(),
$migrateFieldName . '_fileReferenceUids' => array(),
);
$oldFieldNames[$migrateFieldName . '_fileUids'] = $migrateFieldName . '_fileUids';
$oldFieldNames[$migrateFieldName . '_fileReferenceUids'] = $migrateFieldName . '_fileReferenceUids';
foreach ($files as $file) {
/** @var $file \TYPO3\CMS\Core\Resource\FileReference */
$fileProperties = $file->getProperties();
$fileFieldContents['paths'][] = '../../' . $file->getPublicUrl();
$fileFieldContents['titleTexts'][] = $fileProperties['title'];
$fileFieldContents['captions'][] = $fileProperties['description'];
$fileFieldContents['links'][] = $fileProperties['link'];
$fileFieldContents['alternativeTexts'][] = $fileProperties['alternative'];
$fileFieldContents[$migrateFieldName . '_fileUids'][] = $file->getOriginalFile()->getUid();
$fileFieldContents[$migrateFieldName . '_fileReferenceUids'][] = $file->getUid();
foreach ($files as $file) {
/** @var $file \TYPO3\CMS\Core\Resource\FileReference */
$fileProperties = $file->getProperties();
$fileFieldContents['paths'][] = '../../' . $file->getPublicUrl();
$fileFieldContents['titleTexts'][] = $fileProperties['title'];
$fileFieldContents['captions'][] = $fileProperties['description'];
$fileFieldContents['links'][] = $fileProperties['link'];
$fileFieldContents['alternativeTexts'][] = $fileProperties['alternative'];
$fileFieldContents[$migrateFieldName . '_fileUids'][] = $file->getOriginalFile()->getUid();
$fileFieldContents[$migrateFieldName . '_fileReferenceUids'][] = $file->getUid();
}
foreach ($oldFieldNames as $oldFieldType => $oldFieldName) {
if ($oldFieldType === '__typeMatch') {
continue;
}
foreach ($oldFieldNames as $oldFieldType => $oldFieldName) {
if ($oldFieldType === '__typeMatch') {
continue;
}
if ($oldFieldType === 'paths' || substr($oldFieldType, -9) == '_fileUids' || substr($oldFieldType, -18) == '_fileReferenceUids') {
// For paths and uids, make comma separated list
$fieldContents = implode(',', $fileFieldContents[$oldFieldType]);
} else {
// For all other fields, separate by newline
$fieldContents = implode(chr(10), $fileFieldContents[$oldFieldType]);
}
$row[$oldFieldName] = $fieldContents;
if ($oldFieldType === 'paths' || substr($oldFieldType, -9) == '_fileUids' || substr($oldFieldType, -18) == '_fileReferenceUids') {
// For paths and uids, make comma separated list
$fieldContents = implode(',', $fileFieldContents[$oldFieldType]);
} else {
// For all other fields, separate by newline
$fieldContents = implode(chr(10), $fileFieldContents[$oldFieldType]);
}
$row[$oldFieldName] = $fieldContents;
}
}
}
$row['_MIGRATED'] = TRUE;
static::$migrationCache[$table][$row['uid']] = $row;
}
/**
* Check if fieldis in type
* Checks whether field is in type
*
* @param string $fieldName
* @param string $table
......@@ -145,7 +165,10 @@ class FrontendContentAdapterService {
if (empty($fieldConfiguration['__typeMatch'])) {
return TRUE;
} else {
return in_array($row[$fieldConfiguration['__typeMatch']['typeField']], $fieldConfiguration['__typeMatch']['types']);
return in_array(
$row[$fieldConfiguration['__typeMatch']['typeField']],
$fieldConfiguration['__typeMatch']['types']
);
}
}
}
......@@ -37,10 +37,16 @@ class FrontendContentAdapterServiceTest extends \TYPO3\CMS\Core\Tests\UnitTestCa
*/
protected $singletonInstances = array();
/**
* @var string
*/
protected $accessibleFixtureName;
/**
* Saving the singletons
*/
public function setUp() {
$this->accessibleFixtureName = $this->buildAccessibleProxy('TYPO3\\CMS\\Core\\Resource\\Service\\FrontendContentAdapterService');
$this->singletonInstances = \TYPO3\CMS\Core\Utility\GeneralUtility::getSingletonInstances();
$this->fileRepositoryMock = $this->getMock('TYPO3\\CMS\\Core\\Resource\\FileRepository');
\TYPO3\CMS\Core\Utility\GeneralUtility::setSingletonInstance('TYPO3\\CMS\\Core\\Resource\\FileRepository', $this->fileRepositoryMock);
......@@ -50,10 +56,33 @@ class FrontendContentAdapterServiceTest extends \TYPO3\CMS\Core\Tests\UnitTestCa
* Restoring the singletons
*/
public function tearDown() {
call_user_func_array($this->accessibleFixtureName . '::_setStatic', array('migrationCache', array()));
\TYPO3\CMS\Core\Utility\GeneralUtility::resetSingletonInstances($this->singletonInstances);
unset($this->fileRepositoryMock);
}
/**
* @test
*/
public function customTableIsNotConsidered() {
$dbRow = array(
'uid' => uniqid(),
);
/* @see \TYPO3\CMS\Core\Resource\Service\FrontendContentAdapterService::modifyDBRow */
$result = call_user_func_array($this->accessibleFixtureName . '::modifyDBRow', array(&$dbRow, uniqid('tx_testtable')));
$this->assertNull($result);
}
/**
* @test
*/
public function recordWithoutUidIsNotConsidered() {
$dbRow = array();
/* @see \TYPO3\CMS\Core\Resource\Service\FrontendContentAdapterService::modifyDBRow */
$result = call_user_func_array($this->accessibleFixtureName . '::modifyDBRow', array(&$dbRow, 'tt_content'));
$this->assertNull($result);
}
/**
* @test
*/
......@@ -62,14 +91,47 @@ class FrontendContentAdapterServiceTest extends \TYPO3\CMS\Core\Tests\UnitTestCa
->method('findByRelation')
->will($this->returnValue(array()));
$dbRow = array(
'uid' => uniqid(),
'CType' => 'image',
'image' => '1'
);
\TYPO3\CMS\Core\Resource\Service\FrontendContentAdapterService::modifyDBRow($dbRow, 'tt_content');
/* @see \TYPO3\CMS\Core\Resource\Service\FrontendContentAdapterService::modifyDBRow */
call_user_func_array($this->accessibleFixtureName . '::modifyDBRow', array(&$dbRow, 'tt_content'));
$this->assertEmpty($dbRow['image']);
}
/**
* @test
*/
public function processedRecordsAreCached() {
// Asserting that this is only called once,
// since second call shall be delivered from cache
$this->fileRepositoryMock->expects($this->once())
->method('findByRelation')
->will($this->returnValue(array()));
$testUid = uniqid();
$dbRow = array(
'uid' => $testUid,
'CType' => 'image',
'image' => '1',
);
/* @see \TYPO3\CMS\Core\Resource\Service\FrontendContentAdapterService::modifyDBRow */
call_user_func_array($this->accessibleFixtureName . '::modifyDBRow', array(&$dbRow, 'tt_content'));
$dbRow = array(
'uid' => $testUid,
'CType' => 'image',
'image' => '1',
);
/* @see \TYPO3\CMS\Core\Resource\Service\FrontendContentAdapterService::modifyDBRow */
call_user_func_array($this->accessibleFixtureName . '::modifyDBRow', array(&$dbRow, 'tt_content'));
}
/**
* @test
*/
......@@ -85,15 +147,17 @@ class FrontendContentAdapterServiceTest extends \TYPO3\CMS\Core\Tests\UnitTestCa
->method('findByRelation')
->will($this->returnValue(array($fileReference)));
$dbRow = array(
'uid' => uniqid(),
'CType' => 'image',
'image' => '1'
);
\TYPO3\CMS\Core\Resource\Service\FrontendContentAdapterService::modifyDBRow($dbRow, 'tt_content');
/* @see \TYPO3\CMS\Core\Resource\Service\FrontendContentAdapterService::modifyDBRow */
call_user_func_array($this->accessibleFixtureName . '::modifyDBRow', array(&$dbRow, 'tt_content'));
$this->assertSame('../../path/to/file', $dbRow['image']);
}
public function conteRowsOfDifferentTypesDataProvider() {
public function contentRowsOfDifferentTypesDataProvider() {
$filePropertiesImage = array(
'title' => 'Image',
'description' => 'IMAGE DESCRIPTION',
......@@ -107,6 +171,7 @@ class FrontendContentAdapterServiceTest extends \TYPO3\CMS\Core\Tests\UnitTestCa
return array(
'Image Element' => array(
array(
'uid' => uniqid(),
'CType' => 'image',
'image' => '',
'media' => '',
......@@ -116,6 +181,7 @@ class FrontendContentAdapterServiceTest extends \TYPO3\CMS\Core\Tests\UnitTestCa
),
'Textpic Element' => array(
array(
'uid' => uniqid(),
'CType' => 'textpic',
'image' => '',
'media' => '',
......@@ -125,6 +191,7 @@ class FrontendContentAdapterServiceTest extends \TYPO3\CMS\Core\Tests\UnitTestCa
),
'Uploads Element' => array(
array(
'uid' => uniqid(),
'CType' => 'uploads',
'image' => '',
'media' => '',
......@@ -137,7 +204,7 @@ class FrontendContentAdapterServiceTest extends \TYPO3\CMS\Core\Tests\UnitTestCa
/**
* @test
* @dataProvider conteRowsOfDifferentTypesDataProvider
* @dataProvider contentRowsOfDifferentTypesDataProvider
*/
public function migrationOfLegacyFieldsIsOnlyDoneWhenRelationFieldIsVisibleInType($dbRow, $expectedCaption, $fileProperties) {
$fileReference = $this->getMock('TYPO3\\CMS\\Core\\Resource\\FileReference', array(), array(), '', FALSE);
......@@ -154,7 +221,8 @@ class FrontendContentAdapterServiceTest extends \TYPO3\CMS\Core\Tests\UnitTestCa
->method('findByRelation')
->will($this->returnValue(array($fileReference)));
\TYPO3\CMS\Core\Resource\Service\FrontendContentAdapterService::modifyDBRow($dbRow, 'tt_content');
/* @see \TYPO3\CMS\Core\Resource\Service\FrontendContentAdapterService::modifyDBRow */
call_user_func_array($this->accessibleFixtureName . '::modifyDBRow', array(&$dbRow, 'tt_content'));
$this->assertSame($expectedCaption, $dbRow['imagecaption']);
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment