I am using the plugin image2, and would like the ability to upload images to our server.
I have added config.filebrowserUploadUrl="/CkeditorImageUpload"
to my config.js, and the "Image properties" dialog does have a upload image tab which can upload images to my server. So far so good but the problem is that when an image is uploaded, the url field is not updated in the image properties dialog so the user can't use the uploaded image.
Should my /CkeditorImageUpload return something special to cause the dialog to update?
Yes, CKEditor expects the upload script to return a <script> tag that calls an anonymous function.
Everything is described in the documentation http://docs.ckeditor.com/#!/guide/dev_file_browser_api - see Example 3 with a PHP example of script that sends a response after a file upload:
<?php
// Required: anonymous function reference number as explained above.
$funcNum = $_GET['CKEditorFuncNum'] ;
// Optional: instance name (might be used to load a specific configuration file or anything else).
$CKEditor = $_GET['CKEditor'] ;
// Optional: might be used to provide localized messages.
$langCode = $_GET['langCode'] ;
// Check the $_FILES array and save the file. Assign the correct path to a variable ($url).
$url = '/path/to/uploaded/file.ext';
// Usually you will only assign something here if the file could not be uploaded.
$message = ;
echo "<script type='text/javascript'>window.parent.CKEDITOR.tools.callFunction($funcNum, '$url', '$message');</script>";
?>
Related
I wan't to know "How to show only image on the url not other content even html?". Like see this url link of Image. This url only shows image not any other content on webpage and also see the url of website it's dynamic url not a specific image url.
So, how to achieve that?
You simply make the request to the URL of the image.
For example, if your image is called test1.png and you have it in a directory called images, you would make the URL like this:
https://your.domain/images/test1.png
If you want to hide the full path to the images and serve them through a page (so you have some control over the request for some reason), you can do something more like the following. Let's call the PHP page img.php. And the request could be like
https://your.domain/img.php/test1
<?php
$request = './default.png';
if (isset($_SERVER['PATH_INFO'])){
$request = './images'.$_SERVER['PATH_INFO'].'.png';
if (! file_exists($request)){
$request = './default.png';
}
}
// we now know we have a valid request and the file was found
header('Content-type: image/png');
header('Content-Length: '.filesize($request));
echo file_get_contents($request);
exit;
?>
With this approach you could have any number of images in the /images/ directory and serve them if they match the request.
The website in your sample maybe using the same $_SERVER['PATH_INFO'] info approach but would be dynamically creating the image using the passed variables and explode('/',$_SERVER['PATH_INFO']) along with imagecreate()
A very quick hack version would be something like the following. The request would be like this:
https://your.domain/test.php/100x50/919/222
And the very quick code, with almost no error checking could be:
<?php
function hexToColor($hx){
$rgb = array(0,0,0);
if (strlen($hx) == 3){
$rgb[0] = hexdec($hx[0].$hx[0]);
$rgb[1] = hexdec($hx[1].$hx[1]);
$rgb[2] = hexdec($hx[2].$hx[2]);
} else {
$rgb[0] = hexdec($hx[0].$hx[1]);
$rgb[1] = hexdec($hx[2].$hx[3]);
$rgb[2] = hexdec($hx[4].$hx[5]);
}
return $rgb;
}
// default values
$sizeW = 100;
$sizeH = 100;
$bg = array(0,0,0);
$fg = array(255,255,255);
if (isset($_SERVER['PATH_INFO'])){
$opts = explode('/',substr($_SERVER['PATH_INFO'],1));
$bgSet = false;
foreach($opts as $k => $v){
// check for a width x height request
if (strpos($v,'x')){
$tmp = explode('x',$v);
$sizeW = $tmp[0];
$sizeH = $tmp[1];
} elseif ($bgSet){
// must be a foreground request
$fg = hexToColor($v);
} else {
$bg = hexToColor($v);
$bgSet = true;
}
}
}
header("Content-Type: image/png");
$im = #imagecreate($sizeW,$sizeH)
or die("Cannot Initialize new GD image stream");
$background_color = imagecolorallocate($im,$bg[0],$bg[1],$bg[2]);
$text_color = imagecolorallocate($im,$fg[0],$fg[1],$fg[2]);
imagestring($im,1,5,5,$sizeW.' x '.$sizeH,$text_color);
imagepng($im);
imagedestroy($im);
exit;
?>
But I would strongly recommend a heap of error checking before using that code!
As I understand you want to dynamically update the picture.
You can see that on their main website they created a form for the entered values:
After that, on the picture URL there are all the values you need to display this image:
https://dummyimage.com/600x400/8a1a8a/232dba&text=xzcxzcnbngh
which is this image:
what you can't see is their server side, which takes the parameters 600x400/8a1a8a/232dba&text=xzcxzcnbngh, creates a picture using their server and returning it to you.
I'll suggest you to create a server side that will return a picture and text based on the given parameters.
based on your server you will need to find out how to create the picture and return it.
As you can see here, I just modified the "src" value of the and it changed the text on the photo.
which means that their server receives the request and send back the image.
If you want a simple solution you could just send back those parameters to your page scripts, and create this image element using JavaScript.
That way, your html code will be clean without even the img element tag.
create your img in JS and send put it on the html body.
Image placeholder that’s updated by scripting
HTML code:
<img id="abc" src="">
Javascript code:
var abcImage = document.getElementById('abc');
abcImage.src = 'https://dummyimage.com/600x400/000/fff';
The issue I'm facing is, I get the following error while trying to upload some pdfs your upload file is not PDF file. However, this error doesn't show up for all pdfs, it's only for some pdf files I get this error.
<?php
$error = $_FILES['fileToUpload']['error'];
//get upload file type
$type = $_FILES['fileToUpload']['type'];
$action = "upload";
//get file name
$picname = $_FILES['fileToUpload']['name'];
$nameArray = explode(".", $picname);
if {
//check files
//filetoUpload code
}
?>
The issue is that, in the url: '../controller/uploadFile.php' even if the file is PDF, $type = $_FILES['fileToUpload']['type']; will return empty and then it will go into the condition else if($type !="application/pdf" ) and pop up the alert your upload file is not PDF file.. Like I said, this issue is with most of the pdf file. However, some pdf files manage to get uploaded without any issue and if a pdf file gets uploaded, then $type will be application/pdf.
Your input will be highly appriciated.
---UPDATE---
The issue is with $_FILES, it's not fetching the pdf file details for some reason
The issue has been resolved. I checked '$error= $_FILES['fileToUpload']['error']; and the value was returning 1
Value: 1; The uploaded file exceeds the upload_max_filesize directive in php.ini.```
You could better check the extension, this also prevents malicious users to upload exe or zip files when they provide the header Content-Type: application/pdf. Also not all browsers/api libraries specify a Content-Type.
If your filename does not contain a path, check it with a regex so people cannot upload files to directories they shouldn't (ex ../../cache/exe). use for example
preg_match("/^[a-zA-Z0-9_+\\- ]+\\.pdf$/", $filename) to check if it is a pdf.
Do never do unlink('files/' . $filename); when $filename could be anything submitted by the user. Delete ../index.php could destroy your server.
Currently I am using angular-ckeditor to add CKEditor 4.
In my template, I display it as:
<div ng-repeat="editor in editors">
<div ckeditor="options" ng-model="editor.content"></div>
</div>
I'm looking for a way to upload images to CKEditor from desktop. As far as I understand, angular-ckeditor and CKEditor libraries are separate, so I can add widgets and plugins easily.
The problem is that I can't seem to find the right plugins/widgets (that do NOT use jQuery), which will help me to upload an image from desktop. I made it work only with image links.
There is not a lot of documentation about it on the official website. They say to use PHP files that will upload and browse images, but don't really explain how, especially with angular-ckeditor. So I have several questions now:
Which plugins do I need for a simple image uploader, so that I can paste images into CKEditor?
How do I set it up with AngularJS?
What does a PHP file uploader(/browser) look like?
What I have tried so far doesn't even change the CKEditor tabs (it should change the image properties dialog by adding an "Upload" tab and some other UI). So clearly I'm missing a solid tutorial somewhere for all of this.
(I could also try to switch to ng-ckeditor, if a solution with this would be simpler)
First, let's take a look at some basics without Angular. For CKEditor version 4, we can initialize an editor with the filebrowserImageUploadUrl configuration option, which enables functionality from the File Browser API:
CKEDITOR.replace('editor', {
filebrowserImageUploadUrl: '/upload.php?type=image'
});
This just loads an editor instance onto a <textarea name="editor">. Because we set the filebrowserImageUploadUrl option, the Upload tab becomes available in the editor's image dialog. The example value, /upload.php?type=image, is the URL to the PHP script on the server that handles the uploaded image files.
When a user uploads an image, CKEditor will send the image to this URL on the server. The handler at this URL should validate the request, resize the image (if needed), and move the uploaded image to a permanent location on the server. Then, the handler sends an HTML response back to CKEditor with the image's public URL.
Of course, we can write the server-side handler in any language. Here's a basic example for PHP that we'll save as upload.php:
<?php
$tempName = $_FILES['upload']['tmp_name'];
$fileName = uniqid() . $_FILES['upload']['name'];
$uploadPath = '/path/to/uploads/' . $fileName;
$imageUrl = 'http://example.com/uploads/' . $fileName;
$success = move_uploaded_file($tempName, $uploadPath);
$html = '<script>window.parent.CKEDITOR.tools.callFunction(%s, "%s", "%s");</script>';
$message = $success ? 'Uploaded successfully.' : 'Upload failed.';
echo sprintf($html, $_GET['CKEditorFuncNum'], $imageUrl, $message);
This script places an uploaded image into the web server's uploads/ directory so the browser can fetch the image. It passes back the CKEditorFuncNum parameter from the request to identify the appropriate callback for the upload. This example provides some basic protection against duplicate filenames, but, for a real-world application, we'd need to add security, validation, and error handling (authentication, CSRF, file type checking, max size, file name sanitization, etc.).
So far, this all works with CKEditor's standard, built-in functionality (no plugins, Angular, or jQuery needed). To enable users to drag-and-drop or paste images into the editor, we can add the Upload Image plugin to our CKEditor build (or use the standard-all distribution from the CKEditor CDN).
We need to declare the plugin when initializing the editor:
CKEDITOR.replace('editor', {
extraPlugins: 'uploadimage',
filebrowserImageUploadUrl: '/upload.php?type=image'
});
...and then extend our upload.php script to return the JSON response expected by the plugin. Add this block before the last three lines of the previous example:
if (isset($_GET['responseType']) && $_GET['responseType'] === 'json') {
echo json_encode([
'uploaded' => $success,
'fileName' => $fileName,
'url' => $imageUrl,
]);
return;
}
The Upload Image plugin sends the responseType=json URL parameter that the server-side script can check for to determine which type of response to send back.
Finally, let's take a look at how to initialize an editor using the angular-ckeditor package described in the question:
<div ng-controller="EditorCtrl as editor">
<textarea ckeditor="editor.options" ng-model="editor.content"></textarea>
</div>
var myApp = angular.module('myApp', ['ckeditor'])
myApp.controller('EditorCtrl', function () {
this.options = {
extraPlugins: 'uploadimage',
filebrowserImageUploadUrl: '/image-upload.php?type=image'
};
});
As we can see, we don't need to do much to "angularize" this. Once we create our template, we declare the same configuration options that we'd pass to the plain CKEDITOR.replace() on a controller that we reference on an element with the ckeditor directive.
I wonder whether someone may be able yo help me please.
I've put together this page which allows users to view a gallery of their uploaded images.
Upon initial upload, the physical images are saved in the following file structure:
UploadedFiles/userid/locationid/image and the details of the image i.e. description etc are saved in an xml file called files.xml which is in the same directory as the physical images.
I'm now working on allowing the user to be able to delete these images.
By way of a deletion icon under each image, I've, admitedly with some help, put together the following which successfully deletes the physical image.
'Deletion Icon Onclick Event'
<script type="text/javascript">
Galleria.ready(function() {
this.$('thumblink').click();
$(".galleria-image").append(
"<span class='btn-delete ui-icon ui-icon-trash'></span>");
$(".btn-delete").live("click", function(){
var img = $(this).closest(".galleria-image").find("img");
// send the AJAX request
$.ajax({
url : 'delete.php',
type : 'post',
data : { image : img.attr('src') },
success : function(){
alert('Deleting image... ');
img.parent().fadeOut('slow');
}
});
return false;
});
});
</script>
Original 'delete.php'
<?php
if (!empty($_POST)) {
$image = $_POST['image'];
if (file_exists($image)) {
unlink($image);
}
}
?>
Updated 'delete.php'
<?php
if (!empty($_POST)) {
$image = $_POST['image'];
if (file_exists($image)) {
unlink($image);
}
}
$doc = new DOMDocument;
$doc->load('files.xml');
$thedocument = $doc->documentElement;
$list = $thedocument->getElementsByTagName('files');
$nodeToRemove = null;
foreach ($list as $domElement){
$attrValue = $domElement->getAttribute('file_name');
if ($attrValue == 'image') {
$nodeToRemove = $domElement;
}
}
if ($nodeToRemove != null)
$thedocument->removeChild($nodeToRemove);
echo $doc->saveXML();
?>
The problem I'm having is deleting the xml node form the xml file. I've provided an extract of the XML file below.
<?xml version="1.0" encoding="utf-8" ?>
- <files>
<file name="stag.jpg" source="stag.jpg" size="21341" originalname="stag.jpg" description="No description provided" userid="1" locationid="1" />
</files>
I've done quite a bit of research about how to go about this and found that jQuery had it's own command i.e. jQuery.remove which I thought would be able to delete the node. Following the brief tutorial I added the following to the end of my 'Onclick Event' script:
var doc = $(files.xml);
doc.find('file_name:src').remove();
Unfortunately, although I don't receive a specific error, the node isn't being deleted from the file. I'm a complete beginner when it comes to XML so perhaps I'm looking at this too simplistically.
I just wondered wheteher someone could perhaps have a look at this please and let me know where I'm going wrong.
Many thanks and regards
This is because JavaScript(JQuery) loads the XML DOM in memory and then when you delete a node,
it gets deleted from the in-memory xml doc(the object).
It wont be removed from the physical XML file.
JS runs in a sandbox Browser environment and cannot alter local files on the system.
and if you are trying to load xml from a remote server then its a very bad idea.
the XML file from remote server is downloaded as temp file and then when you load XML again an in-memory DOM is created and the node is deleted from it.
So in case you want the actual file to be changed,
you will need to use AJAX and send some HTTP request to your server to do the same to the physical file.
UPDATE:
Check this tutorial
http://www.phpeveryday.com/articles/PHP-XML-Removing-Node-P415.html
and try to load the xml file in your delete.php and remove the corresponding node from it and then save this xml back to the original file which will be overwritten.
I have a feeling security concerns may not allow this but is it possible to generate a file with JavaScript and allow the user to drag it to the desktop (or file system)?
The following code drags out a file from a server
files[0].addEventListener("dragstart",function(evt){
evt.dataTransfer.setData("DownloadURL", "application/octet-stream:Eadui2.ttf:http://thecssninja.come/demo/gmail_dragout/Eadui.ttf");
},false);
And with the below code I can generate a file and have it download but I can't set the file name or let the user select the location.
var uriContent = "data:application/octet-stream," + encodeURIComponent(JSON.stringify(map));
location.href = uriContent;
Ideally I'd like a magical combination of both.
following code is currently working in Chrome only:
// generate downloadable URL, file name here will not affect stored file
var url = URL.createObjectURL(new File([JSON.stringify(map)], 'file_name.txt'));
// note that any draggable element may be used instead of files[0]
// since JSON.stringify returns a string, we use 'text' type in setData
files[0].addEventListener("dragstart", function(evt) {
evt.dataTransfer.setData("DownloadURL", "text:file_name.txt:" + url);
}, false);
now, dragging our files[0] element from the browser to desktop or file system, will store there a text file called, file_name.txt.
Feel free to choose another file name :)
This is only possible for Chrome, and even in Chrome you can't set the location. If using only Chrome is okay then you will have the following options:
Stick with Drag n' Drop like from the CSS Ninja's tutorial, then you should try Ben's answer. encodeURIComponent is one way, but if you have the file generated using BlobBuilder then you can use window.webkitURL.createObjectURL() to get the file's URL. You can also try using FileWriter() with requestFileSystem(TEMPORARY, ...).
Chrome supports download attribute for anchor tags so you can have regular link for the user to click (dragging also works):
Download
For cross browser support I suggest Downloadify.
You could try sending it to the server, saving the file, checking the return value and firing the download file function, followed by a server file that deletes the file from the server.
Something like this (with jQuery)
$.ajax({
url: 'saveFile.php',
method: 'post',
data: {
Filedata: data// file data variable
},
success: function(d) {
// save file function, where d is the filename
}
})
PHP:
$filename = ;//generate filename
file_put_contents($filename, $_POST['Filedata']);
echo $filename;
Obviously there is more to it but that should be the basics