Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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") {
url = url.url;
headers = url.headers;
}
$.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);
};
});
@tovic

This comment has been minimized.

Copy link
Owner Author

tovic commented Oct 14, 2018

Your upload.php file must return one of these response:

{
    "uploaded": true,
    "url": "http://127.0.0.1/uploaded-image.jpg"
}
{
    "uploaded": false,
    "error": {
        "message": "Could not upload this image."
    }
}
@tovic

This comment has been minimized.

Copy link
Owner Author

tovic commented Oct 14, 2018

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

This comment has been minimized.

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.