Typo3 10.4 - How to add FAL image to my extension - typo3

I'm a new Typo3 user and I'm trying to add images to my extension with using FAL.
I found some old docs and posts on stackoverflow to help me for adding FAL to add images, I'm using 10.4 version.
I configured my TCA, my locallang, and the model but the field doesn't appear in backend, the sources used were quite old I don't know if I missed something to make it works
I added it in my Configuration/TCA like that :
'image' => [
'exclude' => true,
'label' => 'LLL:EXT:myextension/Resources/Private/Language/locallang_db.xlf:tx_myextension_domain_model_atelier.image',
'config' =>
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig(
'image',
[
'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_TEXT => [
'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'
],
\TYPO3\CMS\Core\Resource\File::FILETYPE_AUDIO => [
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette,
--palette--;;filePalette'
],
\TYPO3\CMS\Core\Resource\File::FILETYPE_VIDEO => [
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette,
--palette--;;filePalette'
],
\TYPO3\CMS\Core\Resource\File::FILETYPE_APPLICATION => [
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette,
--palette--;;filePalette'
]
],
'foreign_match_fields' => [
'fieldname' => 'image',
'tablenames' => 'tx_myextension_domain_model_atelier',
'table_local' => 'sys_file',
],
'maxitems' => 3
],
$GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext']
),
],
Language/locallang.xlf :
<trans-unit id="tx_myextension_domain_model_atelier.image">
<source>image</source>
</trans-unit>
Model :
/**
* #var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Extbase\Domain\Model\FileReference>
*/
protected $image;
/**
* #return \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Extbase\Domain\Model\FileReference> $image
*/
public function getImage()
{
return $this->image;
}
/**
* #param \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Extbase\Domain\Model\FileReference> $image
* #return void
*/
public function setImage(\TYPO3\CMS\Extbase\Persistence\ObjectStorage $image)
{
$this->image = $image;
}
can someone tell me if i missed something, or if i made a mistake? thank you

The first thing i can see that you are missing is whenever you use ObjectStorage, you have to initialise it first. That means, in your model, you have to do something like this:
/**
* Initializes all ObjectStorage properties when model is reconstructed from DB (where __construct is not called)
* Do not modify this method!
* It will be rewritten on each save in the extension builder
* You may modify the constructor of this class instead
*/
public function initializeObject()
{
$this->image = $this->image ?? new ObjectStorage();
}
The second thing you have to do in order to display it in your Backend, you have to add it on the types. The types are responsible for the backend view, and you can configure the order which your columns, tabs and palettes are displayed.
return [
'ctrl' => [...],
'types' => [
'0' => [
'showitem' => 'hidden, image, sys_language_uid, l10n_parent, l10n_diffsource'
],
],
'columns' => [...]
];

Related

How to create a TCA field for uploading a PDF file to SQL `mediumblob` in TYPO3 10.4

I am trying to find solution, that will allow user to upload PDF file via TCA. Uploaded file musn't create relation with sys_file_reference.
My current code in TCA:
'pdf_data' => [
'exclude' => true,
'label' => 'PDF file',
'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig(
'pdf_file',
[
'appearance' => [
'createNewRelationLinkTitle' => 'Add PDF file',
],
'maxitems' => 1,
'minitems' => 0,
'overrideChildTca' => [
'types' => [
'0' => [
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette,
--palette--;;filePalette'
],
\TYPO3\CMS\Core\Resource\File::FILETYPE_TEXT => [
'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'
],
\TYPO3\CMS\Core\Resource\File::FILETYPE_AUDIO => [
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette,
--palette--;;filePalette'
],
\TYPO3\CMS\Core\Resource\File::FILETYPE_VIDEO => [
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette,
--palette--;;filePalette'
],
\TYPO3\CMS\Core\Resource\File::FILETYPE_APPLICATION => [
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette,
--palette--;;filePalette'
],
],
],
'filter' => [
'0' => [
'parameters' => [
'allowedFileExtensions' => 'pdf'
]
]
],
'default' => null,
],
'pdf'
),
]
],
Although Thomas already stated, that it is very uncommon and you really need a good reason to store PDF files in a database, you could still try to provide your own form engine rendering via TCA column type user
https://docs.typo3.org/m/typo3/reference-tca/10.4/en-us/ColumnsConfig/Type/User.html
Just make sure to provide a render type, that will return basic information about the stored data, so that BE users will get a convenient user interface to deal with the files.
Additionally you might want to deal with the data while it gets stored, so providing methods for the DataHandler would be necessary too.
https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ApiOverview/Typo3CoreEngine/Introduction/Index.html

Access translator in Shopware 6 Plugin

I am developing my first Shopware 6 plugin and was wondering how to access snippets in the Plugin class. I checked the Developer Guide but could not make it work.
I want to use the plugin translation as label in customField select options.
myfirstplugin.en-GB.json
{
"myfirstplugin": {
"my_custom_field_option_1": "Option 1",
"my_custom_field_option_2": "Option 2",
}
}
MyFirstPlugin.php
class MyFirstPlugin extends Plugin
{
// ....
private function createCustomFields(Context $context): void
{
if ($this->customFieldSetExists($context)) {
return;
}
$customFieldSetRepository = $this->container->get('custom_field_set.repository');
$customFieldSetRepository->create([
[
'id' => '294865e5c81b434d8349db9ea6b4e135',
'name' => 'my_custom_field_set',
'customFields' => [
[
'name' => 'my_custom_field',
'type' => CustomFieldTypes::SELECT,
'config' => [
'label' => [ 'en-GB' => 'My custom field'],
'options' => [
[
'value' => '294865e5c81b434d8349db9ea6b4e487',
// Access my_custom_field_option_1 of snippet myfirstplugin.en-GB.json
'label' => 'my_custom_field_option_1',
],
[
'value' => '1ce5abe719a04346930c7e43514ed4f1',
// Access my_custom_field_option_2 of snippet myfirstplugin.en-GB.json
'label' => 'my_custom_field_option_2',
],
],
'customFieldType' => 'select',
'componentName' => 'sw-single-select',
'customFieldPosition' => 1,
],
],
]
],
], $context);
}
}
You can inject an argument of type Translator to your service
in services.xml
<argument type="service" id="translator"/>
in your service
use Shopware\Core\Framework\Adapter\Translation\Translator;
/**
* #var Translator
*/
private $translator;
public function __construct($translator)
{
$this->translator = $translator;
}
then down the way you can use this pretty much the same as in a twig template:
$translated = $this->translator
->trans(
'myfirstplugin.product.detail.294865e5c81b434d8349db9ea6b4e487');
I think you can use the snippet repository and search the label as you want in the Plugin class like
$sRepo = $this->container->get('snippet.repository');
$labels = $sRepo->search((new Criteria())
->addFilter(
new MultiFilter(
MultiFilter::CONNECTION_OR,
[
new ContainsFilter('translationKey', 'my_custom_field_option_1'),
new ContainsFilter('translationKey', 'my_custom_field_option_2')
]
)
), $context)->getElements();
When you create the custom field you don't have to reference a translation snippet. Instead you can just provide the translations in the payload directly.
'config' => [
'label' => ['en-GB' => 'Label english', 'de-DE' => 'Label german'],
'type' => CustomFieldTypes::SELECT,
'options' => [
[
'value' => '294865e5c81b434d8349db9ea6b4e487',
'label' => ['en-GB' => 'Option english', 'de-DE' => 'Option german'],
],
[
'value' => '1ce5abe719a04346930c7e43514ed4f1',
'label' => ['en-GB' => 'Option english', 'de-DE' => 'Option german'],
],
],
],

TYPO3: add maxitems = 1 to an image selection for a backend module

I use the following code to make an image selection available in the backend:
(TYPO3 docs - inline - File Abstraction Layer)
'image' => [
'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.images',
'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig(
'image',
[
'appearance' => [
'createNewRelationLinkTitle' => 'LLL:EXT:cms/locallang_ttc.xlf:images.addFileReference'
],
// custom configuration for displaying fields in the overlay/reference table
// to use the image overlay palette instead of the basic overlay palette
'overrideChildTca' => [
'types' => [
'0' => [
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette,
--palette--;;filePalette'
],
\TYPO3\CMS\Core\Resource\File::FILETYPE_TEXT => [
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette,
--palette--;;filePalette'
],
],
],
],
$GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext']
),
],
I want to limit the selection to 1 item which should be:
TYPO3 dosc - maxitems option
image => [
'config' => [
'maxitems' => 1,
],
],
I cannot find how to add that ... all I tried gives errors
Sometimes, you just have to find the matching part of documentation...
File abstraction layer (FAL)
The API call is \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig(). The first argument is the name of the current field, the second argument is an override configuration array, (...)
So it should do with overriding a part of the generated configuration by:
'image' => [
'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.images',
'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig(
'image',
[
'maxitems' => 1
]
)
]

Add custom image field to tt_content

how can I add a custom image field to tt_content correctly ? I made the first part with Overrides/tt_content.php and in ext_tables.sql, and thus I can see the new field in the backend, and in the frontend context I get data.tx_pnbase_icon.
But it is not possible for me to choose an image in the backend, nor will it be saved, even if the popup with the file list works.
Do I have to tell tt_content to connect the field with sys_file_reference (in Typoscript) ?
Or, do I even have to extend the Content model ?
Field in backend
<?php
$temporaryColumn = array(
'tx_pnbase_icon' => [
'label' => 'Icon für Inhalt',
'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig(
'tx_pnbase_icon',
[
'appearance' => [
'createNewRelationLinkTitle' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:images.addFilegallery'
],
'foreign_types' => [
'0' => [
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_gallery.imageoverlayPalette;imageoverlayPalette,
--palette--;;filePalette'
],
\TYPO3\CMS\Core\Resource\File::FILETYPE_TEXT => [
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_gallery.imageoverlayPalette;imageoverlayPalette,
--palette--;;filePalette'
],
\TYPO3\CMS\Core\Resource\File::FILETYPE_IMAGE => [
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_gallery.imageoverlayPalette;imageoverlayPalette,
--palette--;;filePalette'
],
\TYPO3\CMS\Core\Resource\File::FILETYPE_AUDIO => [
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_gallery.imageoverlayPalette;imageoverlayPalette,
--palette--;;filePalette'
],
\TYPO3\CMS\Core\Resource\File::FILETYPE_VIDEO => [
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_gallery.imageoverlayPalette;imageoverlayPalette,
--palette--;;filePalette'
],
\TYPO3\CMS\Core\Resource\File::FILETYPE_APPLICATION => [
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_gallery.imageoverlayPalette;imageoverlayPalette,
--palette--;;filePalette'
]
],
'foreign_match_fields' => [
'fieldname' => 'tx_pnbase_icon',
'tablenames' => 'tt_content',
'table_local' => 'sys_file',
],
'maxitems' => 1
],
$GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext']
),
],
);
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTCAcolumns(
'tt_content',
$temporaryColumn
);
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addFieldsToPalette(
'tt_content',
'appearanceLinks', // layout
'tx_pnbase_icon',
'after:layout' // 'after:' layout
);
In ext_tables.sql
CREATE TABLE tt_content (
tx_pnbase_icon int(11) unsigned NOT NULL default '0'
);
TYPO3 by default will only store the number of relations inside the columns.
In case you are working with TypoScript FLUIDTEMPLATE, you can use data processing to resolve file relations. See https://docs.typo3.org/m/typo3/reference-typoscript/10.4/en-us/ContentObjects/Fluidtemplate/Index.html#dataprocessing for an overview of the concept, and https://github.com/TYPO3/TYPO3.CMS/blob/10.4/typo3/sysext/frontend/Classes/DataProcessing/FilesProcessor.php for the concrete processor to use. All processors have an example usage in their PHPDoc.
In case you use plain TypoScript, you should be able to use the FILES cObject: https://docs.typo3.org/m/typo3/reference-typoscript/master/en-us/ContentObjects/Files/Index.html#cobj-files.
https://docs.typo3.org/m/typo3/reference-coreapi/10.4/en-us/ApiOverview/Fal/UsingFal/Frontend.html contains the whole overview of how to retrieve files.

TYPO3 how to redeclare FrontendUser class

I have TYPO3 7.6.18. I need to redeclare TYPO3\CMS\Extbase\Domain\Model\FrontendUser class and extend it with my new class Fhk\Feusersplus\Domain\Model\FrontendUser. I need that TYPO3 use my FrontEnd class. (I need add new upload field)
I tried:
ext_typoscript_setup.txt:
config.tx_extbase{
persistence{
classes{
In2code\Femanager\Domain\Model\User {
subclasses {
0 = Fhk\Feusersplus\Domain\Model\User
}
}
TYPO3\CMS\Extbase\Domain\Model\FrontendUser{
subclasses {
0 = Fhk\Feusersplus\Domain\Model\FrontendUser
}
}
Fhk\Feusersplus\Domain\Model\User {
mapping {
tableName = fe_users
recordType = 0
}
}
}
}
objects {
In2code\Femanager\Controller\NewController.className = Fhk\Feusersplus\Controller\NewController
In2code\Femanager\Controller\EditController.className = Fhk\Feusersplus\Controller\EditController
In2code\Femanager\Controller\UserController.className = Fhk\Feusersplus\Controller\UserController
#Kennziffer\KeQuestionnaire\Domain\Repository\ResultRepository.className = Fhk\Feusersplus\Domain\Repository\ResultRepository
}
}
ext_localconf.php
$GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects']['TYPO3\CMS\Extbase\Domain\Model\FrontendUser'] = array(
'className' => 'Fhk\Feusersplus\Domain\Model\FrontendUser'
);
But I have error:
Exception while property mapping at property path "": Property "backgroundimage" was not found in target object of type "Fhk\Feusersplus\Domain\Model\User".
my file ext:Configuration/TCA/Overrides/fe_users.php
$tmp_feusersplus_columns = array(
'backgroundimage' => [
'exclude' => 1,
'label' => 'Background image',
'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig(
'image', [
'appearance' => [
'createNewRelationLinkTitle' => 'LLL:EXT:cms/locallang_ttc.xlf:images.addFileReference'
],
'maxitems' => 1,
// custom configuration for displaying fields in the overlay/reference table
// to use the imageoverlayPalette instead of the basicoverlayPalette
'foreign_match_fields' => [
'fieldname' => 'backgroundimage',
'tablenames' => 'fe_users',
'table_local' => 'sys_file',
],
'foreign_types' => [
'0' => [
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette,
--palette--;;filePalette'
],
\TYPO3\CMS\Core\Resource\File::FILETYPE_TEXT => [
'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'
],
\TYPO3\CMS\Core\Resource\File::FILETYPE_AUDIO => [
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette,
--palette--;;filePalette'
],
\TYPO3\CMS\Core\Resource\File::FILETYPE_VIDEO => [
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette,
--palette--;;filePalette'
],
\TYPO3\CMS\Core\Resource\File::FILETYPE_APPLICATION => [
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette,
--palette--;;filePalette'
]
]
], $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'])
],
);
And yes, I extend ext_tables with backgroundimage field
It's seems that TYPO3 not use my new FrontendUser class.
Help me please anybody!
I don't think that there is a Problem with DB or TCA, most likely the property is just missing in your model Property "backgroundimage" was not found:
protected $backgroundimage = null;
public function getBackgroundimage()
{
return $this->backgroundimage;
}