在 Symfony 上使用 ElFinder:我无法选择图像
Posted
技术标签:
【中文标题】在 Symfony 上使用 ElFinder:我无法选择图像【英文标题】:Using ElFinder on Symfony: I can't select images 【发布时间】:2021-02-05 08:17:00 【问题描述】:我想在我的 Symfony 项目中使用 ElFinder 作为我的文件管理器。我关注了 GitHub 上的文档。在我的 routes.yaml 中:
elfinder:
resource: '@FMElfinderBundle/Resources/config/routing.yaml'
security.yaml
- path: ^/efconnect, role: [ROLE_USER]
- path: ^/elfinder, role: [ROLE_USER]
最后是 fm_elfinder.yaml
fm_elfinder:
instances:
default:
locale: '%locale%' # defaults to current request locale
editor: ckeditor # other options are tinymce, tinymce4, fm_tinymce, form, simple, custom
connector:
roots:
uploads:
driver: LocalFileSystem
path: uploads
upload_max_size: 2M
然后我将它添加到 Sonata 的 Admin 元素上,如下所示: 受保护的函数configureFormFields(FormMapper $formMapper)
$formMapper
->with('Contenu')
->add('published', CheckboxType::class, ['required' => false, 'label' => 'Publier'])
->add('title', TextType::class, ['required' => true, 'label' => 'Titre'])
->add('textLink', TextType::class, ['required' => true, 'label' => 'Texte du lien'])
->add('media', ElFinderType::class, array(
'label' => 'Photo',
'enable' => true,
'required' => true,
'instance' => 'default',
'attr' => array('class' => 'form-control')
)
)
->end();
然后我继续 Sonata Admin,当我尝试添加图像时,打开一个窗口,我添加了一个 jpeg,但是当我点击它时,似乎什么也没发生。就像,我可以选择它,但我的窗口保持打开状态,我的字段没有填满图像的名称。 感谢您的帮助。
【问题讨论】:
我在 easyadmin 2 中遇到了同样的问题,它与 CKEditor 配合得很好,但是当尝试添加单个文件字段时,窗口会打开,但单击时没有任何反应。我也得到了一个 console.warn('test')。那来自vendor/helios-ag/fm-elfinder-bundle/src/Resources/views/Form/elfinder_widget.html.twig
。如果我发现更多东西,我会告诉你...
【参考方案1】:
好的,我让它在我的 easyadmin 表单上工作。这是 easyAdmin 2 配置:
easy_admin:
entities:
BlogPost:
class: App\Entity\BlogPost
form:
fields:
- property: 'title', label: 'page.title'
- property: 'image', type: 'App\Form\ElFinderType', label: 'blog.image.file', type_options: enable: true, instance: 'single'
(我将vendor/helios-ag/fm-elfinder-bundle/src/Form/Type/ElFinderType.php
文件复制到App\Form\ElFinderType.php
。这不是必需的)。
我将 fm_elfinder 连接器设置为简单:
# src/packages/fm_elfinder.yaml
fm_elfinder:
instances:
single:
locale: fr
editor: simple
theme: smoothness
relative_path: false
connector:
roots:
uploads:
driver: LocalFileSystem
path: uploads/images
show_hidden: false
upload_allow: [ 'image/png', 'image/jpg', 'image/jpeg' ]
upload_deny: [ 'all' ]
upload_max_size: 2M
接下来我将包中的两个模板文件复制到我的templates\bundles
目录:
# templates/bundles/FMElfinderBundle/Form/elfinder_widget.html.twig #
% block elfinder_widget %
<div class="buttons">
<input type="button" block('widget_attributes')
data-type="elfinder-remove-button" value="Delete" class="% if value is empty %hide% endif % remove-button"/>
<input type="button" block('widget_attributes')
data-type="elfinder-add-button" value="Add" class="% if value is not empty %hide% endif % add-button"/>
</div>
% if value is not empty %
<img src=" value " >
% endif %
<input type="text" block('widget_attributes') % if value is not empty %value=" value " % endif %
data-type="elfinder-input-field" class="hide"/>
% if enable and instance is defined %
<script type="text/javascript" charset="utf-8">
const addButtonSelector = '[data-type="elfinder-add-button"][id=" id "]';
const removeButtonSelector = '[data-type="elfinder-remove-button"][id=" id "]';
const inputSelector = '[data-type="elfinder-input-field"][id=" id "]';
live('click', addButtonSelector, () =>
window.open(" path('elfinder', 'instance': instance, 'homeFolder': homeFolder ) ?id= id ", "popupWindow", "height=450, width=900");
);
removeButtonListener()
function live(eventType, elementQuerySelector, cb)
document.addEventListener(eventType, function (event)
const qs = document.querySelectorAll(elementQuerySelector);
if (qs)
let el = event.target, index = -1;
while (el && ((index = Array.prototype.indexOf.call(qs, el)) === -1))
el = el.parentElement;
if (index > -1)
cb.call(el, event);
)
function setValue(value)
document.querySelector(inputSelector).value = value;
function displayImage(value)
const inputElement = document.querySelector(inputSelector);
const parent = inputElement.parentElement
const image = document.createElement("img");
image.src = value;
parent.append(image)
const removeButton = document.querySelector(removeButtonSelector);
const addButton = document.querySelector(addButtonSelector);
removeButton.classList.remove('hide')
addButton.classList.add('hide')
removeButtonListener()
function removeButtonListener()
const removeButtonElement = document.querySelector(removeButtonSelector);
if(removeButtonElement)
removeButtonElement.addEventListener('click', () =>
const addButtonElement = document.querySelector(addButtonSelector);
removeButtonElement.classList.remove('hide')
const parent = removeButtonElement.closest('.form-widget')
const inputElement = parent.querySelector('[data-type="elfinder-input-field"]');
inputElement.value = null
const imageElement = parent.getElementsByTagName('img')[0]
if (imageElement)
parent.removeChild(imageElement)
removeButtonElement.classList.add('hide')
addButtonElement.classList.remove('hide')
document.querySelector(inputSelector).value = null;
)
</script>
% endif %
% endblock %
第一个包含字段和填写它们所需的 JavaScript。我添加了一个 Add
按钮。这将打开 elfinder,一旦选择了图像,此按钮就会隐藏,并且会添加一个 Remove
按钮。
接下来是 ElFinder 窗口:
# templates/bundles/FMElfinderBundle/Elfinder/simple.html.twig #
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<script data-main=" path('ef_main_js') "
src="//cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.min.js"></script>
<script>
function getUrlParam(paramName)
const reParam = new RegExp('(?:[\?&]|&)' + paramName + '=([^&]+)', 'i');
const match = window.location.search.match(reParam);
return (match && match.length > 1) ? match[1] : '' ;
define('elFinderConfig',
// elFinder options (REQUIRED)
// Documentation for client options:
// https://github.com/Studio-42/elFinder/wiki/Client-configuration-options
defaultOpts:
url: ' path('ef_connect', 'instance': instance, 'homeFolder': homeFolder ) ',
lang: ' locale ',
onlyMimes: onlyMimes|raw ,
getFileCallback: function (file)
window.opener.setValue(file.url);
window.opener.displayImage(file.url);
window.close();
,
commandsOptions:
edit:
extraOptions:
// set API key to enable Creative Cloud image editor
// see https://console.adobe.io/
creativeCloudApiKey: '',
// browsing manager URL for CKEditor, TinyMCE
// uses self location with the empty value
managerUrl: ''
,
quicklook:
// to enable CAD-Files and 3D-Models preview with sharecad.org
sharecadMimes: ['image/vnd.dwg', 'image/vnd.dxf', 'model/vnd.dwf', 'application/vnd.hp-hpgl', 'application/plt', 'application/step', 'model/iges', 'application/vnd.ms-pki.stl', 'application/sat', 'image/cgm', 'application/x-msmetafile'],
// to enable preview with Google Docs Viewer
googleDocsMimes: ['application/pdf', 'image/tiff', 'application/vnd.ms-office', 'application/msword', 'application/vnd.ms-word', 'application/vnd.ms-excel', 'application/vnd.ms-powerpoint', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'application/postscript', 'application/rtf'],
// to enable preview with Microsoft Office Online Viewer
// these MIME types override "googleDocsMimes"
officeOnlineMimes: ['application/vnd.ms-office', 'application/msword', 'application/vnd.ms-word', 'application/vnd.ms-excel', 'application/vnd.ms-powerpoint', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'application/vnd.oasis.opendocument.text', 'application/vnd.oasis.opendocument.spreadsheet', 'application/vnd.oasis.opendocument.presentation']
,
// bootCallback calls at before elFinder boot up
bootCallback: function (fm, extraObj)
/* any bind functions etc. */
fm.bind('init', function ()
);
// for example set document.title dynamically.
var title = document.title;
fm.bind('open', function ()
var path = '',
cwd = fm.cwd();
if (cwd)
path = fm.path(cwd.hash) || null;
document.title = path ? path + ':' + title : title;
).bind('destroy', function ()
document.title = title;
);
,
managers:
// 'DOM Element ID': /* elFinder options of this DOM Element */
'elfinder':
);
</script>
</head>
<body>
<!-- Element where elFinder will be created (REQUIRED) -->
<div id="elfinder"></div>
</body>
</html>
这里添加的主要功能是 getFileCallback
函数:
getFileCallback: function (file)
window.opener.setValue(file.url);
window.opener.displayImage(file.url);
window.close();
,
这现在适用于我的单个图像字段,并且不会影响 CKEditor 集成。
【讨论】:
以上是关于在 Symfony 上使用 ElFinder:我无法选择图像的主要内容,如果未能解决你的问题,请参考以下文章
在 Symfony 中找不到在 null 上调用成员函数 isPasswordValid() 的解决方案