Skip to content

Instantly share code, notes, and snippets.

@taufik-nurrohman
Last active February 6, 2023 17:04
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save taufik-nurrohman/8370b6c52c6f1a21d82982a5af9f47ae to your computer and use it in GitHub Desktop.
Enable image upload in CKEditor 5 without using the Easy Image service.
/**
* This code is based on <https://github.com/pourquoi/ckeditor5-simple-upload>
* and will be implemented by <https://github.com/mecha-cms/extend.c-k-editor> in the future!
*/
// The upload adapter
var Adapter = function(loader, urlOrObject, t) {
var $ = this;
$.loader = loader;
$.urlOrObject = urlOrObject;
$.t = t;
$.upload = function() {
return new Promise(function(resolve, reject) {
$._initRequest();
$._initListeners(resolve, reject);
$._sendRequest();
});
};
$.abort = function() {
$.xhr && $.xhr.abort();
};
$._initRequest = function() {
$.xhr = new XMLHttpRequest();
var url = $.urlOrObject,
headers;
if (typeof url === "object") {
headers = url.headers;
url = url.url;
}
$.xhr.withCredentials = true;
$.xhr.open('POST', url, true);
if (headers) {
for (var key in headers) {
if (typeof headers[key] === "function") {
$.xhr.setRequestHeader(key, headers[key]());
} else {
$.xhr.setRequestHeader(key, headers[key]);
}
}
}
$.xhr.responseType = 'json';
};
$._initListeners = function(resolve, reject) {
var xhr = $.xhr,
loader = $.loader,
t = $.t,
genericError = t('Cannot upload file:') + ' ' + loader.file.name;
xhr.addEventListener('error', function() {
reject(genericError);
});
xhr.addEventListener('abort', reject);
xhr.addEventListener('load', function() {
var response = xhr.response;
if (!response || !response.uploaded) {
return reject(response && response.error && response.error.message ? response.error.message : genericError);
}
resolve({
'default': response.url
});
});
if (xhr.upload) {
xhr.upload.addEventListener('progress', function(evt) {
if (evt.lengthComputable) {
loader.uploadTotal = evt.total;
loader.uploaded = evt.loaded;
}
});
}
}
$._sendRequest = function() {
var data = new FormData();
data.append('upload', $.loader.file);
$.xhr.send(data);
};
};
// Create the editor
ClassicEditor.create(document.querySelector('textarea')).then(function(editor) {
console.log(editor);
editor.plugins.get('FileRepository').createUploadAdapter = function(loader) {
return new Adapter(loader, 'http://127.0.0.1/upload.php?token=b4d455', editor.t);
};
});
@taufik-nurrohman
Copy link
Author

Example:

<?php

$data = [
    'uploaded' => false,
    'error' => ['message' => 'Unknown error.']
];

if ($_SESSION['token'] !== $_GET['token']) {
    $data['error']['message'] = 'Invalid token.';
} else if (file_exists(ASSET_DIR . '/' . $_FILES['upload']['name']) {
    $data['error']['message'] = 'File already exists.';
} else {
    // Upload the image, etc.
   $data = [
        'uploaded' => true,
        'url' => ASSET_URL . '/' . $_FILES['upload']['name']
    ];
}

header('Content-Type: application/json');
echo json_encode($data);
exit;

@boxfrommars
Copy link

boxfrommars commented Feb 20, 2019

there is a bug when url is an object: you rewrite url object with string and headers is always undefined

if (typeof url === "object") {
    url = url.url;
    headers = url.headers;
}

this lines should be in a reverse order.

Okay!

@AdamMiltonBarker
Copy link

AdamMiltonBarker commented Feb 6, 2023

$_FILES is always empty.

@taufik-nurrohman
Copy link
Author

@AdamMiltonBarker CKEditor 5 already has its own online builder so this code is considered obsolete. It also has an extension called SimpleUploadAdapter which works the same.

@AdamMiltonBarker
Copy link

@AdamMiltonBarker CKEditor 5 already has its own online builder so this code is considered obsolete. It also has an extension called SimpleUploadAdapter which works the same.

I found an easier way:


        ClassicEditor.create( document.querySelector( '#editor' ), {
            // toolbar: [ 'heading', '|', 'bold', 'italic', 'link' ]
            ckfinder: {
                uploadUrl: '../photo-upload'
            }
        })
        .then( editor => {
            window.editor = editor;
        })
        .catch( err => {
            console.error( err.stack );
        });

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment