可以使用插件更改CKFinder自动重命名格式吗?

时间:2017-08-04 08:13:57

标签: ckfinder

我正在使用CKFinder 3.4 for PHP,我正在寻找一种方法来更改上传服务器上已存在的文件时发生的自动重命名的格式。标准格式是将file.ext重命名为file(1).ext。我需要将其更改为file-1.ext.

可以在以下方面轻松更改ckfinder源代码中的功能:

/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder/Filesystem/File/File.php

但是我想避免更改源文件,因为它会使更新变得更加困难。

最好我想使用插件解决问题,但BEFORE_COMMAND_FILE_UPLOAD事件似乎不包含(自动)重命名的文件名。

那些曾经解决类似问题并找到解决方案的人?

1 个答案:

答案 0 :(得分:0)

我准备了一个小型连接器插件,可以按照您描述的方式重命名文件。不幸的是,如果没有小的黑客攻击,我无法实现这一结果:绑定一个闭包来访问私有对象属性。

要了解有关CKFinder 3 PHP Connector插件的更多信息,请查看plugins docs

这是插件,我希望你会发现它很有用:

<?php

namespace CKSource\CKFinder\Plugin\CustomAutorename;

use CKSource\CKFinder\CKFinder;
use CKSource\CKFinder\Event\BeforeCommandEvent;
use CKSource\CKFinder\Event\CKFinderEvent;
use CKSource\CKFinder\Filesystem\Folder\WorkingFolder;
use CKSource\CKFinder\Plugin\PluginInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\File\UploadedFile;

class CustomAutorename implements PluginInterface, EventSubscriberInterface
{
    protected $app;

    public function setContainer(CKFinder $app)
    {
        $this->app = $app;
    }

    public function getDefaultConfig()
    {
        return [];
    }

    public function onBeforeUpload(BeforeCommandEvent $event)
    {
        $request = $event->getRequest();

        /** @var UploadedFile $uploadedFile */
        $uploadedFile = $request->files->get('upload');

        /** @var WorkingFolder $workingFolder */
        $workingFolder = $this->app['working_folder'];

        if ($uploadedFile) {
            $uploadedFileName = $uploadedFile->getClientOriginalName();
            if (!$workingFolder->containsFile($uploadedFileName)) {
                // File with this name doesn't exist, nothing to do here.
                return;
            }

            $basename = pathinfo($uploadedFileName, PATHINFO_FILENAME);
            $extension = pathinfo($uploadedFileName, PATHINFO_EXTENSION);

            $i = 0;

            // Increment the counter until there's no file named like this in current folder.
            while (true) {
                $i++;
                $uploadedFileName = "{$basename}-{$i}.{$extension}";

                if (!$workingFolder->containsFile($uploadedFileName)) {
                    break;
                }
            }

            // And here's the hack to make a private property accessible to set a new file name.
            $setOriginalName = function (UploadedFile $file, $newFileName) {
                $file->originalName = $newFileName;
            };

            $setOriginalName = \Closure::bind($setOriginalName, null, $uploadedFile);

            $setOriginalName($uploadedFile, $uploadedFileName);
        }
    }

    public static function getSubscribedEvents()
    {
        return [CKFinderEvent::BEFORE_COMMAND_FILE_UPLOAD => 'onBeforeUpload'];
    }
}