首页 > 解决方案 > 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 图像扩展任何扩展并使用独立扩展进行扩展。

标签: typo3extbasetypo3-extensionstypo3-10.x

解决方案


有点晚了,但几年前的一个 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 谈过这件事,很难防止坏事。此脚本中有一些验证,但还不够。就我而言,前端用户“有点信任”,前端登录由管理员提供。


推荐阅读