How to process with RubaXa File API uploaded file blobs in php? - php

I found this useful tool called RubaXa / jquery.fileapi
which slices a file and create blobs. But within the documentation there is a lack of information about how to process the uploaded parts on the server. The example on the page refers to a url: './ctrl.php' but you can't see the content of it on the developers page. I used this (look below) client side script so far and there were no errors. A file was sliced and several post requests appeared in my firebug console. So it seems to work. But how to process the received fileparts in PHP on the server?
imported scripts:
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
<script>
window.FileAPI = {
debug: false // debug mode
, staticPath: 'jquery.fileapi-master/FileAPI/' // path to *.swf
};
</script>
<script src="jquery.fileapi-master/FileAPI/FileAPI.min.js"></script>
<script src="jquery.fileapi-master/jquery.fileapi.min.js"></script>
the initiation and setup of the fileuploader:
jQuery(function ($){
$('#uploader').fileapi({
url: 'stash.php',
autoUpload: true,
accept: 'video/*',
multiple: false, //only single file upload
chunkSize: .5 * FileAPI.MB //filesize of the blobs/chunks
});
});
the HTML file upload "form":
<div id="uploader">
<div class="js-fileapi-wrapper">
<input type="file" name="files[]" />
</div>
<div data-fileapi="active.show" class="progress">
<div data-fileapi="progress" class="progress__bar"></div>
</div>
</div>

Hope this code will help you
<?php
/**
* FileAPI upload controller (example)
*/
include './FileAPI.class.php';
if( !empty($_SERVER['HTTP_ORIGIN']) ){
// Enable CORS
header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']);
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Range, Content-Disposition, Content-Type');
}
if( $_SERVER['REQUEST_METHOD'] == 'OPTIONS' ){
exit;
}
if( strtoupper($_SERVER['REQUEST_METHOD']) == 'POST' ){
$files = FileAPI::getFiles(); // Retrieve File List
$images = array();
// Fetch all image-info from files list
fetchImages($files, $images);
// JSONP callback name
$jsonp = isset($_REQUEST['callback']) ? trim($_REQUEST['callback']) : null;
// JSON-data for server response
$json = array(
'images' => $images
, 'data' => array('_REQUEST' => $_REQUEST, '_FILES' => $files)
);
// Server response: "HTTP/1.1 200 OK"
FileAPI::makeResponse(array(
'status' => FileAPI::OK
, 'statusText' => 'OK'
, 'body' => $json
), $jsonp);
exit;
}
function fetchImages($files, &$images, $name = 'file'){
if( isset($files['tmp_name']) ){
$filename = $files['tmp_name'];
list($mime) = explode(';', #mime_content_type($filename));
if( strpos($mime, 'image') !== false ){
$size = getimagesize($filename);
$base64 = base64_encode(file_get_contents($filename));
$images[$name] = array(
'width' => $size[0]
, 'height' => $size[1]
, 'mime' => $mime
, 'size' => filesize($filename)
, 'dataURL' => 'data:'. $mime .';base64,'. $base64
);
}
}
else {
foreach( $files as $name => $file ){
fetchImages($file, $images, $name);
}
}
}
?>

you can get the source code in here:
https://github.com/mailru/FileAPI
inside the "server" folder it is the ctrl.php and FileAPI.class.php

Related

403 Error Persists After Changing File Permissions & Editing Htaccess File

Below is some background on why I am asking this question followed by some research I have done as of now before bringing this question forward. I hope that I am asking the correct question. As is it often the case that we ask the wrong question because we do not fully understand the issue and therefore waste our time and those of others.
Discovery of an issue:
I click a button on my website that is supposed to save edits to an article. When I do click the button, I get the following : it turns white and nothing changes.
Below is the code for the button in question this button exists in the file community/profile.php.
<button onclick="saveEditedArticle();" class="btn btn-dark btn-lg btn-block" id="edit_postbutton">Save Article</button>
Initial Steps Taken To Investigate The Problem
I opened up the chrome dev tools to see what could possibly be happening.
1) In Chrome Dev Tools I Get A 403 Error
10jquery.js:8630 POST https://bullbuster.net/community/controllers/article.php 403
send # jquery.js:8630
ajax # jquery.js:8166
saveEditedArticle # (index):591
onclick # (index):6451
2) I Do Some Research To See What A 403 Error Is
3) I Use Google & Find Stack Overflow Questions On This Issue:
403 forbidden error -executing and ajax page
403 Forbidden error when making an ajax Post request
4) I am told a 403 Error Means That My File Has The Wrong Permissions
I then change the permissions for :
https://bullbuster.net/community/controllers/article.php
to 0755 (what this means) from 0644 (what this means)
5) I am told it is possible that it is an issue with my htaccess file:
Header set Access-Control-Allow-Origin "*"
Below is the part of the file from the community/controllers/article.php that access is being forbidden from (403) even though this file has 0755 permissions
case 'save-edit':
//echo 'made it';
$validation = $validate->check($_POST, array(
'edit_article_category' => array(
'required' => true,
),
'edit_new_post_title' => array(
'required' => true,
),
'edit_new_post_content' => array(
'required' => true,
),
'edit_line_type' => array(
'required' => true,
), /*
'edit_lbtest-select' => array(
'required' => true,
),*/
));
if($validation->passed()){
$update = $Ambassador->saveEditedArticle();
The function saveEditedArticle is found in two files:
1) community/profile.php
function saveEditedArticle()
{
event.preventDefault();
$("#edit_formatted-tags").val($("#edit_tags").tagsinput('items'));
//alert(tags);
//var form = $("#article").serialize();
//alert(tags);
$('.selectpicker').selectpicker('setStyle', 'error-input', 'remove');
$('#new_post_title').removeClass('error-input');
$('#redactor-uuid-0').removeClass("error-input");
$.ajax({
url: './controllers/article.php',
type: 'post',
dataType: 'json',
crossDomain: 'true',
data:
$("#edit_article").serialize()
,
success: function(data){
if(data == 'validation passed'){
$('#edit_validation-error').hide();
$('#edit_postbutton').attr('disabled', 'true');
$('#edit_submission-success').show();
setTimeout(function() {
//location.reload();
var location = window.location.href;
window.location = location;
}, 1500);
} else {
for (i = 0; i < data.length; i++) {
var field = data[i][0];
//$('#'+field).addClass("error-input");
if(field=='edit_new_post_title'){
$('#edit_new_post_title').addClass("error-input");
}
if(field=='edit_new_post_content'){
$('.redactor-editor').addClass("error-input");
}
$('#'+field).selectpicker('setStyle', 'error-input');
$('#edit_validation-error').show();
}
}
}
});
}
2) This is in the file classes/ambassador.php
public function saveEditedArticle(){
$content = Input::get('edit_new_post_content');
$start = "<img src=\"";
$end = "\"";
$image = self::getBetween($content, $start, $end);
if($image==''){
$start = "src=\"//www.youtube.com/embed/";
$end = "\"";
$image = self::getBetween($content, $start, $end);
if($image!=''){
$image = "https://img.youtube.com/vi/" . $image . "/0.jpg";
}
if($image==''){
$start = "//player.vimeo.com/video/";
$end = "\"";
$image = self::getBetween($content, $start, $end);
if($image!=''){
$link = 'https://vimeo.com/api/v2/video/' . $image . '.php';
$html_returned = unserialize(file_get_contents($link));
$image = $html_returned[0]['thumbnail_large'];
}
}
}
if($image==''){
$image = 'img/articles/475-33d0f7b0970af583c001559f19c26911.jpg';
}
//$content = str_replace('http://', 'https://', Input::get('new_post_content'));
$slug1 = strtolower(Input::get('edit_article_category'));
$slug2 = strtolower(Input::get('edit_new_post_title'));
$slug2 = preg_replace('/[^a-zA-Z0-9 ]/s', '', $slug2);
$slug = $slug1 . '/' . $slug2;
$slug = str_replace(' ', '-', $slug);
$slug = preg_replace ('/-+/', '-', $slug);
$article_category = Input::get('edit_article_category');
$article_title = ucwords(Input::get('edit_new_post_title'));
$article_content = Input::get('edit_new_post_content');
$line_category_id = Input::get('edit_line_type');
//$lb_test_id = Input::get('edit_lbtest-select');
$tags = Input::get('edit_formatted-tags');
$article_id = Input::get('article_id');
$update = $this->_db->update('Article', $article_id,
array(
'category'=>$article_category,
'title'=>$article_title,
'content'=>$article_content,
'line_category_id'=>$line_category_id,
//'lb_test_id'=>$lb_test_id,
'tags'=>$tags,
'image_preview'=>$image,
'slug'=>$slug
),
'id');
}

Image file coming empty

I have created a script to upload the image with text but the problem is that when we post the data and upload the image the file is coming empty I do not know why the file is coming empty can anyone help me out to get the correct file
This is my ajax script
$(document).ready(function(e) {
$("#post").on('submit', (function(e) {
$("#load").show();
var form = this;
var formData = new FormData(this);
alert(formData);
formData.append('post_dt', $("#contentbox").html());
$.ajax({
url : "http://domainname.com/demo/forums/post_forum",
type : "POST",
data : formData,
contentType : false,
cache : false,
processData : false,
success : function(data) {
$("#data_update").prepend($(data).fadeIn('slow'));
$("#contentbox").empty();
form.reset();
},
complete: function() {
$("#load").hide();
}
});
}));
});
This the html form which is being created
<form method="POST" action="" id="post" enctype="multipart/form-data" onsubmit="return false;">
<ul>
<li>
<i class="fa fa-photo"></i> Upload A Photo / Document
<input type="file" name="image" />
</li>
</ul>
<div id='display'></div>
<div id="contentbox" contenteditable="true" name="post_dt">
</div>
<input type="submit" id="sb_art" class="btn_v2" value="Start Discussion" />
</form>
My php script which I have created within the controller
public function post_forum() {
$config['upload_path'] = './assets/uploads/';
$config['allowed_types'] = 'gif|jpg|png';
$config['max_size'] = 3000;
$this->load->library('upload', $config);
if(!empty($this->input->post('image'))) {
if (!$this->upload->do_upload('image')) {
$error = array('error' => $this->upload->display_errors());
} else {
$dt = $this->upload->data();
$file = $dt['file_name'];
}
} else {
$file = 'Filename.jpg';
}
$word_dta = $this->input->post('post_dt');
$time_posted = time();
$user_id = $this->basic_model->is_login($this);
$data_upload = array(
'upload_document' => $file,
'discussion' => $word_dta,
'user_id' => $user_id,
'time_posted' => $time_posted,
'status' => 'Posted'
);
$post_id = $this->basic_model->insertRecord($data_upload, 'forums');
$data = array(
'file_name' => $file,
'data' => $word_dta,
'time_posted' => $time_posted,
'post_id' => $post_id,
'name' => $this->basic_model->getUserData(),
'command' => 'Submit Post'
);
$this->load->view('forum/includes/get_data', $data);
}
add id as imageFieldId to file in html. Then try
var file_data = $('#imageFieldId').prop('files')[0];
var form_data = new FormData();
form_data.append('file', file_data);
//formData.append('post_dt', $("#contentbox").html());
$.ajax({.....
I have sorted out my issue I was making a mistake within the controller which was my mistak so I have resolved my issues take care
Ensure your webserver (nginx/apache) upload size limit are correct.
This link could be your reference to set the upload size:
Increase File Upload Size Limit
Edit NginX Conf to Increase File Size Upload

Download files from storage is not working?

Actually my task is when I select from-date and to-date using date picker and then I click download button, select the id from orders table between dates and check invoice->id is matching with files in storage folder. If files are matched create zip and download.
I can zipped but download is not working.
export.blade.php
<button class="btn btn-success dateDifference" role="button"><i class="fa fa-download"></i> Download </button>
<script>
$(".dateDifference").on("click", function() {
var fromDate = $(".dateFrom").val();
var toDate = $(".dateTo").val();
$.post('{{ route('exportInvoiceDownload') }}', {fromDate: fromDate, toDate: toDate}, function(response){
//alert(response);
});
});
</script>
routes.php
Route::post('/export/download/invoices', [
'as' => 'exportInvoiceDownload', 'uses' => 'BookingController#downloadInvoices'
]);
Controller.php
public function downloadInvoices(Request $request)
{
$fromDateReplace = str_replace('/', '-', $request->fromDate);
$fromDate = date("Y-m-d", strtotime($fromDateReplace));
$toDateReplace = str_replace('/', '-', $request->toDate);
$toDate = date("Y-m-d", strtotime($toDateReplace));
$archive_name = storage_path('app') . '/invoice_archive/Rechnung_'.$fromDate.'_'.$toDate.'.zip';
$orders = Booking::select('invoice_id')
->whereBetween('created_at', [$fromDate, $toDate])
->get();
if (count($orders) > 0 ) {
$zip = new ZipArchive;
if ($zip->open($archive_name, ZipArchive::CREATE) === TRUE) {
foreach ($orders as $order) {
$file = storage_path('app') . '/invoice_archive/test-'.$order->invoice_id.'.pdf';
if (file_exists($file)) {
$zip->addFile($file, 'test-'.$order->invoice_id.'.pdf');
}
}
$zip->close();
$headers = [
'Pragma' => 'public',
'Expires' => 0,
'Content-Type' => 'application/octet-stream',
'Content-Disposition' => 'attachment; filename=\"test_'.$fromDate.'_'.$toDate.'.zip\"',
'Content-Transfer-Encoding' => 'binary'
];
if (file_exists($archive_name)) {
return response()->download($archive_name, 'test_'.$fromDate.'_'.$toDate.'.zip', $headers) /*->deleteFileAfterSend(TRUE)*/;
}
}
}
}
seems you are calling this route with ajax, if that's true than download won't work in this case, you need traditional post request because ajax binary response will not open download popup in browser so instead of ajax just submit the form as browser default or make it get request and open it in new browser tab then it will consider content-dispostion header and download popup will appear.

Receive API application/octet-stream Post via PHP

I have post that comes from an iOS device. The header is that of:
application/octet-stream
I am trying to figure out in PHP how to receive that file. $_FILES seems to only work for:
multipart/form-data
Here is what we use to do:
if(isset($_FILES['media'])){
$this->load->library( 'lib_files' );
ini_set('max_execution_time', 300);
$parts = pathinfo( $_FILES['media']['name'] );
$result = $this->lib_files->move_file_into_structure( array(
'project_id' => $project_id
, 'current_path' => $_FILES['media']['tmp_name']
, 'original_name' => $parts['filename']
, 'extension' => $parts['extension']
, 'insert_for' => 'mobile_journal_id'
, 'insert_for_id' => $journal_id
, 'user_id' => $user_project->user_id
) );
But now I am trying to grab octet-stream binary upload and I am confused how to do that here. So far I think I have to do something like this:
if($_SERVER['REQUEST_METHOD'] == 'POST') {
if($_POST == null) {
$handle = fopen('php://input', 'r');
$rawData = fgets($handle);
}
}
That rawData should be my file correct? How do I grab things like original_name, extension, current path I take it is php://input. I have never used octet-stream and I found nothing really online about doing it for php.

Ajax Upload with JQuery and PHP

I have a problem with Ajax uploading using Jquery and PHP.. Although there're many stackoverflow posts discussing the same subject, I didn't find one that matches my case.
HTML :
<form action="uploadrecord.php" id="upload_record_form" method="post" enctype="multipart/form-data">
<div id="upload_record_form_result"></div>
<ul>
<li><input type="file" name="uploadrecord" id="uploadrecord"/></li>
</ul>
<progress></progress>
</form>
</div>
Javascript :
$('#uploadrecord').live('change', function(event) {
var formData = new FormData($('#upload_record_form')[0]);
$.ajax({
url: $('#upload_record_form').attr('action'),
type: 'POST',
enctype: 'multipart/form-data',
xhr: function() {
myXhr = $.ajaxSettings.xhr();
if (myXhr.upload) {
myXhr.upload.addEventListener('progress', progressHandlingFunction, false);
}
return myXhr;
},
success: completeHandler = function(data) {
$('#upload_record_form_result').html(data);
},
error: errorHandler = function() {
alert("Failure");
},
data: formData,
cache: false,
contentType: false,
processData: false
}, 'json');
});
PHP
<?php
if (isset($_FILES['uploadrecord'])) {
if ((!empty($_FILES["uploadrecord"])) && ($_FILES['uploadrecord']['error'] == 0)) {
$filename = basename($_FILES['uploadrecord']['name']);
$ext = substr($filename, strrpos($filename, '.') + 1);
$types = array(
'video/mp4', 'video/3gpp', 'video/divx', 'video/flv', 'video/mpeg', 'video/mpeg-2', 'video/mpeg4', 'video/mpeg4'
);
$type = $_FILES['uploadrecord']['type'];
if (in_array($type, $types) && $_FILES["uploadrecord"]["size"] < 20000000) {
$new = sha1(date('Y/m/d H:i:s'));
$newname = dirname(__FILE__) . '/records/' . $new . '.' . $ext;
if ((move_uploaded_file($_FILES['uploadrecord']['tmp_name'], $newname))) {
echo 'done';
} else {
echo 'failed 1';
}
}
} else {
echo 'failed 2';
}
} else {
echo 'Upload failed 3';
}
When I try the previous code, and upload a record file, it displays "failed 2", meaning that the "error" code is different from 0.
when I var_dump the array $_FILES['uploadrecord']...this is what I get:
array (size=5)
'name' => string 'Nao Robot.flv' (length=13)
'type' => string '' (length=0)
'tmp_name' => string '' (length=0)
'error' => int 1
'size' => int 0
I can't figure out, why 'tmp_name' and type are set to empty strings, and why the size is set to 0.
Where's the problem exactly? is it from the client or server side scripting?
Thanks in advance
ON MAC OSX:
1) Go to /etc/php.ini
2) Open the file with permission to write/read
3) Search for line:
upload_max_filesize = 2M
4)Change to, for example, 6MB ou more:
upload_max_filesize = 6M
5) Save and restart apache with command:
sudo apachectl restart

Categories