helios-ag / FMElfinderBundle

:file_folder: ElFinderBundle provides ElFinder integration with TinyMCE, CKEditor, Summernote editors
MIT License
275 stars 128 forks source link

Cloudflare assets by default? #404

Closed bobvandevijver closed 2 years ago

bobvandevijver commented 4 years ago

Looks like the bin/console elfinder:install is no longer required as the bundle now uses cloudflare by default to retrieve the assets. Doesn't look configurable either...

This also means that the assets configuration option is no longer doing anything.

I do not want to depend on an external provider for my project, so it looks like I need to implement the finder view by myself and only use the PHP backend of the bundle.

bobvandevijver commented 4 years ago

Looks like the do the same in elfinder now, so it is not really related to this bundle. However, it is still possible to use the "normal" js files, so maybe add some documentation on how to use those?

featuriz commented 4 years ago

The command bin/console elfinder:install install to public folder not to website public folder, configured at composer.json and also to be noted is,

  1. I copied from public folder to web folder and
  2. assets:install deletes elfinder folder from my web folder. So I have to run elfinder:install every time.
remmel commented 4 years ago

@featuriz

2. assets:install deletes elfinder folder from my web folder. So I have to run elfinder:install every time.

To automatically re-install elfinder js I added in composer.json:

"post-install-cmd": [
      "@auto-scripts",
        "bin/console elfinder:install",
    ],

I would be better if it would be done automatically without that line, by creating the public/bundles/fmelfinder/ without calling elfinder:install or using CDN

bobvandevijver commented 3 years ago

Even when using the elfinder:install the bundle still retrieves certain parts from Cloudflare, such as require.js (see line below), which in turn loads jquery and jquery-ui and their dependencies.

https://github.com/helios-ag/FMElfinderBundle/blob/1d93c718715afdec9b192a8c8b59d82862f43ae1/src/Resources/views/Elfinder/elfinder_type.html.twig#L7

image

bobvandevijver commented 3 years ago

Okay, so in order to get this working without any CDN load, I needed to use a custom template for the instance.

I copied the default ckeditor template, and adjusted the require.js so it would be loaded from my local webserver. Next I copied and adjusted the ef_main_js file into the template, and adjusted the requirejs configuration to retrieve the assets from my local webserver. Lastly, I made sure to configure webpack (as I'm using Symfony Encore) to copy the required assets. Obviously, you will need to add the required npm/yarn packages: yarn add jquery-ui-dist jquery-ui-themes requirejs.

config/packages/fm_elfinder.yml

fm_elfinder:
  instances:
    default:
      editor: custom # was ckeditor
      editor_template: elfinder/elfinder.html.twig

templates/elfinder/elfinder.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 src="{{ asset('build/elfinder/requirejs/require.js') }}"></script>
  <script>
    function getUrlParam(paramName) {
      var reParam = new RegExp('(?:[\?&]|&amp;)' + paramName + '=([^&]+)', 'i');
      var match = window.location.search.match(reParam);

      return (match && match.length > 1) ? match[1] : '';
    }

    var funcNum = getUrlParam('CKEditorFuncNum');
    var mode = getUrlParam('mode');
    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) {
          if (funcNum) {
            {% if relative_path %}
            window.opener.CKEDITOR.tools.callFunction(funcNum, '{{ pathPrefix }}' + file.url.replace("{{ app.request.schemeAndHttpHost }}/", ''));
            {% else %}
            window.opener.CKEDITOR.tools.callFunction(funcNum, file.url);
            {% endif %}
            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']
          }
        },
        // bootCalback calls at before elFinder boot up
        bootCallback: function (fm, extraObj) {
          /* any bind functions etc. */
          fm.bind('init', function () {
            // any your code
          });
          // 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': {}
      }
    });

    (function () {
      'use strict';
      var
          // Start elFinder (REQUIRED)
          start = function (elFinder, editors, config) {
            // load jQueryUI CSS
            elFinder.prototype.loadCss('{{ asset('build/els/jquery-ui/themes/smoothness/jquery-ui.min.css') }}');

            $(function () {
              var optEditors = {
                    commandsOptions: {
                      edit: {
                        editors: Array.isArray(editors) ? editors : []
                      }
                    }
                  },
                  opts = {};

              // Interpretation of "elFinderConfig"
              if (config && config.managers) {
                $.each(config.managers, function (id, mOpts) {
                  opts = Object.assign(opts, config.defaultOpts || {});
                  // editors marges to opts.commandOptions.edit
                  try {
                    mOpts.commandsOptions.edit.editors = mOpts.commandsOptions.edit.editors.concat(editors || []);
                  } catch (e) {
                    Object.assign(mOpts, optEditors);
                  }
                  // Make elFinder
                  $('#' + id).elfinder(
                      // 1st Arg - options
                      $.extend(true, {}, opts, mOpts || {}),
                  );
                });
              } else {
                alert('"elFinderConfig" object is wrong.');
              }
            });
          },

          // JavaScript loader (REQUIRED)
          load = function () {
            require([
                  'elfinder'
                  , '{{ asset('build/els/js/extras/editors.default.min.js') }}'
                  , 'elFinderConfig'
                ],
                start,
                function (error) {
                  alert(error.message);
                }
            );
          }
      ;

      // config of RequireJS (REQUIRED)
      require.config({
        paths: {
          'jquery': '{{ asset('build/els/jquery/jquery.min.js')|split('.js')[0] }}',
          'jquery-ui': '{{ asset('build/els/jquery-ui/jquery-ui.min.js')|split('.js')[0] }}',
          'elfinder': '{{ asset('build/els/js/elfinder.min.js')|split('.js')[0] }}'
        },
        waitSeconds: 10 // optional
      });

      // load JavaScripts (REQUIRED)
      load();
    })();
  </script>
</head>
<body>

<!-- Element where elFinder will be created (REQUIRED) -->
<div id="elfinder"></div>

</body>
</html>

webpack.config.js

var Encore = require('@symfony/webpack-encore');

Encore
    .copyFiles([
      {
        from: './node_modules/requirejs/',
        to: 'elfinder/requirejs/[path][name].[hash:8].[ext]',
        pattern: /require\.js$/
      },
      {from: './node_modules/jquery/dist', to: 'els/jquery/[path][name].[ext]', pattern: /jquery\.min\.js$/},
      {
        from: './node_modules/jquery-ui-dist',
        to: 'els/jquery-ui/[path][name].[ext]',
        pattern: /jquery-ui\.min\.(js|css)$/
      },
      {
        from: './node_modules/jquery-ui-themes/themes/smoothness',
        to: 'els/jquery-ui/themes/smoothness/[path][name].[ext]'
      },
      {from: './vendor/studio-42/elfinder/css', to: 'els/css/[path][name].[ext]'},
      {from: './vendor/studio-42/elfinder/img', to: 'els/img/[path][name].[ext]'},
      {from: './vendor/studio-42/elfinder/js', to: 'els/js/[path][name].[ext]'},
      {from: './vendor/studio-42/elfinder/sounds', to: 'els/sounds/[path][name].[ext]'}
    ])
;

module.exports = Encore.getWebpackConfig();
helios-ag commented 2 years ago

Closing as resolved.

bobvandevijver commented 2 years ago

@helios-ag It would stil be nice if the bundle would support this out of the box, without the need to fully override the Twig template...

helios-ag commented 2 years ago

@bobvandevijver can you make PR in this case?