typo3 - TYPO3 10 通过扩展模型从前端上传多张图片
问题描述
我正在尝试扩展Ext:cart
. 当有人从购物车页面订购产品时。我想接受来自用户的图像。
我已经添加了以下配置。
配置/TCA/覆盖/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
);
配置/Extbase/Persistence/Classes.php
<?php
declare(strict_types = 1);
return [
\Extcode\Cart\Domain\Model\Order\Item::class => [
'tableName' => 'tx_cart_domain_model_order_item'
],
];
模型:类/域/模型/订单/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;
}
}
现在,我创建了一个实用程序类来在下订单时修改 orderItem。但是,我没有得到扩展的图像字段。
<?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;
}
}
任何人都可以指导如何使用 FAL 图像扩展任何扩展并使用独立扩展进行扩展。
解决方案
有点晚了,但几年前的一个 9.5 项目,我创建了一个辅助类来将媒体附加到对象。这仅限于图像、Youtube 和 Vimeo,但如果需要,也不太难扩展到其他媒体类型。这并不理想,但它正在工作,我希望它可以帮助某人。
/**
* 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;
}
请注意,文件上传根据定义是不安全的!我曾经和 Helmut 谈过这件事,很难防止坏事。此脚本中有一些验证,但还不够。就我而言,前端用户“有点信任”,前端登录由管理员提供。
推荐阅读
- regex - 匹配 URL 路径和子项
- dart - 对不可为空的变量使用 late 关键字有什么好处?
- java - LinkedMultiValueMap SpringFramework 未迭代(错误:无法转换为类)
- database - mysql 连接器在故障转移到从属设备后无法回退到主控设备
- c# - 具有多种不同类型的列表
- javascript - parentNode.removeChild() 和 remove() 有什么区别
- hibernate - 使用 Hibernate/JPA 在 Spring Boot 上的购物车应用程序
- rest - Azure DevOps 问题通过包含德语变音符号的 REST 调用创建项目
- django - Django RadioSelect 小部件,添加附加信息
- php - 带有验证码的 PHP 表单不起作用(白屏)