[ckeditor] 커스텀 파일 브라우저 / 업 로더를 CKEditor와 어떻게 통합 할 수 있습니까?

공식 문서는 명확하지 않습니다. 사용자 정의 파일 브라우저 / 업 로더를 CKEditor와 통합하는 올바른 방법은 무엇입니까? (v3-FCKEditor 아님)



답변

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>

사용자 정의 코드는 CKEditorFuncNum이라는 GET 매개 변수를 수신합니다. 저장하십시오-이것이 콜백 함수입니다. 그것을 넣어 봅시다$callback .

누군가 파일을 선택하면이 JavaScript를 실행하여 어떤 파일이 선택되었는지 CKEditor에 알립니다.

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

여기서 “url”은 선택한 파일의 URL입니다. 선택적 세 번째 매개 변수는 “불법 파일”등의 표준 경고 대화 상자에 표시 할 텍스트 일 ​​수 있습니다. 세 번째 매개 변수가 오류 메시지 인 경우 url을 빈 문자열로 설정하십시오.

CKEditor의 “upload”탭은 “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 문서는이 모든 것에 불완전하지만 위의 내용을 따르면 챔피언처럼 작동합니다.


답변

이전 FCKEditor에서 사용 가능한 FileBrowser를 CKEditor에 통합하는 방법에 대한 작은 자습서를 게시했습니다.

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

그렇게하기위한 단계별 지침이 포함되어 있으며 매우 간단합니다. 이 정보를 찾는 사람이이 튜토리얼이 도움이되기를 바랍니다.


답변

방금 학습 과정을 직접 밟았습니다. 나는 그것을 알아 냈지만 문서가 나에게 다소 위협적인 방식으로 쓰여졌다는 데 동의합니다. 저에게 가장 큰 “아하”순간은 브라우징을 위해 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) 당신이 당신의 onclick을 공급 처리기에 다음 선택의 목록을 제공하는 PHP & JS를 사용하고, 당신이 선택한 이미지에 두 개의 인수는 URL / 경로와 CKeditor 함수를 호출하고 URL에서 CKeditor가 제공 한 CKEditorFuncNum :

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

Simarly, 업 로더는 단순히 사용자 가 제공 한 URL (예 : upload.php)을 호출 하고 다시 $ _GET [ ‘CKEditorFuncNum’]을 제공합니다. 대상은 iframe이므로 $ _FILES에서 파일을 저장 한 후 다음과 같이 피드백을 CKeditor에 전달합니다.

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


답변

나는 이것을 알아 내기 위해 잠시 보냈고 여기에 내가 한 일이 있습니다. 나는 그것이 내가 필요로하는 것처럼 그것을 아주 간단하게 세분화했습니다.

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를 업로드 스크립트로 교체하되 페이지가 동일한 내용을 출력하는지 확인하십시오.

<%@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
%>


답변

이것이 제가 사용한 접근 방식입니다. 매우 간단하고 잘 작동합니다.

CK 편집기 루트 디렉토리에는 config.js라는 파일이 있습니다.

나는 이것을 추가했습니다 (쿼리 스트링은 필요하지 않습니다. 이것은 파일 관리자를위한 것입니다). 또한 표시된 기본 버튼의 일부 스키닝 및 변경을 포함했습니다.

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');


답변

CKEditor 3.0의 Custom filebrowser callbacks 라는 제목의 zerokspot의 기사가이를 처리합니다. 가장 관련성이 높은 섹션은 다음과 같습니다.

따라서 파일을 선택했을 때 파일 브라우저에서해야 할 일은 올바른 콜백 번호 (일반적으로 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을 길이가 0이 아닌 문자열로 설정하고 URL을 비우고 성공하면 그 반대의 경우도 마찬가지입니다.


답변

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-editor 문서는 사용자 정의 파일 업로드를 위해 많은 R & D를 수행 한 후 명확하지 않습니다. 마침내이 솔루션을 찾았습니다. 그것은 저에게 효과적이며 다른 사람들에게도 도움이되기를 바랍니다.