TinyMCE: elFinderと連携して画像アップロードと選択機能を追加する

TinyMCEには画像挿入ボタン( `image` )が用意されていますが、標準の状態だとURLを入力する機能しかなく画像をアップロードして挿入するようなことができません。ファイルのアップロードと選択機能の仕組みを別途用意して、TinyMCEの `file_browser_callback` という設定を経由することでファイル選択(挿入)の機能を実現することができます。

画像のアップロードや選択機能を自力で、かつ使ってもらう人に使いやすいように作成するのは少し手間がかかるので、今回はelFinderを活用して画像アップロード機能を追加する方法を説明します。(内部的な仕組みは `<iframe>` なので、ひと通り仕組みが把握できれば自作や他の製品と連携するための参考になると思います)

![image2.png](https://qiita-image-store.s3.amazonaws.com/0/782/a5b3d845-58c0-58a2-605c-1bbdfd952d16.png)

## 1. TinyMCEとelFinderを設置する

まず、TinyMCEとelFinderを設置して使用できる状態にしてください。設置の仕方は「[TinyMCEを設置する](http://qiita.com/nissuk/items/e31bdfa858d6c5c018c2)」および「[elFinderを設置する](http://qiita.com/nissuk/items/1ec79b7478e7c1282873)」に記載しています。

※ elFinderの `connector.minimal.php` で指定する `path` と `URL` はサーバ上で公開されている場所のものにする必要があります。

## 2. TinyMCEの設定を行う

TinyMCE側では

1. 画像挿入ボタンを有効にする ( `plugins` と `toolbar` に `image` を設定、または追加する ) ※
2. ファイルブラウザの設定を行う ( `file_browser_callback` )

の2つの設定を行います。(※ `toolbar`にはデフォルトで `image` が含まれているので `toolbar` を変えない場合は `plugins` の設定だけで可)

`file_browser_callback` はファイルブラウザが開かれる時に呼び出される関数を指定するものです。この設定を行っておくと、画像挿入ボタンを開いた際のダイアログ内にファイルブラウザを開くボタンが自動で追加されます。

### 例 (「[追加]」となっている部分)

```html
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <script src="js/tinymce/tinymce.min.js"></script>
    <script>

    // ファイルブラウザが開かれる時に呼び出される関数
    // https://github.com/Studio-42/elFinder/wiki/Integration-with-TinyMCE-4.x を一部変更しています。
    function elFinderBrowser (field_name, url, type, win) {
        tinymce.activeEditor.windowManager.open({
            file: '/elFinder-2.1.12/elfinder.html', // elFinderを配置した場所を指定して下さい(絶対パス)
            title: 'ファイルのアップロード・選択',
            width: 900,  
            height: 450,
            resizable: 'yes'
        }, {
            setUrl: function (url) {
                win.document.getElementById(field_name).value = url;
            }
        });
        return false;
    }

    tinymce.init({
        selector: "#foo", // id="foo"の場所にTinyMCEを適用
        language: "ja",   // 言語 = 日本語

        plugins: "image", // [追加] 1. 画像挿入ボタンを有効にする
        file_browser_callback : elFinderBrowser // [追加] 2. ファイルブラウザの設定を行う (elFinderとの連携)
    });
    </script>
</head>
<body>
    <textarea id="foo" name="foo">最初に入力しておきたい文章</textarea>
</body>
</html>
```

うまく設定できると

1. 画像挿入ボタンが追加されている
2. 画像挿入ボタンをクリックした先のダイアログ内に画像選択ボタンが追加されている
3. 画像選択ボタンをクリックした先のダイアログ内にelFinderが表示される
4. elFinder内のアップロードボタン(フロッピーディスクのアイコン)やファイルドラッグで画像がアップロードできる

ところまで確認ができます。

![image1.png](https://qiita-image-store.s3.amazonaws.com/0/782/75f1f733-d775-d500-ad4f-2d66ce9a68ee.png)

(1と2)

## 3. elFinderの設定を行う

2.のTinyMCEの設定のみではアップロードはできますが、画像を選択してTinyMCEに挿入することはまだできません。選択・挿入を行うには、elFinder側のelfinder.html上にある `getFileCallback` (ファイルが選択された時の処理) の設定を行います。

### 例 (elfinder.html。「[追加]」となっている部分)

```html
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>elFinder 2.1.x source version with PHP connector</title>
        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2" />

        <!-- jQuery and jQuery UI (REQUIRED) -->
        <link rel="stylesheet" type="text/css" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css">
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
        <script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>

        <!-- elFinder CSS (REQUIRED) -->
        <link rel="stylesheet" type="text/css" href="css/elfinder.min.css">
        <link rel="stylesheet" type="text/css" href="css/theme.css">

        <!-- elFinder JS (REQUIRED) -->
        <script src="js/elfinder.min.js"></script>

        <!-- GoogleDocs Quicklook plugin for GoogleDrive Volume (OPTIONAL) -->
        <!--<script src="js/extras/quicklook.googledocs.js"></script>-->

        <!-- elFinder translation (OPTIONAL) -->
        <script src="js/i18n/elfinder.jp.js"></script>

        <!-- elFinder initialization (REQUIRED) -->
        <script type="text/javascript" charset="utf-8">

            // [追加] 
            // https://github.com/Studio-42/elFinder/wiki/Integration-with-TinyMCE-4.x を一部変更しています。
            var FileBrowserDialogue = {
                init: function() {
                    // 独自のonLoad処理が必要な場合ここにコードを記載
                },
                mySubmit: function (URL) {
                    // 選択されたファイルパスをTinyMCEに渡します。
                    parent.tinymce.activeEditor.windowManager.getParams().setUrl(URL);

                    // TinyMCEダイアログに対して画像サイズの項目設定および更新を指示します。
                    var t = parent.tinymce.activeEditor.windowManager.windows[0];
                    t.find('#src').fire('change');

                    // ポップアップウィンドウを閉じます。
                    parent.tinymce.activeEditor.windowManager.close();
                }
            };

            // Documentation for client options:
            // https://github.com/Studio-42/elFinder/wiki/Client-configuration-options
            $(document).ready(function() {
                $('#elfinder').elfinder({
                    url : 'php/connector.minimal.php'  // connector URL (REQUIRED)
                    , lang: 'jp'                    // language (OPTIONAL)

                    // [追加]
                    , getFileCallback: function(file) {
                        FileBrowserDialogue.mySubmit(file.url); // 選択されたファイルパスをTinyMCEに渡します。
                    }
                });
            });
        </script>
    </head>
    <body>

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

    </body>
</html>
```

うまく設定できると、画像選択ボタンをクリックして出てくるelFinderダイアログ上の画像ファイルをダブルクリックすることで画像の挿入ができます。(ダブルクリックではなく選択して「挿入」ボタンで挿入したい、などのカスタマイズはelFinderのイベントなどと連携して処理を作成する必要があります)