Where to influence in which languages an extbase record can be translated? - typo3

In a custom built TYPO3 extension, records are only available in language -1 in the backend. That was specified as such, but should now be changed so records can be translated.
Something is missing. I thought this would be in TCA, but the definitions look quite normal:
'columns' => [
'sys_language_uid' => [
'exclude' => true,
'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.language',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'special' => 'languages',
'items' => [
[
'LLL:EXT:lang/locallang_general.xlf:LGL.allLanguages',
-1,
'flags-multiple'
]
],
'default' => 0,
],
],
'l10n_parent' => [
'displayCond' => 'FIELD:sys_language_uid:>:0',
'exclude' => true,
'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.l18n_parent',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'items' => [
['', 0],
],
'foreign_table' => 'tx_myext_domain_model_item',
'foreign_table_where' => 'AND tx_myext_domain_model_item.pid=###CURRENT_PID### AND tx_myext_domain_model_item.sys_language_uid IN (-1,0)',
],
],
Also, when I change TCA, for example change config as such:
'config' => array(
'type' => 'select',
'renderType' => 'selectSingle',
'foreign_table' => 'sys_language',
'foreign_table_where' => 'ORDER BY sys_language.title',
'items' => array(
array('LLL:EXT:lang/locallang_general.xlf:LGL.allLanguages', -1),
array('LLL:EXT:lang/locallang_general.xlf:LGL.default_value', 0)
),
),
It's still the same: only language -1 (ALL) is selectable.
Of course, the sysfolder those records are on is translated in multiple languages. Also, the columns for sys_language_uid, l10n_parent and l10n_diffsource are present in the database.
Are the other languages maybe disabled somewhere? Where else could I look?
Or which element could be missing else to make records translateable?
Thanks for any hint.

Related

TYPO3 TCA selectMultiple config

I've an issue wit TYPO3 selectField, selectMultipleSideBySide.
I've configure the field like this:
$tmpColumns = [
'tx_tcademo_list' => [
'label' => 'Items',
'config' => [
'type' => 'select',
'renderType' => 'selectMultipleSideBySide',
'foreign_table' => 'tx_tcademo_domain_model_item',
'MM' => 'tx_tcademo_record_item_mm',
'MM_hasUidField' => true,
'MM_match_fields' => [
'tablenames' => 'fe_users',
'fieldnames' => 'tx_tcademo_items',
],
'minitems' => 0,
'maxitems' => 99999,
],
],
];
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTCAcolumns('fe_users', $tmpColumns);
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addToAllTCAtypes('fe_users', 'tx_tcademo_list');
Issue is:
The field is added to fe_users correctly, and items can be selected as expected, and they're saved to db MM relation, but when form is redrawn, the selected items are not marked as selected, and will be overwritten with next save.
Link to extension which demonstrates the issue:
TCA Demo extension

Problem with file upload TCA after upgrading to TYPO3 10

On typo3v9 i had working file upload field with this TCA configuration:
'image' => [
'exclude' => 0,
'label' => 'image upload',
'config' => [
'type' => 'group',
'internal_type' => 'db',
'uploadfolder' => 'uploads/folder',
'show_thumbs' => 1,
'size' => 5,
'allowed' => $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'],
'disallowed' => '',
],
],
i get this result:
but after migration to typo3v10 it does not work properly and give this result:
Someone have working solution for single file upload field?
I guess you mean internal_type=file ? That's deprecated. Here an example for image upload. However you can allow other types here too, I am sure you can find more info on that.
'photos' => [
'exclude' => true,
'label' => 'LLL:EXT:xxx/Resources/Private/Language/locallang_db.xlf:tx_xxx_domain_model_activity.photos',
'config' =>
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig(
'photos',
[
'appearance' => [
'createNewRelationLinkTitle' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:images.addFileReference'
],
'foreign_types' => [
'0' => [
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette,
--palette--;;filePalette'
],
\TYPO3\CMS\Core\Resource\File::FILETYPE_IMAGE => [
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette,
--palette--;;filePalette'
]
],
'maxitems' => 30
],
$GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext']
),
],

ZF2 Route multiple strings to the same controller?

I want to configure my Zf2 application in such a way that multiple strings route to the same controller. For example www.mysite.com/this and www.mysite.com/that both route to the same controller and have this and that available to capture with $this->params. How would I accomplish something like this? Would I need 2 separate route declarations?
'directory' => [
'type' => 'Zend\Mvc\Router\Http\Literal',
'options' => [
'route' => '/string1 || /string2 || /string3',
'defaults' => [
'controller' => 'Application\Controller\MyController',
'action' => 'index'
],
],
]
Easiest solution IMO, is:
'varcatcher' => [
'type' => 'Segment',
'options' => [
'route' => '[/[:tail]]',
'defaults' => [
'controller' => '\Application\Controller\Index',
'action' => 'catch',
'module' => 'Application',
],
'constraints' => [
'tail' => '[a-zA-z0-9_-]*'
],
],
'may_terminate' => true,
],
Then deal with it in your action:
public function catchAction(){
die( $this->params()->fromRoute('tail') );
}
Because ZF2 routes are LIFO. It's probably optimal to deal with it by inserting it first, and handling whatever cases you need to 'catch'.
The mention of LIFO, is because if you define routes 'after' in the router array, those will precede the catch-all, which seems to be of benefit if I've read your question right.
Cheers!
Alex
You could use a Zend\Mvc\Router\Http\Regex route type, instead of a Literal one and do something like
'directory' => [
'type' => 'Zend\Mvc\Router\Http\Regex',
'options' => [
'route' => '/string(?<id>[0-9]+)',
'defaults' => [
'controller' => 'Application\Controller\MyController',
'action' => 'index'
],
],
]
As of definition of Literal route create 3 routes:
'directory1' => [
'type' => 'Zend\Mvc\Router\Http\Literal',
'options' => [
'route' => '/string1',
'defaults' => [
'controller' => 'Application\Controller\MyController',
'action' => 'index',
],
],
],
'directory2' => [
'type' => 'Zend\Mvc\Router\Http\Literal',
'options' => [
'route' => '/string2',
'defaults' => [
'controller' => 'Application\Controller\MyController',
'action' => 'index',
],
],
],
'directory3' => [
'type' => 'Zend\Mvc\Router\Http\Literal',
'options' => [
'route' => '/string3',
'defaults' => [
'controller' => 'Application\Controller\MyController',
'action' => 'index',
],
],
],

ZF 2.4 File Validator Required False Doesn't Work

Today I updated to ZF 2.4 to use float validator but unfortunately i realized that my file upload form field gives unexpected error messages.
Here is my form object
$this->add([
'name' => 'profileimage',
'type' => '\Zend\Form\Element\File',
'attributes' => [
'id' => 'profileimage',
'class' => 'styled',
],
]
);
And Here is my validator
$inputFilter->add([
'name' => 'profileimage',
'required' => false,
'allow_empty' => true,
'priority' => 300,
'filters' => [
['name' => 'StripTags'],
['name' => 'StringTrim'],
],
'validators' => [
[
'name' => '\Zend\Validator\File\IsImage',
],
[
'name' => '\Zend\Validator\File\UploadFile',
],
[
'name' => '\Zend\Validator\File\ImageSize',
'options' => [
'minWidth' => 300,
'minHeight' => 300,
]
],
[
'name' => '\Zend\Validator\File\Size',
'options' => [
'max' => '20MB',
]
],
]
]);
As you see the image upload field is not required and may be empty. But in my form I get these errors:
array (size=1)
'profileimage' =>
array (size=4)
'fileIsImageNotReadable' => string 'File is not readable or does not exist' (length=38)
'fileUploadFileErrorNoFile' => string 'File was not uploaded' (length=21)
'fileImageSizeNotReadable' => string 'File is not readable or does not exist' (length=38)
'fileSizeNotFound' => string 'File is not readable or does not exist' (length=38)
How can I handle this issue? I need to this field to be optional.
change your filter
$inputFilter->add([
'name' => 'profileimage',
'type' => '\Zend\InputFilter\FileInput',
'required' => false,
'allow_empty' => true,
'priority' => 300,
'filters' => [
['name' => 'StripTags'],
['name' => 'StringTrim'],
],
'validators' => [
[
'name' => '\Zend\Validator\File\IsImage',
],
[
'name' => '\Zend\Validator\File\UploadFile',
],
[
'name' => '\Zend\Validator\File\ImageSize',
'options' => [
'minWidth' => 300,
'minHeight' => 300,
]
],
[
'name' => '\Zend\Validator\File\Size',
'options' => [
'max' => '20MB',
]
],
]
]);
read about it here: http://framework.zend.com/manual/current/en/modules/zend.input-filter.file-input.html

TYPO3 object storage is empty

i wanna ad a relation from one model to a nother.
/**
* #var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
* #inject
*/
protected $objectManager;
/**
* action create
*
* #param \ReRe\Rere\Domain\Model\Modul $newModul
* #return void
*/
public function createAction(\ReRe\Rere\Domain\Model\Modul $newModul) {
$this->addFlashMessage('The object was created. Please be aware that this action is publicly accessible unless you implement an access check. See Wiki', '', \TYPO3\CMS\Core\Messaging\AbstractMessage::ERROR);
$this->modulRepository->add($newModul);
// Erzeugt ein Leeres Fach
$fachHelper = new \ReRe\Rere\Domain\Model\Fach();
$fach = $this->objectManager->create('\ReRe\Rere\Domain\Model\Fach');
// Fach Werte setzen
$fach->setFachname($this->request->getArgument('fachname'));
$fach->setFachnr($this->request->getArgument('fachnummer'));
$fach->setPruefer($this->request->getArgument('pruefer'));
$fach->setNotenschema($this->request->getArgument('notenschema'));
// Fach einem Modul zuordnen
$fach->setModulnr($newModul->getModulnr());
//$request = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance("\ReRe\Rere\Domain\Model\Fach");
//\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($newModul);
// Fach speichern
$this->fachRepository->add($fach);
$newModul->addFach($fach);
$this->redirect('list');
}
in database in modul the relationcounter will increased ...
DB looks like this:
but if I want to render the view like this:
<f:for each="{moduls}" as="modul">
{modul.modulname}
<f:for each="{modul.fach}" as="fach">
{fach.fachname}
no fach objects were printed ..
if I do <f:debug> of modul i got this:
Here The TCA-Configs:
Modul:
if (!defined('TYPO3_MODE')) {
die('Access denied.');
}
$GLOBALS['TCA']['tx_rere_domain_model_modul'] = array(
'ctrl' => $GLOBALS['TCA']['tx_rere_domain_model_modul']['ctrl'],
'interface' => array(
'showRecordFieldList' => 'sys_language_uid, l10n_parent, l10n_diffsource, hidden, modulnr, modulname, gueltigkeitszeitraum, fach',
),
'types' => array(
'1' => array('showitem' => 'sys_language_uid;;;;1-1-1, l10n_parent, l10n_diffsource, hidden;;1, modulnr, modulname, gueltigkeitszeitraum, fach, --div--;LLL:EXT:cms/locallang_ttc.xlf:tabs.access, starttime, endtime'),
),
'palettes' => array(
'1' => array('showitem' => ''),
),
'columns' => array(
'sys_language_uid' => array(
'exclude' => 1,
'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.language',
'config' => array(
'type' => 'select',
'foreign_table' => 'sys_language',
'foreign_table_where' => 'ORDER BY sys_language.title',
'items' => array(
array('LLL:EXT:lang/locallang_general.xlf:LGL.allLanguages', -1),
array('LLL:EXT:lang/locallang_general.xlf:LGL.default_value', 0)
),
),
),
'l10n_parent' => array(
'displayCond' => 'FIELD:sys_language_uid:>:0',
'exclude' => 1,
'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.l18n_parent',
'config' => array(
'type' => 'select',
'items' => array(
array('', 0),
),
'foreign_table' => 'tx_rere_domain_model_modul',
'foreign_table_where' => 'AND tx_rere_domain_model_modul.pid=###CURRENT_PID### AND tx_rere_domain_model_modul.sys_language_uid IN (-1,0)',
),
),
'l10n_diffsource' => array(
'config' => array(
'type' => 'passthrough',
),
),
't3ver_label' => array(
'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.versionLabel',
'config' => array(
'type' => 'input',
'size' => 30,
'max' => 255,
)
),
'hidden' => array(
'exclude' => 1,
'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.hidden',
'config' => array(
'type' => 'check',
),
),
'starttime' => array(
'exclude' => 1,
'l10n_mode' => 'mergeIfNotBlank',
'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.starttime',
'config' => array(
'type' => 'input',
'size' => 13,
'max' => 20,
'eval' => 'datetime',
'checkbox' => 0,
'default' => 0,
'range' => array(
'lower' => mktime(0, 0, 0, date('m'), date('d'), date('Y'))
),
),
),
'endtime' => array(
'exclude' => 1,
'l10n_mode' => 'mergeIfNotBlank',
'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.endtime',
'config' => array(
'type' => 'input',
'size' => 13,
'max' => 20,
'eval' => 'datetime',
'checkbox' => 0,
'default' => 0,
'range' => array(
'lower' => mktime(0, 0, 0, date('m'), date('d'), date('Y'))
),
),
),
'modulnr' => array(
'exclude' => 1,
'label' => 'LLL:EXT:rere/Resources/Private/Language/locallang_db.xlf:tx_rere_domain_model_modul.modulnr',
'config' => array(
'type' => 'input',
'size' => 30,
'eval' => 'trim'
),
),
'modulname' => array(
'exclude' => 1,
'label' => 'LLL:EXT:rere/Resources/Private/Language/locallang_db.xlf:tx_rere_domain_model_modul.modulname',
'config' => array(
'type' => 'input',
'size' => 30,
'eval' => 'trim,required'
),
),
'gueltigkeitszeitraum' => array(
'exclude' => 1,
'label' => 'LLL:EXT:rere/Resources/Private/Language/locallang_db.xlf:tx_rere_domain_model_modul.gueltigkeitszeitraum',
'config' => array(
'type' => 'input',
'size' => 30,
'eval' => 'trim'
),
),
'fach' => array(
'exclude' => 1,
'label' => 'LLL:EXT:rere/Resources/Private/Language/locallang_db.xlf:tx_rere_domain_model_modul.fach',
'config' => array(
'type' => 'inline',
'foreign_table' => 'tx_rere_domain_model_fach',
'foreign_field' => 'modulnr',
'maxitems' => 9999,
'appearance' => array(
'collapseAll' => 0,
'levelLinksPosition' => 'top',
'showSynchronizationLink' => 1,
'showPossibleLocalizationRecords' => 1,
'showAllLocalizationLink' => 1
),
),
),
),
);
And TCA Fach
<?php
if (!defined ('TYPO3_MODE')) {
die ('Access denied.');
}
$GLOBALS['TCA']['tx_rere_domain_model_fach'] = array(
'ctrl' => $GLOBALS['TCA']['tx_rere_domain_model_fach']['ctrl'],
'interface' => array(
'showRecordFieldList' => 'sys_language_uid, l10n_parent, l10n_diffsource, hidden, fachnr, fachname, pruefer, notenschema, modulnr, matrikelnr',
),
'types' => array(
'1' => array('showitem' => 'sys_language_uid;;;;1-1-1, l10n_parent, l10n_diffsource, hidden;;1, fachnr, fachname, pruefer, notenschema, modulnr, matrikelnr, --div--;LLL:EXT:cms/locallang_ttc.xlf:tabs.access, starttime, endtime'),
),
'palettes' => array(
'1' => array('showitem' => ''),
),
'columns' => array(
'sys_language_uid' => array(
'exclude' => 1,
'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.language',
'config' => array(
'type' => 'select',
'foreign_table' => 'sys_language',
'foreign_table_where' => 'ORDER BY sys_language.title',
'items' => array(
array('LLL:EXT:lang/locallang_general.xlf:LGL.allLanguages', -1),
array('LLL:EXT:lang/locallang_general.xlf:LGL.default_value', 0)
),
),
),
'l10n_parent' => array(
'displayCond' => 'FIELD:sys_language_uid:>:0',
'exclude' => 1,
'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.l18n_parent',
'config' => array(
'type' => 'select',
'items' => array(
array('', 0),
),
'foreign_table' => 'tx_rere_domain_model_fach',
'foreign_table_where' => 'AND tx_rere_domain_model_fach.pid=###CURRENT_PID### AND tx_rere_domain_model_fach.sys_language_uid IN (-1,0)',
),
),
'l10n_diffsource' => array(
'config' => array(
'type' => 'passthrough',
),
),
't3ver_label' => array(
'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.versionLabel',
'config' => array(
'type' => 'input',
'size' => 30,
'max' => 255,
)
),
'hidden' => array(
'exclude' => 1,
'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.hidden',
'config' => array(
'type' => 'check',
),
),
'starttime' => array(
'exclude' => 1,
'l10n_mode' => 'mergeIfNotBlank',
'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.starttime',
'config' => array(
'type' => 'input',
'size' => 13,
'max' => 20,
'eval' => 'datetime',
'checkbox' => 0,
'default' => 0,
'range' => array(
'lower' => mktime(0, 0, 0, date('m'), date('d'), date('Y'))
),
),
),
'endtime' => array(
'exclude' => 1,
'l10n_mode' => 'mergeIfNotBlank',
'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.endtime',
'config' => array(
'type' => 'input',
'size' => 13,
'max' => 20,
'eval' => 'datetime',
'checkbox' => 0,
'default' => 0,
'range' => array(
'lower' => mktime(0, 0, 0, date('m'), date('d'), date('Y'))
),
),
),
'fachnr' => array(
'exclude' => 1,
'label' => 'LLL:EXT:rere/Resources/Private/Language/locallang_db.xlf:tx_rere_domain_model_fach.fachnr',
'config' => array(
'type' => 'input',
'size' => 30,
'eval' => 'trim'
),
),
'fachname' => array(
'exclude' => 1,
'label' => 'LLL:EXT:rere/Resources/Private/Language/locallang_db.xlf:tx_rere_domain_model_fach.fachname',
'config' => array(
'type' => 'input',
'size' => 30,
'eval' => 'trim,required'
),
),
'pruefer' => array(
'exclude' => 1,
'label' => 'LLL:EXT:rere/Resources/Private/Language/locallang_db.xlf:tx_rere_domain_model_fach.pruefer',
'config' => array(
'type' => 'input',
'size' => 30,
'eval' => 'trim'
),
),
'notenschema' => array(
'exclude' => 1,
'label' => 'LLL:EXT:rere/Resources/Private/Language/locallang_db.xlf:tx_rere_domain_model_fach.notenschema',
'config' => array(
'type' => 'input',
'size' => 30,
'eval' => 'trim,required'
),
),
'modulnr' => array(
'exclude' => 1,
'label' => 'LLL:EXT:rere/Resources/Private/Language/locallang_db.xlf:tx_rere_domain_model_fach.modulnr',
'config' => array(
'type' => 'input',
'size' => 30,
'eval' => 'trim,required'
),
),
'matrikelnr' => array(
'exclude' => 1,
'label' => 'LLL:EXT:rere/Resources/Private/Language/locallang_db.xlf:tx_rere_domain_model_fach.matrikelnr',
'config' => array(
'type' => 'select',
'foreign_table' => 'tx_rere_domain_model_pruefling',
'MM' => 'tx_rere_fach_pruefling_mm',
'size' => 10,
'autoSizeMax' => 30,
'maxitems' => 9999,
'multiple' => 0,
'wizards' => array(
'_PADDING' => 1,
'_VERTICAL' => 1,
'edit' => array(
'type' => 'popup',
'title' => 'Edit',
'script' => 'wizard_edit.php',
'icon' => 'edit2.gif',
'popup_onlyOpenIfSelected' => 1,
'JSopenParams' => 'height=350,width=580,status=0,menubar=0,scrollbars=1',
),
'add' => Array(
'type' => 'script',
'title' => 'Create new',
'icon' => 'add.gif',
'params' => array(
'table' => 'tx_rere_domain_model_pruefling',
'pid' => '###CURRENT_PID###',
'setValue' => 'prepend'
),
'script' => 'wizard_add.php',
),
),
),
),
'modul' => array(
'config' => array(
'type' => 'passthrough',
),
),
'note' => array(
'config' => array(
'type' => 'passthrough',
),
),
),
);
The model class looks ok and all annotations seem to be correct.
Could you please post your TCA configuration for both Modul and Fach (the relation entry for both should be enough).
Quick question, are you able to see the relations between the two objects in the backend and if so, can you see it from both sides?
Go to the BE and check with the list tool if you can see related "Fach" objects in a "Modul" object and vise versa.
Maybe the TCA relation is no set up correctly and you can only access the relation from one side.
From which side have you created the relations (Modul->Fach or Fach->Modul)?
Of course it should be working either way.
UPDATE 1
Does the column "modulnr" in your table "tx_rere_domain_model_fach" contain the correct Modul-UIDs?
-> To speed the process up, could you send me a download link to your extension? I would then install it on a test system and we will quickly find out what is wrong.
UPDATE 2
I found what is going wrong in your extension. After creating a new Modul and Fach the class \ReRe\Rere\Controller\ModulController handles the form data. In line 116
$fach->setModulnr($newModul->getModulnr());
the value for the reference, which should be the UID of the Modul is set to the Modulnr. As the reference to the foreign table is configured to be the UID, the UID of the Modul needs to be set here. Change the line to the following and it works:
$fach->setModulnr($newModul->getUid());
You will have to change this in every controller action that creates a new Fach-Modul relation. So this is only an example of what you need to do.
Sidenote
As an additional tip, you might want to take a look into the best practises on how to handle form data in Extbase.
Calls like this
$fach->setFachnr($this->request->getArgument('fachnummer'));
will work but open up a world of pain when it comes to injections, as there is no validation etc.
A very easy and quick way to set up basic validation and also make your code much more readable is to use annotations and parameters in your controller action. So instead of getting the arguments yourself, let the framework to the work for you:
/**
* action create
*
* #param \ReRe\Rere\Domain\Model\Modul $newModul
* #param string $fachname
* #param int $fachnummer
*/
public function createAction(\ReRe\Rere\Domain\Model\Modul $newModul, $fachname, $fachnummer) {
...
If you want to make a parameter optional, just give it a value in the method call:
public function createAction(\ReRe\Rere\Domain\Model\Modul $newModul, $fachname = "foo", $fachnummer="bar") {
...
As I said, this is just a tip, you might want to consider :)
Please check if the ObjectStorage is related to the correct class in your model. Sometimes the extensionbuilder does set up the ObjectStorage but messes up the annotation.
Check if the annotation for "fach" in your ReRe\Rere\Domain\Model\Modul class contains the referenced class. It should look like this:
#var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\ReRe\Rere\Domain\Model\Fach>
If assume your looks just like this, which is wrong and leads to an empty ObjectStorage in the FE:
#var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<>
See how the class the ObjectStorage contains is missing.