I\'m using CKEditor and would like to be able to allow users to upload and embed images in the Text Editor...
The following JS is what loads the CKEditor:
My latest issue was how to integrate CKFinder for image upload in CKEditor. Here the solution.
Download CKEditor and extract in your web folder root.
Download CKFinder and extract withing ckeditor folder.
Then add references to the CKEditor, CKFinder and put
<CKEditor:CKEditorControl ID="CKEditorControl1" runat="server"></CKEditor:CKEditorControl>
to your aspx page.
In code behind page OnLoad event add this code snippet
protected override void OnLoad(EventArgs e)
{
CKFinder.FileBrowser _FileBrowser = new CKFinder.FileBrowser();
_FileBrowser.BasePath = "ckeditor/ckfinder/";
_FileBrowser.SetupCKEditor(CKEditorControl1);
}
Edit Confic.ascx file.
public override bool CheckAuthentication()
{
return true;
}
// Perform additional checks for image files.
SecureImageUploads = true;
(source)
This simple demo may help you in getting what you want. Here is the html/php code from where you want to upload the image:
<html>
<head>
<script src="http://cdn.ckeditor.com/4.6.2/standard-all/ckeditor.js"></script>
</head>
<body>
<form action="index.php" method="POST" style="width:500xp;">
<textarea rows="5" name="content" id="content"></textarea>
<br>
<input type="submit" name="submit" value="Post">
</form>
<script>
CKEDITOR.replace( 'content', {
height: 300,
filebrowserUploadUrl: "upload.php"
});
</script>
</body>
</html>
and here is the code for upload.php file.
<?php
if(isset($_FILES['upload']['name']))
{
$file = $_FILES['upload']['tmp_name'];
$file_name = $_FILES['upload']['name'];
$file_name_array = explode(".", $file_name);
$extension = end($file_name_array);
//we want to save the image with timestamp and randomnumber
$new_image_name = time() . rand(). '.' . $extension;
chmod('upload', 0777);
$allowed_extension = array("jpg", "gif", "png");
if(in_array($extension, $allowed_extension))
{
move_uploaded_file($file, 'upload/' . $new_image_name);
$function_number = $_GET['CKEditorFuncNum'];
$url = 'upload/' . $new_image_name;
$message = '';
echo "<script type='text/javascript'>window.parent.CKEDITOR.tools.callFunction($function_number, '$url', '$message');</script>";
}
}
?>
Note: Don't forget to create a folder "upload" in the same folder and keep all the three files in the same directory. Later you may change their directories once you understand how it works. Also not forget to press send it to the server as shown in picture below.
For those have same problem in Grails ckeditor plugin Give
filebrowserUploadUrl:'/YourAppName/ck/ofm'
to invoke the function that handles image uploade.if you want use your own customized function you can give that file path.
The URL should point to your own custom filebrowser url you might have.
I have already done this in one of my projects, and I have posted a tutorial on this topic on my blog
http://www.mixedwaves.com/2010/02/integrating-fckeditor-filemanager-in-ckeditor/
The tutorial gives a step by step instructions about how to integrate the inbuilt FileBrowser of FCKEditor in CKEditor, if you don't want to make our own. Its pretty simple.
With CKeditor version 4 something, the editor expects JSON in return from the server side. Older version may need a text/html type of response, bearing a javascript snippet. See this link for an explanation of that Explanation of return formats. On the server side, and if you are using C#, you can make a data model like this:
namespace editors.Models
{
public class PostModel
{
public string CKEditor { get; set; } // for older editors
public string CKEditorFuncNum { get; set; } // for older editors
public string langCode { get; set; } // for older editors
public int uploaded { get; set; }
public string filename { get; set; }
}
}
And return the result from your upload routine with this:
PostModel fez = new PostModel { CKEditor = "TheEditor1", CKEditorFuncNum = "1", langCode = "en", uploaded = 1, filename = "/images/in/" + filenameVariable };
return Ok(fez);
Although .net most probably makes json of it automatically, ensure you are returning content-type application/json.
As a side-note for those wanting to check if the uploaded file really is an image file; if you are using Asp.net core, the system.drawing library needs to be installed in a non-standard way. Here's how to do that
Also note that you can change the type of posting in the config.js file to config.filebrowserUploadMethod='form'; , as opposed to config.filebrowserUploadMethod='xhr';
I've recently needed an answer to this as well, and it took me several hours to figure it out, so I decided to resurrect this question with some more up-to-date information and a full answer.
Eventually I stumbled upon this tutorial that explained it to me pretty well. For stackoverflow sake, I will reiterate the tutorial here in case it is removed. I will also include some changes that I made to the tutorial that make this a more flexible solution.
Let's start with any of the releases of ckeditor, (Basic, standard, full, custom) the only requirement is that you have the addon image and filebrowser
(As of writing this, all packages include these 2 addons except for the basic one, but it can be added to the basic one)
After you upload necessary ckeditor files, make sure your installation is working.
Make sure you link your ckeditor.js file script <script src="ckeditor/ckeditor.js"></script>
and then initialize it like so:
$(document).ready(function() {
CKEDITOR.replace( 'editor1' );
});
<textarea name="editor1"></textarea>
Now we have to tell CKEditor that we want to enable uploading. You can do this by going into your ckeditor folder, and editing `config.js'. We need to add this line:
config.filebrowserUploadUrl = '/uploader/upload.php';
somewhere inside the main function E.G
CKEDITOR.editorConfig = function( config ) {
// Define changes to default configuration here. For example:
// config.language = 'fr';
// config.uiColor = '#AADC6E';
config.filebrowserUploadUrl = '/uploader/upload.php';
};
NOTE: This URL is from your project root. No matter where you load this file from, it will start at your site index. Meaning, if your URL is example.com, this URL leads to
http://example.com/uploader/upload.php
After this, CKEditor configuration is done! That was easy eh?
In fact, if you go and test your image uploading again now, you will get an upload option, though it won't quite work yet.
Now you'll notice in the step before this one that it ends with an upload.php
file. This is the part that stumped me, I figured there would be some default that can go with this but as far as I know there is not. Luckily, I found one that works, and I made some changes to it to allow more customization.
So let's go to the path that you supplied in the last step, for continuity in this tutorial I am going to use /uploader/upload.php
.
At this location, make a file called (you guessed it) upload.php
.
This file is going to handle our file uploads.
I will put in my custom upload class, but it's based on this github that I found and forked.
upload.php:
<?php
// Upload script for CKEditor.
// Use at your own risk, no warranty provided. Be careful about who is able to access this file
// The upload folder shouldn't be able to upload any kind of script, just in case.
// If you're not sure, hire a professional that takes care of adjusting the server configuration as well as this script for you.
// (I am not such professional)
// Configuration Options: Change these to alter the way files being written works
$overwriteFiles = false;
//THESE SETTINGS ONLY MATTER IF $overwriteFiles is FALSE
//Seperator between the name of the file and the generated ending.
$keepFilesSeperator = "-";
//Use "number" or "random". "number" adds a number, "random" adds a randomly generated string.
$keepFilesAddonType = "random";
//Only usable when $keepFilesAddonType is "number", this specifies where the number starts iterating from.
$keepFilesNumberStart = 1;
//Only usable when $keepFilesAddonType is "random", this specifies the length of the string.
$keepFilesRandomLength = 4;
//END FILE OVERWRITE FALSE SETTINGS
// Step 1: change the true for whatever condition you use in your environment to verify that the user
// is logged in and is allowed to use the script
if (true) {
echo("You're not allowed to upload files");
die(0);
}
// Step 2: Put here the full absolute path of the folder where you want to save the files:
// You must set the proper permissions on that folder (I think that it's 644, but don't trust me on this one)
// ALWAYS put the final slash (/)
$basePath = "/home/user/public_html/example/pages/projects/uploader/files/";
// Step 3: Put here the Url that should be used for the upload folder (it the URL to access the folder that you have set in $basePath
// you can use a relative url "/images/", or a path including the host "http://example.com/images/"
// ALWAYS put the final slash (/)
$baseUrl = "http://example.com/pages/projects/uploader/files/";
// Done. Now test it!
// No need to modify anything below this line
//----------------------------------------------------
// ------------------------
// Input parameters: optional means that you can ignore it, and required means that you
// must use it to provide the data back to CKEditor.
// ------------------------
// Optional: instance name (might be used to adjust the server folders for example)
$CKEditor = $_GET['CKEditor'] ;
// Required: Function number as indicated by CKEditor.
$funcNum = $_GET['CKEditorFuncNum'] ;
// Optional: To provide localized messages
$langCode = $_GET['langCode'] ;
// ------------------------
// Data processing
// ------------------------
// The returned url of the uploaded file
$url = '' ;
// Optional message to show to the user (file renamed, invalid file, not authenticated...)
$message = '';
// in CKEditor the file is sent as 'upload'
if (isset($_FILES['upload'])) {
// Be careful about all the data that it's sent!!!
// Check that the user is authenticated, that the file isn't too big,
// that it matches the kind of allowed resources...
$name = $_FILES['upload']['name'];
//If overwriteFiles is true, files will be overwritten automatically.
if(!$overwriteFiles)
{
$ext = ".".pathinfo($name, PATHINFO_EXTENSION);
// Check if file exists, if it does loop through numbers until it doesn't.
// reassign name at the end, if it does exist.
if(file_exists($basePath.$name))
{
if($keepFilesAddonType == "number") {
$operator = $keepFilesNumberStart;
} else if($keepFilesAddonType == "random") {
$operator = bin2hex(openssl_random_pseudo_bytes($keepFilesRandomLength/2));
}
//loop until file does not exist, every loop changes the operator to a different value.
while(file_exists($basePath.$name.$keepFilesSeperator.$operator))
{
if($keepFilesAddonType == "number") {
$operator++;
} else if($keepFilesAddonType == "random") {
$operator = bin2hex(openssl_random_pseudo_bytes($keepFilesRandomLength/2));
}
}
$name = rtrim($name, $ext).$keepFilesSeperator.$operator.$ext;
}
}
move_uploaded_file($_FILES["upload"]["tmp_name"], $basePath . $name);
// Build the url that should be used for this file
$url = $baseUrl . $name ;
// Usually you don't need any message when everything is OK.
// $message = 'new file uploaded';
}
else
{
$message = 'No file has been sent';
}
// ------------------------
// Write output
// ------------------------
// We are in an iframe, so we must talk to the object in window.parent
echo "<script type='text/javascript'> window.parent.CKEDITOR.tools.callFunction($funcNum, '$url', '$message')</script>";
?>
The changes that I made to this class allow you to enable/disable file overwriting and gives you some options for when you don't want to overwrite files. The original class always overwrites with no options.
By default this class is set to keep all files, without overwriting. You can play around with those settings to better suit your needs.
If you'll notice, there is a section of code that is just an if(true)
statement, which is always true obviously
if (true) {
echo("You're not allowed to upload files");
die(0);
}
This is for security. This is where you should check if the user uploading is logged in/allowed to upload. If you're not worried about that, you can just remove these lines of code or set it to if(false)
(NOT RECOMMENDED)
You will also need to edit the $basePath
and the $baseUrl
variables to fit your servers needs, or else it will not work. Everything below that can be left alone unless you want to play around.
This class does not offer file protection, you may want to work with it some to make it more safe, so people can't upload scripts or viruses to your server.
I hope that this little tutorial helped someone, as I worked far too long on trying to get this to work for myself, and I hope I can save someone else some time.
There is also some neat troubleshooting steps on that tutorial which I linked above, that may be able to help you find what's going wrong if something is.