TYPO3 10 upload multiple images from frontend by extending model - typo3

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.

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 add image upload field to feuser

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

how to add "target lists" to my custom module

i have create a module and named: Custom_module by Developer Tools --> Module Builder
I trired to add "target lists" to Custom_module like module Campaign, but i can not find the way the do that
everyone can help you to find the best way to add "target lists" to my module.
thanks
You Just need to create a custom sub panel in your custom module.
target list is ProspectLists module.
Follow this link to create custom module.
http://shanedowling.com/sugarcrm-7-custom-subpanels
https://developer.sugarcrm.com/2015/05/18/creating-subpanels-with-custom-results-in-sugar-7-5/
1. Create a new link class
This should go into custom/modules//YourNewLink.php and this class will act as the custom functionality that will build your link between the two records.
<?php
/**
* Custom filtered link
*/
class YourNewLink extends Link2
{
/**
* DB
*
* #var DBManager
*/
protected $db;
public function __construct($linkName, $bean, $linkDef = false)
{
$this->focus = $bean;
$this->name = $linkName;
$this->db = DBManagerFactory::getInstance();
if (empty($linkDef)) {
$this->def = $bean->field_defs[$linkName];
} else {
$this->def = $linkDef;
}
}
/**
* Returns false if no relationship was found for this link
*
* #return bool
*/
public function loadedSuccesfully()
{
// this link always loads successfully
return true;
}
/**
* #see Link2::getRelatedModuleName()
*/
public function getRelatedModuleName()
{
return '<Your_Module>';
}
/**
*
* #see Link2::buildJoinSugarQuery()
*/
public function buildJoinSugarQuery($sugar_query, $options = array())
{
$joinParams = array('joinType' => isset($options['joinType']) ? $options['joinType'] : 'INNER');
$jta = 'active_other_invites';
if (!empty($options['joinTableAlias'])) {
$jta = $joinParams['alias'] = $options['joinTableAlias'];
}
$sugar_query->joinRaw($this->getCustomJoin($options), $joinParams);
return $sugar_query->join[$jta];
}
/**
* Builds main join subpanel
* #param string $params
* #return string JOIN clause
*/
protected function getCustomJoin($params = array())
{
$bean_id = $this->db->quoted($this->focus->id);
$sql = " INNER JOIN(";
$sql .= "SELECT id FROM accounts WHERE id={$bean_id}"; // This is essentially a select statement that will return a set of ids that you can match with the existing sugar_query
$sql .= ") accounts_result ON accounts_result.id = sugar_query_table.id";
return $sql;
}
2. Add a new vardef entry for the link field.
For this example, I'm going to create the custom link on the contacts module. So this code goes in custom/Extension/modules/Contacts/Ext/Vardefs/your_field_name.php
<?php
$dictionary["Contact"]["fields"]["your_field_name"] = array(
'name' => 'active_other_invites',
'type' => 'link',
'link_file' => 'custom/modules/<YourModule>/YourNewLink.php',
'link_class' => 'YourNewLink',
'source' => 'non-db',
'vname' => 'LBL_NEW_LINK',
'module' => '<YourModule>',
'link_type' => 'many',
'relationship' => '',
);
3. Add the new link as a subpanel
This goes under custom/Extension/modules/Contacts/Ext/clients/base/layouts/subpanels/your_subpanel_name.php
<?php
$viewdefs['Contacts']['base']['layout']['subpanels']['components'][] = array (
'layout' => 'subpanel',
'label' => 'LBL_NEW_LINK',
'context' =>
array (
'link' => 'your_field_name',
),
);
4. Add the label
Under custom/Extension/modules/Contacts/Ext/Language/en_us.new_link.php
<?php
$mod_strings['LBL_ACTIVE_OTHER_INVITES'] = 'Your New Link';
5. Quick Repair and Rebuild

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');