TYPO3 add image upload field to feuser - typo3

TYPO3 version 7.6.18. I need to extend fe_user with new field for uploading image ? How to do it? I need add this field to front-end and back-end
ext_tables.php
CREATE TABLE fe_users (
backgroundimage int(11) unsigned NOT NULL default '0'
);
User.php
class User extends \In2code\Femanager\Domain\Model\User
{
/**
* #var string
*/
protected $backgroundimage = null;
/**
* Returns the background value
*
* #return string
* #api
*/
public function getBackgroundimage()
{
return $this->backgroundimage;
}
/**
* Sets the image backgroundimage
*
* #param $backgroundimage
*/
public function setBackgroundimage(\TYPO3\CMS\Extbase\Domain\Model\FileReference
$backgroundimage)
{
$this->backgroundimage = $backgroundimage;
}
/**
* __construct
*/
public function __construct()
{
//Do not remove the next line: It would break the functionality
$this->initStorageObjects();
}
/**
* Initializes all ObjectStorage properties
* 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
*
* #return void
*/
protected function initStorageObjects()
{
}
}
setup.txt
config.tx_extbase{
persistence{
classes{
In2code\Femanager\Domain\Model\User {
subclasses {
0 = Fhk\Feusersplus\Domain\Model\User
}
}
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
}
}
There are my files. What is wrong ?
it is my Backgroundimage.html
{namespace femanager=Istar\Fefiles\ViewHelpers}
<f:render section="default" arguments="{_all}" />
<f:section name="default">
<div class="femanager_fieldset femanager_backgroundimage control-group">
<label for="femanager_field_backgroundimage" class="control-label">
<f:translate key="tx_feusersplus_domain_model_user.backgroundimage" default="Profile background image"/>
</label>
<femanager:form.upload property="backgroundimage" >
<f:if condition="{resource}">
<f:image image="{resource}" alt="" width="50"/>
</f:if>
</femanager:form.upload><br />
</div>
</div>
</f:section>
my set method
public function setBackgroundimage(\TYPO3\CMS\Extbase\Persistence\ObjectStorage $backgroundimage)
{
$this->backgroundimage = $backgroundimage;
}
All right? I still have the same error((
Now I have follow error:
Exception while property mapping at property path "backgroundimage": The identity property "2.jpg" is no UID.

Please try model like this User.php
<?php
namespace VendorName\ExtensionName\Domain\Model;
/**
* Users
*/
class User extends \In2code\Femanager\Domain\Model\User {
/**
* image
*
* #var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Extbase\Domain\Model\FileReference>
*/
protected $image = null;
/**
* Returns the image
*
* #return \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Extbase\Domain\Model\FileReference> $image
*/
public function getImage()
{
return $this->image;
}
/**
* Sets the image
*
* #param \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Extbase\Domain\Model\FileReference> $image image
*
* #return void
*/
public function setImage(\TYPO3\CMS\Extbase\Persistence\ObjectStorage $image)
{
$this->image = $image;
}
}
Your ext_typoscript_setup.txt like this:
config.tx_extbase{
persistence{
classes{
In2code\Femanager\Domain\Model\User {
subclasses {
0 = vendorname\extname\Domain\Model\User
}
}
vendorname\extname\Domain\Model\User {
mapping {
tableName = fe_users
recordType = 0
}
}
}
}
}

Follow below steps for Extend FE USERS.
Updated answers
Just Update your model file User.php Like below
/**
* #var \TYPO3\CMS\Extbase\Domain\Model\FileReference
*/
protected $backgroundimage = null;
Create ext_tables.sql
CREATE TABLE fe_users (
imsge int(11) unsigned NOT NULL default '0',
);
Add TCA Configuration for image fields in ext_tables.php file
$tempColumns = Array (
'image' => array(
'exclude' => 1,
'label' => 'Add image Lables',
'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig(
'image',
array(
'appearance' => array(
'createNewRelationLinkTitle' => 'LLL:EXT:cms/locallang_ttc.xlf:images.addFileReference'
),
'foreign_types' => array(
'0' => array(
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette,
--palette--;;filePalette'
),
\TYPO3\CMS\Core\Resource\File::FILETYPE_TEXT => array(
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette,
--palette--;;filePalette'
),
\TYPO3\CMS\Core\Resource\File::FILETYPE_IMAGE => array(
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette,
--palette--;;filePalette'
),
\TYPO3\CMS\Core\Resource\File::FILETYPE_AUDIO => array(
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette,
--palette--;;filePalette'
),
\TYPO3\CMS\Core\Resource\File::FILETYPE_VIDEO => array(
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette,
--palette--;;filePalette'
),
\TYPO3\CMS\Core\Resource\File::FILETYPE_APPLICATION => array(
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette,
--palette--;;filePalette'
)
),
'maxitems' => 1
),
$GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext']
),
'pdf,doc,docx'
),
),
);
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTCAcolumns("fe_users",$tempColumns,1);
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addToAllTCAtypes("fe_users","image");
Mapping image fields with fe_user tables. ext_typoscript_setup.txt
config.tx_extbase{
persistence{
classes{
TYPO3\CMS\Extbase\Domain\Model\FrontendUser {
subclasses {
Tx_Extendfeuser_User = VendorName\ExtensionName\Domain\Model\User
}
}
VendorName\ExtensionName\Domain\Model\User {
mapping {
tableName = fe_users
recordType = 0
}
}
}
}
}
Create Model fiel User.php
<?php
namespace VendorName\ExtensionName\Domain\Model;
/***************************************************************
*
* Copyright notice
*
* (c) 2015
*
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
/**
* Users
*/
class User extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
/**
* image
*
* #var \TYPO3\CMS\Extbase\Domain\Model\FileReference
*/
protected $image = null;
/**
* Returns the image
*
* #return \TYPO3\CMS\Extbase\Domain\Model\FileReference $image
*/
public function getImage()
{
return $this->image;
}
/**
* Sets the image
*
* #param \TYPO3\CMS\Extbase\Domain\Model\FileReference $image image
*
* #return void
*/
public function setImage(\TYPO3\CMS\Extbase\Domain\Model\FileReference $image)
{
$this->image = $image;
}
}
Also If you want extend Fe user With FE Manager extension then follow the link Extend Fe Users

Related

TYPO3 TCA selectCheckBox not working with extension femanager

I've created a selectCheckBox in TYPO3 like this:
'region' => [
'exclude' => true,
'label' => 'LLL:EXT:myext/Resources/Private/Language/locallang_db.xlf:tx_myext_domain_model_catalog.region',
'config' => [
'type' => 'select',
'renderType' => 'selectCheckBox',
'items' => [
['LLL:EXT:myext/Resources/Private/Language/locallang_db.xlf:tx_myext_domain_model_catalog.region.1', 1],
['LLL:EXT:myext/Resources/Private/Language/locallang_db.xlf:tx_myext_domain_model_catalog.region.2', 2],
['LLL:EXT:myext/Resources/Private/Language/locallang_db.xlf:tx_myext_domain_model_catalog.region.3', 3],
['LLL:EXT:myext/Resources/Private/Language/locallang_db.xlf:tx_myext_domain_model_catalog.region.4', 4],
],
],
],
When I save it, the database has the comma separated IDs as value like:
1,3,4
Now I want to get the value in frontend via the femanager extension.
I've created this configuration for it:
/**
* region
*
* #var array
*/
protected $region = [];
/**
* Returns the region
*
* #return array $region
*/
public function getRegion()
{
return $this->region;
}
/**
* Sets the region
*
* #param array $region
* #return void
*/
public function setRegion($region)
{
$this->region = $region;
}
Database Configuration:
region varchar(255) DEFAULT '' NOT NULL,
But when I try to debug the output like this:
<f:debug>{catalog.region}</f:debug>
It just says this:
array(empty)
So my getRegion function isn't working. Can somebody please give me a hint why it isn't getting the values.
$region is declared to be an array and your setter setRegion() is expecting an array as parameter. But the stored value in the database is a varchar. So, the mapping of the database record on your model will fail for this property.
This is working with your TCA:
/**
* #var string
*/
protected string $region = '';
/**
* #return array
*/
public function getRegion(): array
{
return GeneralUtility::intExplode(',', $this->region, true);
}
/**
* #param mixed $region
*/
public function setRegion($region): void
{
$this->region = (is_array($region) ? implode(',', array_filter($region, 'is_int')) : $region);
}

TYPO3 10 upload multiple images from frontend by extending model

I am trying to extend the model of Ext:cart. While someone orders a product from the cart page. I would like to accept images from users.
I have added the below configuration for the same.
Configuration/TCA/Overrides/tx_cart_domain_model_order_item.php
<?php
$temporaryColumns = [
'images' => [
'exclude' => 0,
'label' => 'Upload Image',
'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig('images', [
'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' => 'images',
'tablenames' => 'tx_cart_domain_model_order_item',
'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'])
],
];
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTCAcolumns(
'tx_cart_domain_model_order_item',
$temporaryColumns
);
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addToAllTCAtypes(
'tx_cart_domain_model_order_item',
'images',
'',
'after:comment'
);
ext_localconf.php
$dispatcher = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\SignalSlot\Dispatcher::class);
$dispatcher->connect(
\Extcode\Cart\Utility\OrderUtility::class,
'changeOrderItemBeforeSaving',
\vendor\myext\Utility\OrderUtility::class,
'changeOrderItemBeforeSaving'
);
$GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects'][\Extcode\Cart\Domain\Model\Order\Item::class] = [
'className' => \vendor\myext\Domain\Model\Order\Item::class
];
\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Object\Container\Container::class)
->registerImplementation(
\Extcode\Cart\Domain\Model\Order\Item::class,
\vendor\myext\Domain\Model\Order\Item::class
);
Configuration/Extbase/Persistence/Classes.php
<?php
declare(strict_types = 1);
return [
\Extcode\Cart\Domain\Model\Order\Item::class => [
'tableName' => 'tx_cart_domain_model_order_item'
],
];
Model: Classes/Domain/Model/Order/Item.php
<?php
namespace vendor\myext\Domain\Model\Order;
/*
* This file is part of the package extcode/cart.
*
* For the full copyright and license information, please read the
* LICENSE file that was distributed with this source code.
*/
class Item extends \Extcode\Cart\Domain\Model\Order\Item
{
/**
* images
*
* #var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Extbase\Domain\Model\FileReference>
*/
protected $images = NULL;
/**
* __construct
*/
public function __construct() {
//Do not remove the next line: It would break the functionality
$this->initStorageObjects();
}
/**
* Initializes all ObjectStorage properties
* 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
*
* #return void
*/
protected function initStorageObjects() {
$this->images = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
}
/**
* Removes a FileReference
*
* #param \TYPO3\CMS\Extbase\Domain\Model\FileReference $imageToRemove The FileReference to be removed
* #return void
*/
public function removeImage(\TYPO3\CMS\Extbase\Domain\Model\FileReference $imageToRemove) {
$this->images->detach($imageToRemove);
}
/**
* Returns the images
*
* #return \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Extbase\Domain\Model\FileReference> $images
*/
public function getImages() {
return $this->images;
}
/**
* Sets the images
*
* #param \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Extbase\Domain\Model\FileReference> $images
* #return void
*/
public function setImages(\TYPO3\CMS\Extbase\Persistence\ObjectStorage $images) {
$this->images = $images;
}
}
Now, I have created a utility class to modify orderItem while placing an order. But, I am not getting an extended images field.
<?php
namespace vendor\myext\Utility;
/*
* This file is part of the package extcode/cart.
*
* For the full copyright and license information, please read the
* LICENSE file that was distributed with this source code.
*/
use TYPO3\CMS\Core\Utility\GeneralUtility;
class OrderUtility
{
/**
* #param array $params
*
* #return array
*/
public function changeOrderItemBeforeSaving(array $params) {
\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($params);die;
}
}
Can anyone guide how to extend any extension with FAL image and extend with standalone extension.
A bit late, but couple years back for a 9.5 project I made an helper class to attach media to objects. This one is limited to images, Youtube and Vimeo, but not very hard to extend to other media types if needed. It's not ideal but it's working, I hope it helps someone.
/**
* Attach an image file or Youtube / Vimeo movie to an object with add method
*
* Jacco van der Post - 2019
* jacco#id-webdesign.nl
*
* #param string|array $uploadFile
* #param object $obj
* #param int $storageUid
* #param string $storageFolder
* #param string $propertyName
* #param bool $deleteFile
* #param bool $add Adding instead of setting
* #param bool $video Is the file a video
*
* #return mixed
* #throws \TYPO3\CMS\Core\Resource\Exception\ExistingTargetFileNameException
* #throws \TYPO3\CMS\Core\Resource\Exception\ExistingTargetFolderException
* #throws \TYPO3\CMS\Core\Resource\Exception\InsufficientFolderAccessPermissionsException
* #throws \TYPO3\CMS\Core\Resource\Exception\InsufficientFolderWritePermissionsException
* #throws \TYPO3\CMS\Core\Resource\Exception\ResourceDoesNotExistException
*
*/
public static function attachFile($uploadFile, $obj, int $storageUid = 1, string $storageFolder = '', string $propertyName = 'logo', bool $deleteFile = false, bool $add = false, bool $video = false)
{
$propertyName = htmlspecialchars($propertyName);
$validMedia = false;
$videoFile = null;
$objectManager = GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
$resourceFactory = ResourceFactory::getInstance();
/** #var \TYPO3\CMS\Core\Resource\StorageRepository $storageRepository */
$storageRepository = $objectManager->get('TYPO3\\CMS\\Core\\Resource\\StorageRepository');
$storage = $storageRepository->findByUid(intval($storageUid)); // 1 ==> default to fileadmin
$folder = htmlspecialchars($storageFolder);
$targetFolder = null;
if ($storage->hasFolder($folder)) {
$targetFolder = $storage->getFolder($folder);
} else {
$targetFolder = $storage->createFolder($folder);
}
if ($video && $uploadFile) {
$youTubeHelper = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Resource\OnlineMedia\Helpers\YouTubeHelper::class, 'youtube');
// Is it a Youtube link?
$videoFile = $youTubeHelper->transformUrlToFile(htmlspecialchars($uploadFile), $targetFolder);
// Is it a Vimeo link?
if (is_null($videoFile)) {
$vimeoHelper = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Resource\OnlineMedia\Helpers\VimeoHelper::class, 'vimeo');
$videoFile = $vimeoHelper->transformUrlToFile(htmlspecialchars($uploadFile), $targetFolder);
if (is_null($videoFile)) {
//throw new \UnexpectedValueException('Invalid Youtube or Vimeo link..');
if (is_object($obj)) {
return $obj;
} else {
return false;
}
}
}
$validMedia = true;
} else {
// It's supposed to be an image
// Prevent script upload instead of image files
if (exif_imagetype(htmlspecialchars($uploadFile['tmp_name'])) && getimagesize(htmlspecialchars($uploadFile['tmp_name']))) {
$validMedia = true;
}
}
if ($validMedia && is_object($obj)) {
if ($deleteFile) {
// Delete older file if needed, works only for model with maxitems 1 file
$method = 'get' . ucfirst($propertyName);
if ($obj->{$method}()) {
$falUid = $obj->{$method}()->getUid();
$fileReferenceObject = $resourceFactory->getFileReferenceObject($falUid);
$fileReferenceObject->getOriginalFile()->delete();
}
}
/** #var \Xxxx\Xxxx\Domain\Model\FileReference $newFileReference */
$newFileReference = $objectManager->get('Xxx\Xxxx\Domain\Model\FileReference');
if ($video) {
$newFileReference->setOriginalResource($videoFile);
if (method_exists($obj, 'getName')) {
$newFileReference->setTitle($obj->getTitle());
} elseif (method_exists($obj, 'getTitle')) {
$newFileReference->setTitle($obj->getTitle());
}
} else {
$originalFilePath = htmlspecialchars($uploadFile['tmp_name']);
$newFileName = htmlspecialchars($uploadFile['name']);
if (file_exists($originalFilePath)) {
$movedNewFile = $storage->addFile($originalFilePath, $targetFolder, $newFileName);
$newFileReference->setOriginalResource($movedNewFile);
$newFileReference->setTitle($newFileName);
if (method_exists($obj, 'getName')) {
$newFileReference->setAlternative($obj->getName());
} elseif (method_exists($obj, 'getTitle')) {
$newFileReference->setAlternative($obj->getTitle());
}
}
}
// 'add' method to filereference when model allows for multiple images attached to object, else 'set'
if ($add) {
$method = 'add' . ucfirst($propertyName);
} else {
$method = 'set' . ucfirst($propertyName);
}
$obj->{$method}($newFileReference);
}
return $obj;
}
Note that file upload is by definition unsafe! I talked once with Helmut about this, it's very hard to prevent bad stuf. There is some validation in this script but not enough. In my case the frontend users were 'kinda trusted' with frontend logins given by admins.

TYPO3 Extbase Dependency Injection Error/Bug in v7?

I am currently upgrading an extbase-extension to be TYPO3 v7 compatible,
and there is a very strange extbase behavior I simply have no clue to.
Within BackendController, A derived model has to be updated,
which looks like this:
/**
* action update
*
* #param \Vendor\MyExt\Domain\Model\Thing $thing
* #return void
*/
public function updateAction(\Vendor\MyExt\Domain\Model\Thing $thing) {
if ($this->request->hasArgument('exit')) {
$this->redirect('list');
exit;
}
$this->setFalItems($thing);
$this->updateStuff($thing);
$this->updateTypeModel($thing);
//...
}
protected function updateTypeModel( \Vendor\MyExt\Domain\Model\Thing $thing ) {
//...
$objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
$mytypeRepository = $this->objectManager->get('Vendor\MyExt\Domain\Repository\TypeWhateverRepository');
$typeModel = $mytypeRepository->findByUid( $TypeId );
//...
in v6, vardump( $typemodel ) showed the corresponding Object,Vendor\MyExt\Domain\Model\TypeWhatever
in v7, vardump( $typemodel ) is showing the parent Object,Vendor\MyExt\Domain\Model\Thing
Why is it working in v6?
Why is the exact same code not working in v7 anymore?
[dreams of dreaded bugs at night]
I digged a little bit deeper, This problem is somehow related to Dependency Injection.:
/**
* typeWhateverRepository
*
* #var \Vendor\MyExt\Domain\Repository\TypeWhateverRepository
* #inject
*/
protected $typeWhateverRepository;
protected function updateTypeModel(\Vendor\MyExt\Domain\Model\Thing $thing) {
// $typeWhateverRepository = $this->objectManager->get('Vendor\\MyExt\\Domain\\Repository\\TypeWhateverRepository');
$typeModel = $this->typeWhateverRepository->findByUid($thing->getTypeId());
-> still the same problem,
-> Call to undefined method Vendor\MyExt\Domain\Model\Thing::setWhatever()
So, DI didn't work at all, Grmpf.
What other prerequisites are necessary to get the DI right?
(BTW, inbetween tests, i un-and reinstall the ext, clearing all caches via installtool.)
Thank you in advance.
First of all... lets do some clean up...
I would recommend to use the inject of your repository:
/**
* seminarRepository
*
* #var \Vendor\MyExt\Domain\Repository\TypeWhateverRepository
*/
protected $typeWhateverRepository;
/**
* #param \Vendor\MyExt\Domain\Repository\TypeWhateverRepository $typeWhateverRepository
*/
public function injectTypeWhateverRepository(TypeWhateverRepository $typeWhateverRepository)
{
$this->typeWhateverRepository= $typeWhateverRepository;
}
Then I would use an Relation from Thing to Type so you don't have to fetch these from your Repository:
/**
* #lazy
* #var \Vendor\MyExt\Domain\Model\TypeWhatever
*/
protected $typeWhatever = null;
/**
* #return \Vendor\MyExt\Domain\Model\TypeWhatever $typeWhatever
*/
public function getTypeWhatever()
{
return $this->typeWhatever;
}
/**
* #param \Vendor\MyExt\Domain\Model\TypeWhatever $typeWhatever
*
* #return void
*/
public function setTypeWhatever(TypeWhatever $typeWhatever)
{
$this->typeWhatever = $typeWhatever;
}
In your Thing TCA put than:
'type_whatever' => [
'exclude' => 0,
'label' => 'LLL:EXT:my_ext/Resources/Private/Language/locallang_db.xlf:tx_myext_domain_model_thing.type_whatever',
'config' => [
'type' => 'select',
'foreign_table' => 'tx_myext_domain_model_typewhatever',
'items' => [
['LLL:EXT:my_ext/Resources/Private/Language/locallang_db.xlf:tx_myext_domain_model_thing.choose', 0],
],
'minitems' => 1,
'maxitems' => 1,
],
],
The Solution to this is trivial, but was hard to find, since I was doing an Extension Update.
the extbase-typoscript setup was missing the subclasses definition m)
extbase setup is usually found in the filetypo3conf/ext/my_ext/Configuration/TypoScript/setup.txt:
config.tx_extbase.persistence.classes {
Vendor\MyExt\Domain\Model\Thing {
subclasses {
0 = Vendor\MyExt\Domain\Model\TypeWhatever
}
}
}
Also note that it is necessary for the class to have a proper 'extends' definition in the Model file.
I still wonder why it worked in v6 at all - but well, nevermind.

Adding custom column to customer_entity

I am trying to add an custom column to customer_entity, which should be editable in customer form in backend.
I am able to add the column to the database table via an UpdateSchema Script in my Module.
But how can I populate it in the customer form and in the grid?
What I tried so far:
I added an attribute with the same name (=column name) with UpdateDataScript, $customerSetup->addAttribute()...
Customer_grid_flat is updated correctly on saving the user, but the value in the table customer_entity didn't get changed. It is saving its values inside the attribute table (customer_entity_varchar).
How can I set up the custom column correctly, so that its value is saved inside 'customer_entity' and not in 'customer_entity_varchar'?
Solution:
My custom attribute now gets properly saved inside customer_entity table.
UpgradeSchema.php
<?php
namespace Custom\MyModule\Setup;
use Magento\Framework\Setup\UpgradeSchemaInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
class UpgradeSchema implements UpgradeSchemaInterface
{
const CUSTOM_ATTRIBUTE_ID = 'custom_attribute';
/**
* #param SchemaSetupInterface $setup
* #param ModuleContextInterface $context
*/
public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $context)
{
$setup->startSetup();
if (version_compare($context->getVersion(), '0.0.3', '<')) {
$setup->getConnection()->addColumn(
$setup->getTable('customer_entity'),
self::CUSTOM_ATTRIBUTE_ID,
[
'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
'nullable' => true,
'default' => null,
'comment' => 'Custom Attribute'
]
);
}
$setup->endSetup();
}
}
UpgradeData.php
<?php
namespace Custom\MyModule\Setup;
use Magento\Customer\Model\Customer;
use Magento\Customer\Setup\CustomerSetupFactory;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Indexer\IndexerRegistry;
use Magento\Framework\Setup\UpgradeDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\TestFramework\Helper\Eav;
class UpgradeData implements UpgradeDataInterface
{
/**
* #var CustomerSetupFactory
*/
private $customerSetupFactory;
/**
* #var IndexerRegistry
*/
protected $indexerRegistry;
/**
* #var \Magento\Eav\Model\Config
*/
protected $eavConfig;
/**
* #var \Magento\Eav\Model\Setup
*/
protected $eavSetupFactory;
/**
* #param CustomerSetupFactory $customerSetupFactory
* #param IndexerRegistry $indexerRegistry
* #param \Magento\Eav\Model\Config $eavConfig
*/
public function __construct(
CustomerSetupFactory $customerSetupFactory,
IndexerRegistry $indexerRegistry,
\Magento\Eav\Model\Config $eavConfig,
EavSetupFactory $eavSetupFactory
)
{
$this->customerSetupFactory = $customerSetupFactory;
$this->indexerRegistry = $indexerRegistry;
$this->eavConfig = $eavConfig;
$this->eavSetupFactory = $eavSetupFactory;
}
/**
* Upgrades data for a module
*
* #param ModuleDataSetupInterface $setup
* #param ModuleContextInterface $context
* #return void
*/
public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
{
$dbVersion = $context->getVersion();
if (version_compare($dbVersion, '0.0.3', '<')) {
$customerSetup = $this->customerSetupFactory->create(['setup' => $setup]);
$customerSetup->addAttribute(
'customer',
UpgradeSchema::CUSTOM_ATTRIBUTE_CODE,
[
'label' => 'Custom Attribute',
'required' => 0,
'visible' => 1, //<-- important, to display the attribute in customer edit
'input' => 'text',
'type' => 'static',
'system' => 0, // <-- important, to have the value be saved
'position' => 40,
'sort_order' => 40
]
);
/** #var EavSetupFactory $eavSetup */
$eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);
$typeId = $eavSetup->getEntityTypeId('customer');
$attribute = $eavSetup->getAttribute($typeId, UpgradeSchema::CUSTOM_ATTRIBUTE_ID);
$customerSetup->getSetup()->getConnection()->insertMultiple(
$customerSetup->getSetup()->getTable('customer_form_attribute'),
array('form_code' => 'adminhtml_customer', 'attribute_id' => $attribute['attribute_id'])
);
$setup->endSetup();
}
}
}

ZF2 How to set <input type='radio' CHECKED> with a custom Form Element

How do I set checked within a form input radio field? This form field is added using a custom Form Element. The value of this field isn't consistent.
My custom Form Element returns 1 element. It is a radio input field. I need this checked each and every time the form is submitted. The reason I am using this instead of a "hidden" field is for the user to see this settings.
This is the custom Form Element
namespace Member\Form\Element;
use Doctrine\ORM\EntityManager;
use Zend\Form\Element\Radio;
/**
* Class OriginalLanguageIsoRadio
*
* #package Member\Form\Element
*/
class OriginalLanguageIsoRadio extends Radio
{
/**
* #var EntityManager $entityManager
*/
protected $entityManager;
/**
* #var string $translationKey
*/
protected $translationKey;
/**
* #var string $textDomain
*/
protected $textDomain;
/**
* #param EntityManager $entityManager
* #param string $translationKey
* #param string $textDomain
*/
public function __construct(
EntityManager $entityManager,
$translationKey,
$textDomain
)
{
$this->entityManager = $entityManager;
$this->translationKey = $translationKey;
$this->textDomain = $textDomain;
}
/**
* Get Value Options
*
* #return array
*
* #throws \Exception
*/
public function getValueOptions()
{
$array = [];
$query = $this->entityManager
->createQueryBuilder()
->from(
'AMDatabase\Entity\TheVerse\TranslationsMasters',
't'
)
->select('t.languageIso')
->setMaxResults(1);
$result = $query->getQuery()
->getArrayResult();
if (is_array($result) && count($result) > '0') {
foreach ($result AS $value) {
if ( $value['languageIso'] == '' ) {
$array['Global'] = $value['Global'];
} else {
$array[$value['languageIso']] = $value['languageIso'];
}
}
}
return $array;
}
}
Then I call the custom Form Element:
/**
* Original Language Iso
*/
$this->add(
[
'type' => 'Member\Form\Element\OriginalLanguageIsoRadio',
'name' => 'original_language_iso',
'options' => [
'label' => 'original_language_iso'
],
'attributes' => [
'id' => 'original_language_iso',
]
]
);
This adds the following to my form:
<input type="radio" name="original_language_iso" id="original_language_iso" value="en-US">
My desired output is
<input type="radio" name="original_language_iso" id="original_language_iso" value="en-US" **checked**>
You have two options:
a) Backend:
The attributes array must contain a 'value' set to the only element of the values available, that's the way to auto-check the radio input. With your example, it would be:
$this->add(
[
'type' => 'Member\Form\Element\OriginalLanguageIsoRadio',
'name' => 'original_language_iso',
'options' => [
'label' => 'original_language_iso'
],
'attributes' => [
'id' => 'original_language_iso',
'value'=>'something_here'
]
]
);
b) Front:
Use jQuery to check the radio input. You may do it with:
jQuery('#original_language_iso').attr('checked','checked');