Export multiple Highchart as Zip file to my project directory - php

I have successfully created total 4 different charts in one my page.
I have one button "Download Selected Chart" and on click of this button I need to create one ZIP file with selected chart PDF, Means if I select three charts then create a ZIP with three charts PDF.
Highchair provides functionality to download chart as PDF, SVG, PNG etc but I amn't able to do for multiple selected charts.
I check Highchart export server document -
http://www.highcharts.com/docs/export-module/setting-up-the-server but I don't understand how to use this.
please help me if anyone has an idea, how I can do this?

An example solution to this would be:
Create your charts
var options1 = {
// ...
};
$('#chart1').highcharts(options1);
Ask the Highcharts export server to generate an image of the chart
var exportUrl = 'http://export.highcharts.com/';
var d1 = $.ajax({
url: exportUrl,
// ...
});
Fetch the contents of the generated image
$.when(d1).done(function(v1) {
var p1 = new JSZip.external.Promise(function (resolve, reject) {
JSZipUtils.getBinaryContent(exportUrl + v1[0], function(err, data) {
// ...
});
});
// ...
Use JSZip to construct and save the ZIP file with the contents of the generated images
// ...
Promise.all([p1]).then(function(values) {
var zip = new JSZip();
zip.file("chart1.png", values[0], {binary:true});
zip.generateAsync({type:"blob"})
.then(function(content) {
saveAs(content, "charts.zip");
});
});
});
You can see this (very scrappy) JSFiddle demonstration of how you could get the ZIP file. The steps are as described above, but not connected to any button and instead executed immediately upon entering the site.

Here i post my solution that is work for me.
On Button click, get svg image using High chart export server.
// get selected checkbox
$('.selected_checkbox').each(function( index ){
var obj = {},chart;
chart = $('#each_chart').highcharts();
obj.svg = chart.getSVG();
obj.type = 'image/png';
obj.async = true;
obj.id = chart_id;
// ajax call for svg
$.ajax({
type: "POST",
url: url,// u need to save svg in your folder
data: obj,
success: function(data)
{
// redirect to php function and create zip
window.location = 'php function call';
}
)}
Ajax Function call to create SVG..
ini_set('magic_quotes_gpc', 'off');
$type = $_POST['type'];
$svg = (string) $_POST['svg'];
$filename = 'name';
$id = $_POST['id'];
if (get_magic_quotes_gpc()) {
$svg = stripslashes($svg);
}
// check for malicious attack in SVG
if(strpos($svg,"<!ENTITY") !== false || strpos($svg,"<!DOCTYPE") !== false){
exit("the posted SVG could contain code for a malicious attack");
}
$tempName = $filename.'_'.$id;
// allow no other than predefined types
if ($type == 'image/png') {
$typeString = '-m image/png';
$ext = 'png';
} elseif ($type == 'image/jpeg') {
$typeString = '-m image/jpeg';
$ext = 'jpg';
} elseif ($type == 'application/pdf') {
$typeString = '-m application/pdf';
$ext = 'pdf';
} elseif ($type == 'image/svg+xml') {
$ext = 'svg';
} else { // prevent fallthrough from global variables
$ext = 'txt';
}
$outfile = APPPATH."tempp/$tempName.$ext";
if (!file_put_contents(APPPATH."tempp/$tempName.svg", $svg)) {
die("Couldn't create temporary file.");
}}
Ajax Success function redirect code..
Here you need to read directory files and create PDF from SVG.
After add each PDF to ZIP.
This is Example solution.You have to change code as per your requirement

Related

Upload image on server and add file path inside image tag using quilljs

I am using quilljs for my editor. All my data are handle by mysql database. I am using Angularjs 1.x and for backend Cakephp is my frame-work.
I am currently trying to build a forum kind of page in which I want to save multiple images along with text which will be formatted using quilljs
<p>sd<img src="data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgA....SUVORK5CYII=" alt="i am image"><b>it is image of earth</b></p>
This is what currently storing in my database. Now if there is multiple big images come in then size of field will be too much high there for I want to upload image inside severside folder and want to print image address inside image tag like:
<p>sd<img src="../img/709f2d0be9d13c645037f1b9bb066b00a6d7/image1.jpg" alt="i am image"><b>it is image of earth</b></p>
So I can fetch image directly from given folder.
i have done small trick with quilljs. i have put some code inside quilljs which send image toward my php script on line number 8663 after if (typeof value === 'string') this statement i have added script which sends image value to my php script
var img = {
'img' : value
}
$.ajax({
url: "../Writers/writerCertificateupload",
data: img,
contentType: undefined,
type: 'post'
}).success(function(path){
node.setAttribute('src', path);
})
where node.setAttribute('src', path); sets path which i am returning from php script it sets it on image tag i.e <img src="../img/709f2d0be9d13c645037f1b9bb066b00a6d7/image1.jpg">
and then it sets it inside editor and then we can save that data within editor. this is how i have solve this problem.
my php code is
public function writerCertificateupload()//pending
{
$id = $this->Auth->user('id');
$this->autoRender=false;
define('UPLOAD_DIR', 'files/post/');
$img = $_POST['img'];
$img = str_replace('data:image/jpeg;base64,', '', $img);
$img = str_replace(' ', '+', $img);
$data = base64_decode($img);
$file = UPLOAD_DIR . uniqid() . '.jpg';
$success = file_put_contents($file, $data);
$file = "../".$file;
print $success ? $file : 'Unable to save the file.';
}
You need to create custom image handler (like here) and check base64 string length with fileReader.
I had the same problem in Angular(primeNg) and ended up with the below solution, Btw plz notice that you only need to monitor the editor text change and do some modification like below:
public async handleTextChange(event: any) {
try {
const operations = event.delta.ops;
for (let i = 0; i < operations.length; i++) {
const op = operations[i];
const opType = Object.keys(op)[0] as any;
if (opType == 'insert' && op['insert'].hasOwnProperty('image')) {
this.isLoading = true;
const uploadedImageURL = await this.uploadImage(op['insert'].image);
this._cdr.detectChanges();
const newContent = event.htmlValue.replace(
op['insert'].image,
uploadedImageURL
);
this.editorContent = newContent;
this.contentChanged.emit(newContent);
}
}
} catch (error) {
this.editorContent = this.editorContent + '<br/><br/>';
} finally {
this.isLoading = false;
this._cdr.detectChanges();
}
The upload method will be like this, by the way the upload logic will be depends on your own logic though more or less it's the same:
async uploadImage(dataURL: string): Promise<string> {
const ImageData: FormData = new FormData();
let fileType = dataURL.substring(
dataURL.indexOf(':') + 1,
dataURL.lastIndexOf(';')
);
let fileExtension = fileType.split('/');
const file = new File(
[dataURL],
`file${new Date().getTime()}.${fileExtension[1]}`,
{ type: fileType }
);
ImageData.append('file', file);
const uploadedImageURL = await this._imageUploaderService
.uploadedImage(ImageData)
.toPromise();
return uploadedImageURL ;
}
The component html would be like this
<p-editor
name="editorContent"
[(ngModel)]="editorContent"
[id]="editorId"
[style]="{ height: '320px' }"
(onTextChange)="handleTextChange($event)"
></p-editor>
<app-spinner *ngIf="isLoading == true"></app-spinner>
It's worth mentioning that I used this for p-editor which belongs to primeNg in angular projects

bootstrap fileinput, show uploaded files and delete them

how can i show and delete previously uploaded files with the great bootstrap-fileinput plugin from krajee, my code is:
html:
<script>
$("#images").fileinput({
uploadAsync: true,
uploadUrl: "upload.php"
}).on("filebatchselected", function(event, files) {
$("#images").fileinput("upload");
});
</script>
upload.php:
<?php
if (empty($_FILES['images'])) {
echo json_encode(['error'=>'No files found for upload.']);
return;
}
$images = $_FILES['images'];
$success = null;
$paths= [];
$filenames = $images['name'];
for($i=0; $i < count($filenames); $i++){
$ext = explode('.', basename($filenames[$i]));
$target = "uploads" . DIRECTORY_SEPARATOR . basename($filenames[$i]);
if(move_uploaded_file($images['tmp_name'][$i], $target)) {
$success = true;
$paths[] = $target;
} else {
$success = false;
break;
}
}
if ($success === true) {
$output = ['uploaded' => $paths];
} elseif ($success === false) {
$output = ['error'=>'Error while uploading images. Contact the system administrator'];
foreach ($paths as $file) {
unlink($file);
}
} else {
$output = ['error'=>'No files were processed.'];
}
echo json_encode($output);
?>
Has anyone an idea ? i think i have to scan the uploads dir and send it back with json or use $output, but i dont know how to this ?
Since you are using json to upload files, you can use it to delete them too. Make another ajax call to the server by sending an array of the image URLs that you want to remove. Then with PHP you can simply unlink them.
So for example: http://jsfiddle.net/fdzsLa0k/1/
var paths = []; // A place to store all the URLs
// Loop through all images
// You can do it for a single image by using an id selector and skipping the looping part
$('.uploaded-img').each(function(i, v) {
paths.push(this.src); // Save found image paths
})
console.log(paths); // Preview the selection in console
// Send the URLs to the server for deletion
$.ajax({
method: 'post',
data: { images: paths },
url: 'ajax.php' // Replace with your ajax-processing file
}).success(function(response) {
console.log(response); // Do fun stuff: notify user, remove images from the loaded HTML
});
uuuhh, the fileinput script need php version higher than 5.3.3, because the plesk panel of my hosting provider supports only 5.3.3 i have the problems, since 11.5 plesk supports multiple php version for each domain on the server, now with php 5.6 everything works great !

PHP can't pick up file

I've been trying to create a registration form that requires students to upload documents at the very end. However, after picking up the form values via jQuery, the PHP document can't seem to pick up my uploaded form. Any ideas?
Form:
<form id="joinUs" enctype="multipart/form-data" method="post">
<!--various form fields-->
<input type="file" name="transcript" id="transcript">
<div class="button" id="submit">Submit!</div>
</form>
jQuery:
$("#submit").click(function(){
//firstName, lastName, grade, studentID, email, phone are all form values
var data = "firstName="+firstName+"&lastName="+lastName+"&grade="+grade+"&studentID="+studentID+"&email="+email+"&phone="+phone;
$.ajax({
type: "POST",
url: "join_submit.php",
data: data,
success: function() {
location.href="http://mvcsf.com/new/success.php";
}
});
join_submit.php
$allowedExtensions = array("pdf");
$max_filesize = 20000;
$upload_path = "docs/transcripts";
$filename = $_FILES["transcript"]["name"];
$filesize = $_FILES["transcript"]["size"];
$extension = $_FILES["transcript"]["type"];
if ($_FILES["transcript"]["error"] > 0) {
echo "Error: " . $_FILES["transcript"]["error"] . "<br />";
}
else if((in_array($extension, $allowedExtensions)) && ($filesize < $max_filesize)) {
move_uploaded_file($_FILES["transcript"]["tmp_name"], $upload_path . $filename);
}
I ran this, and I got no errors. I also tried to print out the file name, except nothing printed out.
This should do it for you :
$("#submit").click(function () {
var transcript = $("#transcript").val();
var data = "firstName=" + firstName + "&lastName=" + lastName + "&grade=" + grade + "&studentID=" + studentID + "&email=" + email + "&phone=" + phone;
var formData = new FormData();
formData.append("file", transcript);
formData.append("data", data);
$.ajax({
type: "POST",
url: "join_submit.php",
enctype: 'multipart/form-data',//optional
cache: false,
contentType: false,
processData: false,
data: {
file: file
data: data
},
success: function () {
location.href = "http://mvcsf.com/new/success.php";
}
});
});
Cheers
First, In your code, you are posting data with $.ajax({...}) and the data sent is
"firstName="+firstName+"&lastName="+lastName+"&grade="+grade+"&studentID="+studentID+"&email="+email+"&phone="+phone;
There is no transcript at all.
Secondly, and most important, you cannot post file with $.ajax({...}) like that, it will not working like that. As #Roy M J says, you should take a look at FormData (for recent browser only), or take a look on the web for an upload jQuery plugin (don't re-invent the whell, some good plugin already exists :))
Take a look here
You cannot send a file like you do the values of HTML elements. There are two methods to file upload, the one I've used successfully is the AJAX method using a third-party feature called 'AjaxUploader'.You can download it here via GitHub. Once you've done it, add the ajaxuploader.js file in your 'js' folder (or wherever you've put all of your script files), include the file in the HTML page where you've to use the uploader. Now, uploading is as simple as follows.
HTML:
<input type="file" name="transcriptUploader" id="transcriptUploader" value="Upload" />
jQuery (you need to have the jQuery file included in your page):
new AjaxUpload('transcriptUploader', {
action: "page_to_handle_upload.php", // You need to have either a separate PHP page to handle upload or a separate function. Link to either one of them here
name: 'file',
onSubmit: function(file, extension) {
// This function will execute once a user has submitted the uploaded file. You can use it to display a loader or a message that the file is being uploaded.
},
onComplete: function(file, response) {
// This function will execute once your file has been uploaded successfully.
var data = $.parseJSON(response); // Parsing the returning response from JSON.
if(data.error == 0)
{
// If the file uploaded successfully.
}
else if(data.error == "size"){
// If the response object sent 'size' as the error. It means the file size exceeds the size specified in the code.
}
else if(data.error == "type"){
// If the response object sent 'type' as the error. It means the file type is not of that specified in the code (in your case, pdf).
}
else{
// In case the file didn't upload successfully or the code didn't return a usual error code. It is still an error so you need to deal with it appropriately.
}
}
});
Your back-end PHP code that will be doing all the heavy lifting (uploading the file, checking extensions, moving it etc):
if(isset($_FILES)) // Checking if a file is posted.
{
if ($_FILES['file']['error'] == 0) //Checking if file array contain 0 as an error. It means AJAX had no error posting the file.
{
$response = array(); // Initializing a new array.
$allowedExts = array("pdf"); // Allowable file format.
$filename = stripslashes($_FILES['file']['name']); // Storing file name.
//$extension = strtolower(self::_getExtension($filename)); // Fetching file extension.
// Code block to extract file extension and storing it in a variable called $extraction.
$i = strrpos($str, ".");
if (!$i)
{
$extension = "";
}
$l = strlen($str) - $i;
$extension = strlower(substr($str, $i + 1, $l));
$size = $_FILES['file']['size']; // Storing file size (in bytes).
$fileNameAfterUpload = md5((time() + microtime())) . '.' . $extension; // Concatinating file name and extension.
$baseSystemPath = "/var/www/<your_folder_name>/uploaded_transcripts/" // Path on which the file will be uploaded. Need to be relative web path.
$maxSize = 10*10*1024; // Storing file size. Be advised the file size is in bytes, so this calculation means max file size will be 10 MB.
$webPath = "uploaded_transcripts/". $filename; // Creating web path by concatinating base web path (the folder in which you'd be uploading the pdf files to) with file name.
if (in_array($extension, $allowedExts)) // Checking if file contains allowabale extensions.
{
if($size <= $maxSize) // Checking if the size of file is less than and equal to the maximum allowable upload size.
{
$moved = move_uploaded_file($_FILES['file']['tmp_name'], $webPath); // Moving the file to the path specified in $webPath variable.
if($moved == true)
{
$response['error'] = 0; // If moved successfully, storing 0 in the response array.
$response['path'] = $webPath; // Storing web path as path in the response array.
$response['filename'] = $filename; // Storing file name in the response array.
}
else
{
$response['error'] = 'internal'; // If move isn't successfull, return 'internal' to AJAX.
}
}
else
{
$response['error'] = 'size'; // If file size is too small or large, return 'size' to AJAX.
}
}
else
{
$response['error'] = 'type'; // If file type is not that of defined, return 'type' to AJAX.
}
echo json_encode($response); // Returning the response in JSON format to AJAX.
}
}
Do let me know if you need further assistance.
P.S: Don't forget to mark it as an answer if it worked.

Are canvas.toDataURL compatible with PHP's base64_decode?

My problem is as follows...
I have a screen in which the user can select a PNG image from its computer, using this:
<input id='icon' type='file' accept='image/png' style='width:400px; height:20px' onchange='llenarThumbnail(this)'>
<img id='thumb' src='#'>
When the user selects the image, a thumbnail is shown automatically, using onclick='llenar Thumbnail(this)', like this:
function llenarThumbnail(input){
if (input.files && input.files[0]){
var reader = new FileReader();
reader.onload = function (e){
$('#thumb').attr('src', e.target.result).width(48).height(48);
};
reader.readAsDataURL(input.files[0]);
}
}
Then, when the user clicks on the proper button to upload the image (not a submit button), I do the following to encode the image into Base64:
function getBase64Image(img){
var canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
var dataURL = canvas.toDataURL("image/png");
console.log(dataURL);
return dataURL.replace(/^data:image\/(png|jpg);base64,/, "");
}
Then, using AJAX I send this encoded image data to the server, and a PHP script does the following:
$binary=base64_decode($imagen_data);
header('Content-Type: bitmap; charset=utf-8');
$file = fopen($icono, 'wb');
fwrite($file, $binary);
fclose($file);
As I was printing diferent alerts along the process, I could see that the encoding was performing (i'm not so sure if correctly or not), and PHP receives the data and creates the PNG file, but when I open the image, the image is empty, there's no data... Thats why I'm asking if this to methods are compatible... I guess they are because they're both Base64... But if its not this, then what am i doing wrong???
Please, I'm tired of looking for this all over the internet! I need some answers! Thank you!
Without seeing your ajax POST, here's a Wild Guess:
Try leaving the prefix on until the URL gets to php.
Which php server are you using?
Some other usual gotchas:
Make sure you have properly set up your upload directory.
Make sure you have permissions set properly on the upload directory.
Client Side:
// create a dataUrl from the canvas
var dataURL= canvas.toDataURL();
// post the dataUrl to php
$.ajax({
type: "POST",
url: "upload.php",
data: {image: dataURL}
}).done(function( respond ) {
// you will get back the temp file name
// or "Unable to save this image."
console.log(respond);
});
Server File: upload.php
<?php
// make sure the image-data exists and is not empty
// php is particularly sensitive to empty image-data
if ( isset($_POST["image"]) && !empty($_POST["image"]) ) {
// get the dataURL
$dataURL = $_POST["image"];
// the dataURL has a prefix (mimetype+datatype)
// that we don't want, so strip that prefix off
$parts = explode(',', $dataURL);
$data = $parts[1];
// Decode base64 data, resulting in an image
$data = base64_decode($data);
// create a temporary unique file name
$file = UPLOAD_DIR . uniqid() . '.png';
// write the file to the upload directory
$success = file_put_contents($file, $data);
// return the temp file name (success)
// or return an error message just to frustrate the user (kidding!)
print $success ? $file : 'Unable to save this image.';
}
I could not get markE solution to work, had to change the data modification :
From :
$parts = explode(',', $dataURL);
$data = $parts[1];
$data=base64_decode($data)
To :
$img = str_replace('data:image/png;base64,', '', $dataURL);
$img = str_replace(' ', '+', $img);
$data=base64_decode($img);
Method from

Saving binary string to file in php sent from POST

I have a drag and drop uploader for (.jpg,.ai,.pdf,.flv,.psd ....etc.)
I'm reading the file as binary and sending the string in a jquery post:
function importZoneDrop(evt) {
evt.stopPropagation();
evt.preventDefault();
var files = evt.dataTransfer.files; // FileList object.
// files is a FileList of File objects. List some properties.
for (var i = 0, f; f = files[i]; i++) {
var start = 0;
var stop = files[0].size - 1;
var reader1 = new FileReader();
var reader2 = new FileReader();
var ext = f.name.substring(f.name.indexOf(".")+1);
if(ext == "JPEG" || ext == "jpeg" || ext == "JPG"){
ext ="jpg";
}
reader1.onload = (function(theFile) {
return function(e) {
// Render thumbnail.
$("#import-drop-zone").append('<img src="'+e.target.result+'" />');
};
})(f);
reader2.onloadend = function(evt) {
if (evt.target.readyState == FileReader.DONE) { // DONE == 2
$.post("/process/upload.php",{"blob":evt.target.result,"extension":ext},function(data){
console.log(data);
});
}
};
reader1.readAsDataURL(f);
var blob = f.slice(start, stop + 1);
reader2.readAsBinaryString(f);
}
}
This works and send the file. Next Get the string and write it using file_put_contents:
$extension = $_POST['extension'];
$file = $_POST['blob'];//sent from jquery post
$filePath = "../_temp/monkey.".$extension;
file_put_contents($filePath,$file);
if(file_put_contents($filePath,$file)){
echo json_encode("it worked");
}else{
echo json_encode("it failed");
}
This will successfully write the file. But the file does not work, it's broke.
What am I doing wrong?
You need to use base64_decode.
file_put_contents($filePath, base64_decode($file));
Note, you're currently writing the data twice. Don't.
if (file_put_contents($filePath, base64_decode($file))) {
is fine
Edit
Also worth nothing that it's more efficient to upload the binary file directly, then you can skip base64_decode. Something like this:
var xhr = new XMLHttpRequest(),
data = new FormData();
data.append("file", f); // You don't need to use a FileReader
// append your post fields
// attach your events
xhr.addEventListener('load', function(e) {});
xhr.upload.addEventListener('progress', function(e) {});
xhr.open('POST', '/process/upload.php', true);
xhr.send(data);
You can view the rest of the events here with some samples here.

Categories