jQuery send file chunks to PHP upload to Ooyala - php

I have been stuck on this for over a week and I think I am long overdue for asking on here.. I am trying to get my users to upload their video files using the jQuery File Upload Plugin. We do not want to save the file on our server. The final result is having the file saved in our Backlot using the Ooyala API. I have tried various approaches and I am successful in creating the asset in Backlot and getting my upload URLs, but I do not know how to upload the file chunks using the URLs into Backlot. I have tried FileReader(), FormData(), etc. I am pasting the last code I had that created the asset, and gave me the upload URLs, but did not save any chunks into Backlot. I assume I may be getting stuck in one of my AJAX calls, but I am not very sure.
I keep getting:
Uncaught InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable.
Here is my page with the JS for the jQuery File Upload widget by BlueImp:
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="<?php print base_path() . path_to_theme() ?>/res/js/jQuery-File-Upload/js/vendor/jquery.ui.widget.js"></script>
<script type="text/javascript" src="<?php print base_path() . path_to_theme() ?>/res/js/jQuery-File-Upload/js/jquery.iframe-transport.js"></script>
<script type="text/javascript" src="<?php print base_path() . path_to_theme() ?>/res/js/jQuery-File-Upload/js/jquery.fileupload.js"></script>
</head>
<body>
<input id="fileupload" type="file" accept="video/*">
<script>
//var reader = FileReader();
var blob;
$('#fileupload').fileupload({
forceIframeTransport: true,
maxChunkSize: 500000,
type: 'POST',
add: function (e, data) {
var goUpload = true;
var ext = ['avi','flv','mkv','mov','mp4','mpg','ogm','ogv','rm','wma','wmv'];
var uploadFile = data.files[0];
var fileName = uploadFile.name;
var fileExtension = fileName.substring(fileName.lastIndexOf('.') + 1);
if ($.inArray( fileExtension, ext ) == -1) {
alert('You must upload a video file only');
goUpload = false;
}
if (goUpload == true) {
$.post('../sites/all/themes/episcopal/parseUploadJSON.php', 'json=' + JSON.stringify(data.files[0]), function (result) {
var returnJSON = $.parseJSON(result);
data.filechunk = data.files[0].slice(0, 500000);
data.url = returnJSON[0];
//reader.onloadend = function(e) {
//if (e.target.readyState == FileReader.DONE) { // DONE == 2
//data.url = returnJSON[0];
// }
//}
//$.each(returnJSON, function(i, item) {
//data.url = returnJSON[0];
//blob = data.files[0].slice(0, 500000);
//console.log(blob);
//reader.readAsArrayBuffer(blob);
//data.submit();
//});
data.submit();
});
}
},//end add
submit: function (e, data) {
console.log(data); //Seems fine
//console.log($.active);
$.post('../sites/all/themes/episcopal/curlTransfer.php', data, function (result) { //fails
console.log(result);
});
return false;
}
});
</script>
</body></html>
Then there is the parseUploadJSON.php code, please keep in mind that my real code has the right Backlot keys. I am sure of this:
<?php
if(isset($_POST['json'])){
include_once('OoyalaAPI.php');
$OoyalaObj = new OoyalaApi("key", "secret",array("baseUrl"=>"https://api.ooyala.com"));
$expires = time()+15*60; //Adding 15 minutes in seconds to the current time
$file = json_decode($_POST['json']);
$responseBody = array("name" => $file->name,"file_name"=> $file->name,"asset_type" => "video","file_size" => $file->size,"chunk_size" => 500000);
$response = $OoyalaObj->post("/v2/assets",$responseBody);
$upload_urls = $OoyalaObj->get("/v2/assets/".$response->embed_code."/uploading_urls");
$url_json_string = "{";
foreach($upload_urls as $key => $url){
if($key+1 != count($upload_urls)){
$url_json_string .= '"' . $key . '":"' . $url . '",';
}else {
$url_json_string .= '"' . $key . '":"' . $url . '"';
}
}
$url_json_string .= "}";
echo $url_json_string;
}
?>
Then I have the curlTransfer.php:
<?php
echo "starting curl transfer";
echo $_POST['filechunk'] . " is the blob";
if(isset($_FILES['filechunk']) && isset($_POST['url'])){
echo "first test passed";
$url = $_POST['url'];
//print_r(file_get_contents($_FILES['filechunk']));
$content = file_get_contents($_FILES['filechunk']);
print_r($content);
$ch = curl_init($url);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt ($ch, CURLOPT_HTTPHEADER, Array("Content-Type: multipart/mixed"));
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_POSTFIELDS, $content);
try {
//echo 'success';
return httpRequest($ch);
}catch (Exception $e){
throw $e;
}
}
/****Code from Ooyala****/
function httpRequest($ch){
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$response = curl_exec($ch);
if(curl_error($ch)){
curl_close($ch);
return curl_error($ch);
}
$head=curl_getinfo($ch);
$content = $head["content_type"];
$code = $head["http_code"];
curl_close($ch);
}
?>
And the OoyalaApi.php is here (I saved a copy on my server):
https://github.com/ooyala/php-v2-sdk/blob/master/OoyalaApi.php
I apologize in advance if the code is messy and there's a lot of parts commented out. I have changed this code so much and I cannot get it. I appreciate all of your time and effort.
EDIT
I went back to trying FileReader out as this post Send ArrayBuffer with other string in one Ajax call through jQuery kinda worked for me, but I think it would be safer to read it using readAsArrayBuffer and now I am having trouble saving the array buffer chunks in some sort of array...

We have implemented ooyala file chunk upload in Ruby On Rails by referring this.
We have used the entire JS file as it is from this link.
https://github.com/ooyala/backlot-ingestion-library

Related

Attempting to stimulate page to produce server sent event with POST data from another page not working

When I open update.php on its own (with self supplied test vars), it sends the SSE to testsse.php just fine and there are no issues (Everything I need to be printed is showing up in inspect element), However, I am trying to have POST data from another page (In this case mootssetest.php) get received by update.php so it may send out the SSE containing the data. I am not sure what I am doing wrong, but this test rig is not working. Guidance would be appreciated.
testsse.php (front end page meant to receive SSE and print)
<!DOCTYPE html>
<html lang="en">
<head>
<title>Using Server-Sent Events</title>
<script>
window.onload = function() {
var link = new EventSource("update.php");
var antispam;
var inputthing = event.data;
var splitted;
link.onmessage = function(event) {
inputthing = event.data;
splitted = inputthing.split(" ");
if (splitted[0] != antispam && splitted[1] == <?php echo $page; ?>) {
document.getElementById("livemsg").innerHTML += "<div id=\"post-" + splitted[0] + "\" class=\"reply\">" + "</div>";
antispam = splitted[0];
};
};
};
</script>
</head>
<body>
<div id="livemsg">
<!--Server response will be inserted here-->
</div>
</body>
</html>
update.php (SSE sender, post receiver)
<?php
$data = json_decode(file_get_contents('php://input'), true);
$postnum = $data[0];
$bread = $data[1];
postnum = 32;
bread = 4;
function liveupdate($postnum, $bread)
{
header("Content-Type: text/event-stream");
header("Cache-Control: no-cache");
echo "data: " . $postnum . " " . $bread . "\n\n";
flush();
}
liveupdate($postnum, $bread);
?>
mootssetest.php (POST sender)
function httppost($postnum, $bread)
{
$url = "http://localhost/update.php";
$data = array($postnum, $bread);
$curl = curl_init($url);
$jsondata = json_encode($data);
curl_setopt( $ch, CURLOPT_POSTFIELDS, $jsondata );
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt( $ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
httppost(420, 4);
?>
(For context, I am trying to have this print a new post in some forum software every time a function is called without refreshing the page for the user)
you haven't included the event in your window.onload() function, please fix it first and try again.

Ajax return values

I am trying to figure out how to send back a value to the Ajax popup box. Currently, the value that gets returned is just the JSON that comes back from the API call. I would much rather use jsondecode to pull out a specific value and have that return, or... lets not even get that complex. I just want to set a variable equal to some message such as "API GET complete" and return that to the Ajax box. This will also help with troubleshooting so I can return a variable to see if things are working. As I said, currently the Ajax popup just displays the JSON that comes back from the API call. This is my first time working with both Ajax and curl_setopt so if you can please make recommendations with examples, that would be fantastic! Thank you!
test.html
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
$('.button').click(function(){
var clickBtnValue = $(this).val();
var ajaxurl = 'auto.php',
data = {'action': clickBtnValue};
$.post(ajaxurl, data, function (response) {
alert(response);
});
});
});
</script>
</head>
<body>
<input type="submit" class="button" name="test" value="Test" />
</body>
</html>
auto.php
<?php
if (isset($_POST['action'])) {
switch ($_POST['action']) {
case 'Test':
Test();
break;
case 'to_the_n':
to_the_n();
break;
}
}
function Test() {
$ch = curl_init('https://api.digitalocean.com/v2/droplets?tag_name=MYTAG');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Bearer MYTOKEN','Content-Type: application/json'));
$result = curl_exec($ch);
$message = "Yay it worked" //Send this message back to Ajax popup, not the API reply
exit;
}
?>
* UPDATE *
* UPDATE *
You can just echo the value from php and it will be alerted in the Ajax success function.
echo 'Yay it worked!! ';
<?php
if (isset($_POST['action'])) {
switch ($_POST['action']) {
case 'Test':
if(Test() == true) {
echo('yay it worked!! ');
exit;
}
break;
case 'to_the_n':
to_the_n();
break;
}
}
function Test() {
$ch = curl_init('https://api.digitalocean.com/v2/droplets?tag_name=MYTAG');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Bearer MYTOKEN','Content-Type: application/json'));
$result = curl_exec($ch);
return true;
}
?>

PHP cURL script adding a 'space' at end of filename

I'm calling a PHP script via AJAX that saves a remote image locally (via Mapbox API). Everything works great, except for the result includes a 'space' (filename.jpg[space]) at the end of the string.
Javascript:
var mapboxUrl = 'https://api.mapbox.com/v4/motioncrafter.96d11990/' + longitude + ',' + latitude + ',11/1280x720#2x.jpg80?access_token=pk.eyJ1IjoibW90aW9uY3JhZnRlciIsImEiOiJjaWg2dHJvM2YwNndudjJrdGI2amUzdnlyIn0.oN201-rjUC4DHhz7QhGJRA';
$.ajax({
type: "POST",
url: "../../php/map.php",
data: {
map: mapboxUrl,
},
success: function(result) {
$('.video_map').val(result);
}
});
PHP:
<?php
$mapboxUrl = $_POST["map"];
$path = "../images/user-maps/";
$imageFile = $path . "map_wide_" . rand(10000, 99999) . time() . ".jpg";
$ch = curl_init($mapboxUrl);
$fp = fopen($imageFile, 'wb');
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
fclose($fp);
echo $imageFile;
?>
Any idea why this space is showing up?
Get rid of this line:
?>
I suspect you have a space after that. Everything outside <?php ... ?> gets sent to the client, so if it's actually ?><space>, the space will be appended to the image filename.
There's no need to have ?> at the end of a script, the end of the file automatically tells PHP to stop processing the code.

Read URL Content in javascript using php

I want to read the content of a URL in javascript. The URL is not on my domain so I need a middle layer that can access cross domain.
I tried to use a PHP function to read the URL and return the result to javascript using jquery but it didn't work.
Here is my trial:
I created a php file named "phpjs_test.php"
<?php
function get_data(){
$url='http://asmary.dreameg.com/texttable.txt';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
$content = curl_exec($ch);
$content = htmlspecialchars($content);
curl_close($ch);
$content = nl2br($content);
return $content;
}
?>
and this is the javascript code:
<script>
$(document).ready(function () {
//httpQuery("http://asmary.dreameg.com/texttable.txt");
getOutput();
});
function getRequest() {
var req = false;
try {
// most browsers
req = new XMLHttpRequest();
} catch (e) {
// IE
try {
req = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
// try an older version
try {
req = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
return false;
}
}
}
return req;
}
function getOutput() {
var ajax = getRequest();
ajax.onreadystatechange = function() {
if (ajax.readyState == 4) {
document.getElementById('output').innerHTML = ajax.responseText;
}
};
ajax.open("GET", "phpjs_test.php", true);
ajax.send(null);
}
I'm completely new to PHP so I don't know even the PHP function is correct or not.
You should just use jQuery ajax methods instead of creating XMLHTTPRequest you don't have to bother with adding more code for IE plus you're already loading the jQuery library. Also if you set the header to Allow-Origin-Access in your PHP file and specify the other domain you're requesting from then you can make an AJAX request and get the response otherwise it will return nothing or in your dev tools network tab it will show a 403 - Forbidden.
Access-Control-Allow-Origin syntax
Change the PHP file to:
<?php
$url='http://asmary.dreameg.com/texttable.txt';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$content = curl_exec($ch);
curl_close($ch);
$content = explode('~',$content);
foreach($content as $c)
{
$records[] = explode('|',$c);
}
$content = json_encode($records);
echo $content;
?>
Javascript will receive a json array like this
[["1","name1","10","city1"],["2","name2","20","city2"],["3","name3","30","city3"],["4","name4","40","city4"],["5","name5","50","city5"],["6","name6","60","city6"],["7","name7","7","city7"],["8","name8","80","city8"],["9","name9","90","city9"],["10","name10","100","city10"],["11","name11","11","city11"],["12","name12","12","city12"],["13","name13","13","city13"],["14","name14","14","city14"],["15","name15","15","city15"],["16","name16","16","city16"],["17","name17","17","city17"],["18","name18","18","city18"],["19","name19","19","city19"],["20","name20","20","city20"],[""]]

Download a File and Upload it with PHP and AJAX

I am developing a web application that uses JQuery AJAX and PHP to upload some data into my database.
One of the fields of the form to be submitted is an URL of a image (any address of the WEB). This image should be downloaded to my FTP server and then its new addrress would be inserted into the database.
How can I download an image from any URL and upload it to my FTP server?
Form:
<form id="form-id" method="post" action="insert.php" charset=utf-8">
<input type="text" name="title" id="title">
<input type="text" name="image-url" id="image-url">
<input type="submit" name="submit" id="submit">
</form>
JavaScript
$("#submit").live("click", function(event){
event.preventDefault();
$.ajax({
type : "POST",
url : "insert.php",
data : {
'title': valueTitle,
'image': valueImage
},
cache : false,
success : function(html) {
if (html == "success") {
//...
} else if (html == "ftp-error") {
//...
} else if (html == "sql-error") {
//...
}
}
});
});
insert.php
$title = $_REQUEST['title'];
$image = $_REQUEST['image'];
$imageInMyServer = downloadImageFromURLAndUploadFTP($image);
function downloadImageFromURLAndUploadFTP($image) {
//that is what I want to know how to do.
}
//sql query with $title and $imageInMyServer
Notes:
The file I want to download is not on my server. It is somewhere else in the Internet and I need to download it to my FTP server
No. I cannot use the first external URL in my SQL Query
Here is a great example on how to do FTP transfers in PHP. As far as downloading the file, you could use wget if you're on linux (using the exec() function).
exec('wget -q ' . $url . ' -0 /path/to/newfile');
Stealing a code snippet from that link I gave you, here is what your function might look like:
function downloadImageFromURLAndUploadFTP($image) {
// in your case it would be some img extension like .jpg, .gif, or .png
// you can check the extension of $image and use that if you want.
$newFile = '/path/to/newfile.ext';
exec('wget -q ' . $image . ' -0 ' . $newFile);
if (file_exists($newFile)) {
// set up connection and login
$connect = ftp_connect($ftpServer);
$login = ftp_login($connect, $ftpUser, $ftpPass);
// check connection
if (!$connect || !$login) {
die('FTP connection has failed!');
} else {
echo "Connected to {$ftpServer}, for user {$ftpUser}";
}
// upload the file
$fileNameOnFTPServer = 'whateverYouWantToNameIt.ext'; // arbitrary extension
$upload = ftp_put($connect, $fileNameOnFTPServer, $newFile, FTP_BINARY);
// check upload status
if (!$upload) {
echo "FTP upload has failed!";
} else {
echo "Uploaded {$image} to {$ftpServer} as {$fileNameOnFTPServer}";
}
ftp_close($connect);
}
}
Note: Sometimes file_exists() doesn't behave the way we intended when the path begins with /. For example /path/to/file might exist but file_exists() will think it doesn't unless you remove the beginning "/". One way to get around that is to check it like this:
file_exists(substr($newFile, 1))
Good luck!
An alternative solution if you do not have exec privileges is to use curl to grab the image, or you could use file_get_contents(), there are many ways, its just personal preference.
Ive put together what your script may look like, im sure you can improve it.
insert.php
<?php
if(isset($_POST['image']) && isset($_POST['title'])){
if(substr($_POST['image'],0,4)=='http'){
$image = curlgetimage($_POST['image']);
$info = pathinfo($_POST['image']);
if(isset($info['extension']) && ($info['extension']=='gif' || $info['extension']=='png' || $info['extension']=='jpg')){
$path='./temp/'.md5($_POST['image']).'.'.$info['extension'];
file_put_contents($path,$image);
if(ftp_put_image($path)===true){
//Do your database stuff, remember to escape..
unlink($path);
echo 'Success';
}else{
echo 'ftp-fail';
}
}else{
echo'File type not allowed';
}
}else{
echo'Must start with http://';
}
}else{
header('Location: http://www.example.com/');
}
function ftp_put_image($file){
if(!file_exists($file)){return false;}
$fp = fopen($file, 'r');
$conn_id = ftp_connect('ftp.yourhost.com'); //change
$login_result = ftp_login($conn_id,'username','password'); //change
$return=(ftp_fput($conn_id, $file, $fp, FTP_BINARY))?true:false;
ftp_close($conn_id);
fclose($fp);
return $return;
}
function curlgetimage($url) {
$header[] = 'Accept: image/gif, image/x-bitmap, image/jpeg, image/pjpeg';
$header[] = 'Connection: Keep-Alive';
$header[] = 'Content-type: application/x-www-form-urlencoded;charset=UTF-8';
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_USERAGENT, 'YourSpiderBot/0.01 (Bla Bla Robot; http://www.example.com; spider#example.com)'); //change
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_REFERER, $url);
curl_setopt($curl, CURLOPT_ENCODING, 'gzip,deflate');
curl_setopt($curl, CURLOPT_AUTOREFERER, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_TIMEOUT, 60);
$return = curl_exec($curl);
curl_close($curl);
return $return;
}
?>

Categories