TYPO3V11 - 文件参考:如何获取文件来创建 ZIP

问题描述 投票:0回答:1

我对 TYPO3 比较陌生,目前正在管理一个基于此 CMS 构建的网站。由于我的经验有限,我非常感谢您提供的任何帮助或指导。

提前谢谢您!

我有数组,使用TYPO3-11.5.39,PHP-7.4.32。

<f:for each="{detail.images}" as="file">
<f:link.file file="{file.originalResource}" download="true" filename="{file.originalResource.properties.name}">Download file</f:link.file>                  
</f:for>

enter image description here enter image description here

我需要将此数组转换为另一个数组以创建存档。这是我的控制器。该功能经过测试,存档是用常量值创建的。但我无法从 TYPO3 获取文件。

<?php

declare(strict_types=1);

namespace Vendor\extName\Controller;

use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Resource\ResourceFactory;
use TYPO3\CMS\Core\Resource\FileReference;
use ZipArchive;



class DownloadController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController
{
    /**
     * Download action to create and download a zip file of images
     *
     * @return void
     */


    public function downloadZipAction(): void
    {

       
        $files = [];

        foreach ($this->detail->images as $fileReference) {
            if ($fileReference instanceof \TYPO3\CMS\Extbase\Domain\Model\FileReference) {
                $file = $fileReference->getOriginalResource();

                if ($file instanceof \TYPO3\CMS\Core\Resource\FileReference) {
                    $identifier = $file->getIdentifier();
                    if ($identifier) {
                        $files[] = ['url' => $identifier];
                    }
                }
            }
        }




        $zipFileName = tempnam(sys_get_temp_dir(), 'images_') . '.zip';

        $zip = new ZipArchive();

        if ($zip->open($zipFileName, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== TRUE) {
            die('Could not create ZIP file.' );
        }

        foreach ($files as $file) {
            $fileContent = @file_get_contents($file); /
            if ($fileContent === false) {
                echo "Failed to fetch file:";
                continue; 
            }
            $fileName = basename($file);
            if (!$zip->addFromString($fileName, $fileContent)) {
                echo "Failed to add file: $fileName";
            }
        }

        $zip->close();

        if (!file_exists($zipFileName) || filesize($zipFileName) == 0) {
            unlink($zipFileName); 
            die('Failed to create a non-empty ZIP file.  ' );
        }

        header('Content-Type: application/zip');
        header('Content-Disposition: attachment; filename="images.zip"');
        header('Content-Length: ' . filesize($zipFileName));

        readfile($zipFileName);

        unlink($zipFileName);
        exit;
    }

}

我的流体模板

                <f:link.action action="downloadZip" controller="Download" arguments="{detail: detail}" target="_blank">
                    Download Images as ZIP
                </f:link.action>

控制器可以工作,但我得到一个空的存档。

zip typo3 php-7.4 typo3-11.x filereference
1个回答
0
投票

我认为问题在于您创建了一个带有“url”子结构的数组,但是当您迭代它时,您没有利用它。此外,文件路径未使用绝对目录。请查看更新后的代码,我已放置“@NEW”注释以查看与您的实现的差异。希望有帮助!

<?php declare(strict_types=1);

namespace Vendor\extName\Controller;

use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
// @NEW: Import this for access to base directory
use TYPO3\CMS\Core\Core\Environment;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Resource\ResourceFactory;
use TYPO3\CMS\Core\Resource\FileReference;
use ZipArchive;

class DownloadController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController
{
    /**
     * Download action to create and download a zip file of images
     *
     * @return void
     */
    public function downloadZipAction(): void
    {
        $files = [];

        foreach ($this->detail->images as $fileReference) {
            if ($fileReference instanceof \TYPO3\CMS\Extbase\Domain\Model\FileReference) {
                $file = $fileReference->getOriginalResource();

                if ($file instanceof \TYPO3\CMS\Core\Resource\FileReference) {
                    $identifier = $file->getIdentifier();
                    if ($identifier) {
                        // @NEW: No longer use 'url' subkey, and create a full path instread.
                            $files[] = Environment::getPublicPath() . $file->getOriginalFile()->getPublicUrl();
                    }
                }
            }
        }

        $zipFileName = tempnam(sys_get_temp_dir(), 'images_') . '.zip';
        $zip = new ZipArchive();

        if ($zip->open($zipFileName, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== TRUE) {
            die('Could not create ZIP file.' );
        }

        foreach ($files as $file) {
            $fileContent = @file_get_contents($file);
            if ($fileContent === false) {
                echo "Failed to fetch file:";
                continue; 
            }
            $fileName = basename($file);
            if (!$zip->addFromString($fileName, $fileContent)) {
                echo "Failed to add file: $fileName";
            }
        }

        $zip->close();

        // @NEW: Split these checks, because 'unlink' on a non-existing otherwise
        if (!file_exists($zipFileName)) {
            die('Failed to create ZIP file.');
        }

        if (filesize($zipFileName) == 0) {
            unlink($zipFileName); 
            die('Failed to create a non-empty ZIP file.');
        }

        header('Content-Type: application/zip');
        header('Content-Disposition: attachment; filename="images.zip"');
        header('Content-Length: ' . filesize($zipFileName));

        readfile($zipFileName);
        unlink($zipFileName);

        exit;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.