ngscz/nette-elfinder

Nette 框架的 Elfinder 实现

2.1.6 2023-01-09 13:04 UTC

This package is auto-updated.

Last update: 2024-09-09 16:52:41 UTC


README

安装

  1. 将以下选项添加到 composer.json 中
	"require": {
		"ngscz/nette-elfinder": "dev-master"
	},
	"repositories": [
		{
			"type": "git",
			"url": "https://github.com/ngscz/nette-elfinder.git"
		}
	],
  1. 将脚本选项添加到 composer.json 中
	"scripts": {
		"ngs-elfinder-move-assets": [
			"cp -r vendor/ngscz/nette-elfinder/assets www",
			"mkdir -p www/assets/vendor/elfinder",
			"cp -r vendor/studio-42/elfinder/css www/assets/vendor/elfinder",
			"cp -r vendor/studio-42/elfinder/js www/assets/vendor/elfinder",
			"cp -r vendor/studio-42/elfinder/img www/assets/vendor/elfinder"
		],
		"post-install-cmd": [
			"@ngs-elfinder-move-assets"
		]
	}
  1. 更新你的 composer 依赖项
composer update

上面的脚本将所需的资产复制到公共(www)目录。如果未自动运行,您应该运行

composer run-script ngs-elfinder-move-assets

将扩展配置添加到 config.neon 中

extensions:
	ngs.elfinder: Ngscz\Elfinder\DI\ElfinderExtension

创建 Elfinder 呈现器并使用 trait ElfinderPresenter

<?php

namespace App\Presenters;

use Nette;

class ElfinderPresenter extends Nette\Application\UI\Presenter
{
    use \Ngscz\Elfinder\Presenters\ElfinderPresenter;

    public function renderDefault()
    {
        $template = $this->getTemplate();

        $template->includePath = $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR .
            'vendor' . DIRECTORY_SEPARATOR .
            'ngscz' . DIRECTORY_SEPARATOR .
            'nette-elfinder' . DIRECTORY_SEPARATOR .
            'src' . DIRECTORY_SEPARATOR .
            'Presenters' . DIRECTORY_SEPARATOR .
            'templates' . DIRECTORY_SEPARATOR .
            'Elfinder' . DIRECTORY_SEPARATOR .
            'default.latte';
    }    

}

将 Elfinder 呈现器添加到您的 Router 中

$router[] = new Route('elfinder/<action>', 'Elfinder:default');

创建模板 templates/Elfinder/default.latte 并包含核心 default.latte 文件(使用在 renderDefault 方法中创建的 $includePath 变量)

etc:

{include $includePath}

您还必须在 @layout.latte 中添加 JS 钩子以绑定文件管理器到您的 CMS

<script src="assets/vendor/ngscz-elfinder/js/ElfinderInputHook.js"></script>

示例:如何将 elfinder 添加到表单

<?php

namespace App\Presenters;

use Nette\Application\UI;
use Ngscz\Elfinder\Forms\ElfinderInput;

class HomepagePresenter extends FrontendPresenter
{

    protected function createComponentForm()
    {
        $form = new UI\Form;
        $form->addComponent(new ElfinderInput, 'file');

        $form->addSubmit('submit');

        // how to set default values
        $qb = $this->assetTable->prepareQueryBuilder();
        $files = [];
        foreach ($qb->getQuery()->getResult() as $file) {
            $files[] = [
                'hash' => $file->getHash(),
                'url' => '/uploads' . $file->getPath(),
            ];
        }

        $form->setDefaults([
            'file' => $files,
        ]);

        $form->onSuccess[] = function($form, $values) {
            dumpe($values);
            //will return array of hashe
        };

        return $form;
    }

}

示例:如何根据文件 mimeType 添加过滤器

    $control = new ElfinderInput($label, $assetTable);
    $control->onlyMimes(['image', 'audio']); //to show only images and audio files
    
    list of possible filters:
    ['image', 'audio', 'application', 'text', 'video']
    
    see main types: https://cs.wikipedia.org/wiki/Typ_internetov%C3%A9ho_m%C3%A9dia#N%C4%9Bkter%C3%A9_%C4%8Dasto_pou%C5%BE%C3%ADvan%C3%A9_typy_m%C3%A9di%C3%AD

自定义 Elfinder 输入并具有自定义属性

<?php declare(strict_types=1);

namespace App\CmsModule\Forms\Controls;

use App\Model\Asset\Asset;
use Nette\Utils\Json;
use Ngscz\Elfinder\Forms\ElfinderInput as BaseElfinderInput;

class ElfinderInput extends BaseElfinderInput
{
    public function __construct($caption, $assetTable)
    {
        parent::__construct($caption, $assetTable);

        $this->setOption(self::OPTION_LOCALES, [
            [
                'locale' => 'cs',
                'label' => 'Česky',
            ],
            [
                'locale' => 'en',
                'label' => 'Anglicky',
            ],
        ]);

        $this->setOption(self::OPTION_FIELDS, [
            [
                'name' => 'title',
                'type' => 'text',
                'label' => 'Název',
            ],
            [
                'name' => 'description',
                'type' => 'textarea',
                'label' => 'Popis',
            ],
        ]);
    }

    public function setValue($value)
    {
        parent::setValue($value);

        if ($this->files !== []) {
            $this->value = Json::encode($this->onLoad());
        }

        return $this;
    }

    private function onLoad(): array
    {
        $values = [];
        foreach ($this->files as $asset) {
            $formValue = [
                'hash' => $asset->getHash(),
                'url' => '/uploads' . $asset->getPath(),
            ];

            foreach ($this->getOption(self::OPTION_LOCALES) as $locale) {
                $translation = $asset->translate($locale['locale'], false);
                $formValue[$locale['locale']]['title'] = $translation->getTitle();
                $formValue[$locale['locale']]['description'] = $translation->getDescription();
            }

            $values[] = $formValue;
        }

        return $values;
    }

    public function onSave(): void
    {
        $values = $this->getValues();

        foreach ($values as $key => $formValue) {
            /** @var Asset $asset */
            $asset = $formValue['file'];

            foreach ($this->getOption(self::OPTION_LOCALES) as $locale) {
                $translation = $asset->translate($locale['locale'], false);
                $translation->setTitle($formValue[$locale['locale']]['title'] ?? null);
                $translation->setDescription($formValue[$locale['locale']]['description'] ?? null);
            }

            $asset->mergeNewTranslations();

            $values[$key]['file'] = $asset;
        }

        $this->values = $values;
    }
}

然后绑定 onSuccess 事件

        $this->onSuccess[] = function (Form $form) use ($name): void {
            $form[$name]->onSave();
        };

@todo

添加示例如何将数据保存到数据库(Uploader)