Как вы можете интегрировать пользовательский файловый браузер/загрузчик с CKEditor?

Официальная документация менее ясна - какой правильный способ интегрировать пользовательский файловый браузер/загрузчик с CKEditor? (v3 - не FCKEditor)

Ответ 1

Начните с регистрации пользовательского браузера/загрузчика при создании экземпляра CKEditor. Вы можете назначить разные URL-адреса для браузера изображений в сравнении с общим файловым браузером.

<script type="text/javascript">
CKEDITOR.replace('content', {
    filebrowserBrowseUrl : '/browser/browse/type/all',
    filebrowserUploadUrl : '/browser/upload/type/all',
    filebrowserImageBrowseUrl : '/browser/browse/type/image',
filebrowserImageUploadUrl : '/browser/upload/type/image',
    filebrowserWindowWidth  : 800,
    filebrowserWindowHeight : 500
});
</script>

Пользовательский код получит GET-параметр CKEditorFuncNum. Сохраните его - это ваша функция обратного вызова. Скажем, вы положили его на $callback.

Когда кто-то выбирает файл, запустите этот JavaScript, чтобы сообщить CKEditor, какой файл был выбран:

window.opener.CKEDITOR.tools.callFunction(<?php echo $callback; ?>,url)

Где "url" - это URL-адрес файла, который они выбрали. Дополнительным третьим параметром может быть текст, который вы хотите отобразить в стандартном диалоговом окне оповещения, например "незаконный файл" или что-то еще. Установите url в пустую строку, если третий параметр является сообщением об ошибке.

Вкладка "upload" CKEditor отправит файл в поле "upload" - в PHP, который отправляется в $_FILES ['upload']. Что CKEditor хочет, чтобы ваш сервер выводил полный блок JavaScript:

$output = '<html><body><script type="text/javascript">window.parent.CKEDITOR.tools.callFunction('.$callback.', "'.$url.'","'.$msg.'");</script></body></html>';
echo $output;

Опять же, вам нужно указать ему этот параметр обратного вызова, URL-адрес файла и, возможно, сообщение. Если сообщение является пустой строкой, ничего не будет отображаться; если сообщение является ошибкой, то url должен быть пустой строкой.

Официальная документация CKEditor является неполной во всем этом, но если вы будете следовать выше, она будет работать как чемпион.

Ответ 2

Я разместил один небольшой учебник об интеграции FileBrowser, доступного в старом FCKEditor, в CKEditor.

http://www.mixedwaves.com/2010/02/integrating-fckeditor-filemanager-in-ckeditor/

Он содержит пошаговые инструкции для этого и его довольно простой. Я надеюсь, что кто-нибудь в поисках этого найдет этот учебник полезным.

Ответ 3

Я только сам прошел процесс обучения. Я понял это, но я согласен, что документация написана таким образом, что это было пугающе. Большой момент "ага" для меня заключался в понимании того, что для просмотра все CKeditor открывает новое окно и предоставляет несколько параметров в URL-адресе. Он позволяет добавлять дополнительные параметры, но имейте в виду, что вам нужно будет использовать encodeURIComponent() для ваших значений.

Я вызываю браузер и загрузчик с помощью

CKEDITOR.replace( 'body',  
{  
    filebrowserBrowseUrl: 'browse.php?type=Images&dir=' +  
        encodeURIComponent('content/images'),  
    filebrowserUploadUrl: 'upload.php?type=Files&dir=' +  
        encodeURIComponent('content/images')  
}

Для браузера, в открывшемся окне (browse.php) вы используете php и js для предоставления списка вариантов, а затем после вашего обработчика onclick вы вызываете функцию CKeditor с двумя аргументами, url/путь к выбранному изображению и CKEditorFuncNum, предоставленный CKeditor в URL:

function myOnclickHandler(){  
//..    
    window.opener.CKEDITOR.tools.callFunction(<?php echo $_GET['CKEditorFuncNum']; ?>, pathToImage);  
    window.close();
}       

Simarly, uploader просто вызывает URL-адрес, который вы указываете, например upload.php, и снова предоставляет $_GET ['CKEditorFuncNum']. Целью является iframe, поэтому, после сохранения файла из $_FILES, вы передаете свои отзывы CKeditor таким образом:

$funcNum = $_GET['CKEditorFuncNum'];  
exit("<script>window.parent.CKEDITOR.tools.callFunction($funcNum, '$filePath', '$errorMessage');</script>");  

Ниже приведен простой интерфейс пользовательского браузера script. Хотя он не позволяет пользователям перемещаться по серверу, он позволяет указать, какой каталог вытаскивать файлы изображений при вызове браузера.

Все это скорее базовое кодирование, поэтому оно должно работать во всех относительно современных браузерах.

CKeditor просто открывает новое окно с предоставленным URL

/*          
    in CKeditor **use encodeURIComponent()** to add dir param to the filebrowserBrowseUrl property

    Replace content/images with directory where your images are housed.
*/          
        CKEDITOR.replace( 'editor1', {  
            filebrowserBrowseUrl: '**browse.php**?type=Images&dir=' + encodeURIComponent('content/images'),  
            filebrowserUploadUrl: 'upload.php?type=Files&dir=' + encodeURIComponent('content/images') 
        });   

//========= полный код ниже для browse.php

<?php  
header("Content-Type: text/html; charset=utf-8\n");  
header("Cache-Control: no-cache, must-revalidate\n");  
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");  

// e-z params  
$dim = 150;         /* image displays proportionally within this square dimension ) */  
$cols = 4;          /* thumbnails per row */
$thumIndicator = '_th'; /* e.g., *image123_th.jpg*) -> if not using thumbNails then use empty string */  
?>  
<!DOCTYPE html>  
<html>  
<head>  
    <title>browse file</title>  
    <meta charset="utf-8">  

    <style>  
        html,  
        body {padding:0; margin:0; background:black; }  
        table {width:100%; border-spacing:15px; }  
        td {text-align:center; padding:5px; background:#181818; }  
        img {border:5px solid #303030; padding:0; verticle-align: middle;}  
        img:hover { border-color:blue; cursor:pointer; }  
    </style>  

</head>  


<body>  

<table>  

<?php  

$dir = $_GET['dir'];    

$dir = rtrim($dir, '/'); // the script will add the ending slash when appropriate  

$files = scandir($dir);  

$images = array();  

foreach($files as $file){  
    // filter for thumbNail image files (use an empty string for $thumIndicator if not using thumbnails )
    if( !preg_match('/'. $thumIndicator .'\.(jpg|jpeg|png|gif)$/i', $file) )  
        continue;  

    $thumbSrc = $dir . '/' . $file;  
    $fileBaseName = str_replace('_th.','.',$file);  

    $image_info = getimagesize($thumbSrc);  
    $_w = $image_info[0];  
    $_h = $image_info[1]; 

    if( $_w > $_h ) {       // $a is the longer side and $b is the shorter side
        $a = $_w;  
        $b = $_h;  
    } else {  
        $a = $_h;  
        $b = $_w;  
    }     

    $pct = $b / $a;     // the shorter sides relationship to the longer side

    if( $a > $dim )   
        $a = $dim;      // limit the longer side to the dimension specified

    $b = (int)($a * $pct);  // calculate the shorter side

    $width =    $_w > $_h ? $a : $b;  
    $height =   $_w > $_h ? $b : $a;  

    // produce an image tag
    $str = sprintf('<img src="%s" width="%d" height="%d" title="%s" alt="">',   
        $thumbSrc,  
        $width,  
        $height,  
        $fileBaseName  
    );  

    // save image tags in an array
    $images[] = str_replace("'", "\\'", $str); // an unescaped apostrophe would break js  

}

$numRows = floor( count($images) / $cols );  

// if there are any images left over then add another row
if( count($images) % $cols != 0 )  
    $numRows++;  


// produce the correct number of table rows with empty cells
for($i=0; $i<$numRows; $i++)   
    echo "\t<tr>" . implode('', array_fill(0, $cols, '<td></td>')) . "</tr>\n\n";  

?>  
</table>  


<script>  

// make a js array from the php array
images = [  
<?php   

foreach( $images as $v)  
    echo sprintf("\t'%s',\n", $v);  

?>];  

tbl = document.getElementsByTagName('table')[0];  

td = tbl.getElementsByTagName('td');  

// fill the empty table cells with data
for(var i=0; i < images.length; i++)  
    td[i].innerHTML = images[i];  


// event handler to place clicked image into CKeditor
tbl.onclick =   

    function(e) {  

        var tgt = e.target || event.srcElement,  
            url;  

        if( tgt.nodeName != 'IMG' )  
            return;  

        url = '<?php echo $dir;?>' + '/' + tgt.title;  

        this.onclick = null;  

        window.opener.CKEDITOR.tools.callFunction(<?php echo $_GET['CKEditorFuncNum']; ?>, url);  

        window.close();  
    }  
</script>  
</body>  
</html>            

Ответ 4

Я потратил некоторое время, пытаясь понять это, и вот что я сделал. Я сломал его очень просто, потому что это то, что мне нужно.

Непосредственно под текстовой областью ckeditor введите файл загрузки, например → →

<form action="welcomeeditupload.asp" method="post" name="deletechecked">
    <div align="center">
        <br />
        <br />
        <label></label>
        <textarea class="ckeditor" cols="80" id="editor1" name="editor1" rows="10"><%=(rslegschedule.Fields.Item("welcomevar").Value)%></textarea>
        <script type="text/javascript">
        //<![CDATA[
            CKEDITOR.replace( 'editor1',
            {
                filebrowserUploadUrl : 'updateimagedone.asp'
            });
        //]]>
        </script>
        <br />
        <br />
        <br />
        <input type="submit" value="Update">
    </div>
</form>

', а затем добавьте файл для загрузки, вот мой, который написан в ASP. Если вы используете PHP и т.д., Просто замените ASP своей загрузкой script, но убедитесь, что страница выводит одно и то же.

<%@LANGUAGE="VBSCRIPT" CODEPAGE="65001"%>
<%
    if Request("CKEditorFuncNum")=1 then
        Set Upload = Server.CreateObject("Persits.Upload")
        Upload.OverwriteFiles = False
        Upload.SetMaxSize 5000000, True
        Upload.CodePage = 65001

        On Error Resume Next
        Upload.Save "d:\hosting\belaullach\senate\legislation"

        Dim picture
        For Each File in Upload.Files
            Ext = UCase(Right(File.Path, 3))
            If Ext <> "JPG" Then
                    If Ext <> "BMP" Then
                    Response.Write "File " & File.Path & " is not a .jpg or .bmp file." & "<BR>"
                    Response.write "You can only upload .jpg or .bmp files." & "<BR>" & "<BR>"
                    End if
            Else
                File.SaveAs Server.MapPath(("/senate/legislation") & "/" & File.fileName)
                f1=File.fileName
            End If
        Next
    End if

    fnm="/senate/legislation/"&f1
    imgop = "<html><body><script type=""text/javascript"">window.parent.CKEDITOR.tools.callFunction('1','"&fnm&"');</script></body></html>;"
    'imgop="callFunction('1','"&fnm&"',"");"
    Response.write imgop
%>

Ответ 5

Это подход, который я использовал. Это довольно просто и прекрасно работает.

В корневом каталоге редактора CK есть файл с именем config.js

Я добавил это (вам не нужен материал querystring, это только для нашего файлового менеджера). Я также включил некоторые скиннинг и изменение отображаемых по умолчанию кнопок:

CKEDITOR.editorConfig = function(config) {

    config.skin = 'v2';
    config.startupFocus = false;
    config.filebrowserBrowseUrl = '/admin/content/filemanager.aspx?path=Userfiles/File&editor=FCK';
    config.filebrowserImageBrowseUrl = '/admin/content/filemanager.aspx?type=Image&path=Userfiles/Image&editor=FCK';
    config.toolbar_Full =
    [
        ['Source', '-', 'Preview', '-'],
        ['Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Print', 'SpellChecker'], //, 'Scayt' 
        ['Undo', 'Redo', '-', 'Find', 'Replace', '-', 'SelectAll', 'RemoveFormat'],
        '/',
        ['Bold', 'Italic', 'Underline', 'Strike', '-', 'Subscript', 'Superscript'],
        ['NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', 'Blockquote'],
        ['JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock'],
        ['Link', 'Unlink', 'Anchor'],
        ['Image', 'Flash', 'Table', 'HorizontalRule', 'SpecialChar'],
        '/',
        ['Styles', 'Format', 'Templates'],
        ['Maximize', 'ShowBlocks']
    ];

};

Затем наш файловый менеджер вызывает это:

opener.SetUrl('somefilename');

Ответ 6

Статья в zerokspot, озаглавленная Пользовательские обратные вызовы файлов в CKEditor 3.0 обрабатывает это. Наиболее релевантный раздел приведен ниже:

Итак, все, что вам нужно сделать из файла браузера при выборе файла является вызов этого кода с правом номер обратного вызова (обычно 1) и URL выбранного файла:

window.opener.CKEDITOR.tools.callFunction(CKEditorFuncNum,url);

Для быстрого загрузчика процесс довольно похожи. Сначала я подумал, что редактор может слушать 200 HTTP-код возврата и, возможно, посмотрите в поле заголовка или что-то чтобы определить местоположение загруженный файл, но затем - через некоторый мониторинг Firebug - я заметил что все, что происходит после загрузки это следующий код:

<script type="text/javascript">
window.parent.CKEDITOR.tools.callFunction(CKEditorFuncNum,url, errorMessage); </script>

Если загрузка не выполнена, установите errorMessage для некоторой ненулевой длины строка и пустой URL-адрес, Вершина успеха.

Ответ 7

Начните с регистрации пользовательского браузера/загрузчика при создании экземпляра CKEditor.

<script type="text/javascript">
CKEDITOR.replace('content', {
    filebrowserUploadUrl: "Upload File Url",//http://localhost/phpwork/test/ckFileUpload.php
    filebrowserWindowWidth  : 800,
    filebrowserWindowHeight : 500
});
</script>

Код для загрузки файла (ckFileUpload.php) и поместите файл загрузки в корневой каталог вашего проекта.

// HERE SET THE PATH TO THE FOLDERS FOR IMAGES AND AUDIO ON YOUR SERVER (RELATIVE TO THE ROOT OF YOUR WEBSITE ON SERVER)

$upload_dir = array(
 'img'=> '/phpwork/test/uploads/editor-images/',
 'audio'=> '/phpwork/ezcore_v1/uploads/editor-images/'
);

// HERE PERMISSIONS FOR IMAGE
$imgset = array(
 'maxsize' => 2000,     // maximum file size, in KiloBytes (2 MB)
 'maxwidth' => 900,     // maximum allowed width, in pixels
 'maxheight' => 800,    // maximum allowed height, in pixels
 'minwidth' => 10,      // minimum allowed width, in pixels
 'minheight' => 10,     // minimum allowed height, in pixels
 'type' => array('bmp', 'gif', 'jpg', 'jpeg', 'png'),  // allowed extensions
);

// HERE PERMISSIONS FOR AUDIO
$audioset = array(
 'maxsize' => 20000,    // maximum file size, in KiloBytes (20 MB)
 'type' => array('mp3', 'ogg', 'wav'),  // allowed extensions
);

// If 1 and filename exists, RENAME file, adding "_NR" to the end of filename (name_1.ext, name_2.ext, ..)
// If 0, will OVERWRITE the existing file
define('RENAME_F', 1);

$re = '';
if(isset($_FILES['upload']) && strlen($_FILES['upload']['name']) >1) {
  define('F_NAME', preg_replace('/\.(.+?)$/i', '', basename($_FILES['upload']['name'])));  //get filename without extension

  // get protocol and host name to send the absolute image path to CKEditor
  $protocol = !empty($_SERVER['HTTPS']) ? 'https://' : 'http://';
  $site = $protocol. $_SERVER['SERVER_NAME'] .'/';
  $sepext = explode('.', strtolower($_FILES['upload']['name']));
  $type = end($sepext);    // gets extension
  $upload_dir = in_array($type, $imgset['type']) ? $upload_dir['img'] : $upload_dir['audio'];
  $upload_dir = trim($upload_dir, '/') .'/';

  //checkings for image or audio
  if(in_array($type, $imgset['type'])){
    list($width, $height) = getimagesize($_FILES['upload']['tmp_name']);  // image width and height
    if(isset($width) && isset($height)) {
      if($width > $imgset['maxwidth'] || $height > $imgset['maxheight']) $re .= '\\n Width x Height = '. $width .' x '. $height .' \\n The maximum Width x Height must be: '. $imgset['maxwidth']. ' x '. $imgset['maxheight'];
      if($width < $imgset['minwidth'] || $height < $imgset['minheight']) $re .= '\\n Width x Height = '. $width .' x '. $height .'\\n The minimum Width x Height must be: '. $imgset['minwidth']. ' x '. $imgset['minheight'];
      if($_FILES['upload']['size'] > $imgset['maxsize']*1000) $re .= '\\n Maximum file size must be: '. $imgset['maxsize']. ' KB.';
    }
  }
  else if(in_array($type, $audioset['type'])){
    if($_FILES['upload']['size'] > $audioset['maxsize']*1000) $re .= '\\n Maximum file size must be: '. $audioset['maxsize']. ' KB.';
  }
  else $re .= 'The file: '. $_FILES['upload']['name']. ' has not the allowed extension type.';

  //set filename; if file exists, and RENAME_F is 1, set "img_name_I"
  // $p = dir-path, $fn=filename to check, $ex=extension $i=index to rename
  function setFName($p, $fn, $ex, $i){
    if(RENAME_F ==1 && file_exists($p .$fn .$ex)) return setFName($p, F_NAME .'_'. ($i +1), $ex, ($i +1));
    else return $fn .$ex;
  }

  $f_name = setFName($_SERVER['DOCUMENT_ROOT'] .'/'. $upload_dir, F_NAME, ".$type", 0);
  $uploadpath = $_SERVER['DOCUMENT_ROOT'] .'/'. $upload_dir . $f_name;  // full file path

  // If no errors, upload the image, else, output the errors
  if($re == '') {
    if(move_uploaded_file($_FILES['upload']['tmp_name'], $uploadpath)) {
      $CKEditorFuncNum = $_GET['CKEditorFuncNum'];
      $url = $site. $upload_dir . $f_name;
      $msg = F_NAME .'.'. $type .' successfully uploaded: \\n- Size: '. number_format($_FILES['upload']['size']/1024, 2, '.', '') .' KB';
      $re = in_array($type, $imgset['type']) ? "window.parent.CKEDITOR.tools.callFunction($CKEditorFuncNum, '$url', '$msg')"  //for img
       : 'var cke_ob = window.parent.CKEDITOR; for(var ckid in cke_ob.instances) { if(cke_ob.instances[ckid].focusManager.hasFocus) break;} cke_ob.instances[ckid].insertHtml(\'<audio src="'. $url .'" controls></audio>\', \'unfiltered_html\'); alert("'. $msg .'"); var dialog = cke_ob.dialog.getCurrent();  dialog.hide();';
    }
    else $re = 'alert("Unable to upload the file")';
  }
  else $re = 'alert("'. $re .'")';
}

@header('Content-type: text/html; charset=utf-8');
echo '<script>'. $re .';</script>';

Документация Ck-редактора не понятна после того, как много R & D для загрузки пользовательских файлов, наконец, я нашел это решение. Это работает для меня, и я надеюсь, что это будет полезно и для других.