Having trouble uploading multiple files - php

Can save individual files, however, with multiple it doesn't appear to get a proper array from $request->file() and foreach fails.
Client
$scope.setFiles = function(element) {
$scope.$apply(function($scope) {
console.log('files:', element.files);
// Turn the FileList object into an Array
$scope.files = []
for (var i = 0; i < element.files.length; i++) {
$scope.files.push(element.files[i])
}
$scope.progressVisible = false
});
};
$scope.uploadFile = function() {
var fd = new FormData()
for (var i in $scope.files) {
fd.append("file", $scope.files[i])
}
var boundary=Math.random().toString().substr(2);
var xhr = new XMLHttpRequest()
xhr.upload.addEventListener("progress", uploadProgress, false)
xhr.addEventListener("load", uploadComplete, false)
xhr.addEventListener("error", uploadFailed, false)
xhr.addEventListener("abort", uploadCanceled, false)
xhr.open("POST", "/fileupload",true)
$scope.progressVisible = true
xhr.setRequestHeader("X-CSRF-TOKEN", csrftoken);
xhr.setRequestHeader('X-Requested-With','XMLHttpRequest');
// xhr.setRequestHeader("content-type","multipart/form-data; charset=utf-8; boundary=" + boundary);
xhr.send(fd)
}
Laravel
public function fileUpload(Request $request)
{
$files = $request->file('file');
$file_count = count($files);
echo $file_count;
foreach ($files as $file) {
$oname = $file->getClientOriginalName();
$filename = $oname.'.'.$file->getClientOriginalExtension();
$file->move(
base_path() . '/uploads/applicants/', $filename
);
}
}

Please use $request->allFiles() instead, it returns an array of all of the files on the request:
foreach ($request->allFiles() as $file) {
//You code here !
}

You must make two changes:
Move a $scope.files out of the method $scope.SetFile
Convert the file into an array parameter

Related

Laravel session::has('key') doesn't exist after new request

First time working with Laravel and a bit confused.
Performing ajax request into controller action and after next request session key I've stored before doesn't exist.
The purpose of this code is to save some set of images and store their names to session for further work..
Session ID's equal in my parent page and ajax request. Application has no user authenticaton yet.
(Upd) Session driver is 'file' by default.
Why session key doesn't save normally?
public function upload(Request $request)
{
$rules = ['photo.*' => 'image|mimes:jpeg,png,jpg|max:2048'];
$validator = Validator::make($request->all(), $rules);
$files = [];
$fileNames = [];
$errors = [];
if ($validator->fails()) {
$errors = ArrayHelper::getFinalValuesRecursive($validator->errors()->messages());
} else {
foreach ($request->file('photo') as $key => $value) {
$imageName = $key . md5(time() . $key) . '.' . $value->getClientOriginalExtension();
$value->move(public_path('uploads'), $imageName);
$fileNames[] = $imageName;
$files[] = '/uploads/' . $imageName;
}
$sessionFiles = [];
if (Session::has('photo')) {
$sessionPhoto = Session::get('photo');
foreach ($sessionPhoto as $value) {
$sessionFiles[] = $value;
}
}
Session::put('photo', array_merge($sessionFiles, $fileNames));
}
Javascript
$(document).ready(function () {
$('#photo').on('change', function () {
var fileData = $('#photo').prop('files');
var formData = new FormData();
for (var i = 0; i < fileData.length; i++) {
formData.append('photo[]', fileData[i]);
}
formData.append("_token", $('input[name="_token"]').attr('value')); //csrf
$.ajax({
url: '{{route('adverts.upload')}}',
dataType: 'text',
cache: false,
contentType: false,
processData: false,
data: formData,
type: 'post',
success: function (response) {
response = $.parseJSON(response);
if (response.errors.length) {
for (var i = 0; i < response.errors.length; i++) {
$('#image_errors')
.append('<div class="invalid-feedback" style="display: block;">' + response.errors[i] + '</div>');
}
} else {
$('#image_errors').html('');
var totalFile = response.files.length;
for (var i = 0; i < totalFile; i++) {
$('#image_preview').append("<img src='" + response.files[i] + "'>");
}
}
}
});
});
});

Getting multiple json objects when uploading mutliple images

When I upload multiple images I don't get any info in my console, but when I upload one image then that image's info is shown in my console. What I would like is that if I upload more then one image I can get that info so that I can then loop through it and display it in my page through the addThumbnail() function.
When I upload mutliple images this shows up in my Response in my network tab
{"name":"kitten_01.jpg"}{"name":"kitten_05.jpg"}
and my console in blank, but when I upload one image I get
{"name":"kitten_05.jpg"}
and I get this in my console
Object { name: "kitten_05.jpg" }
Here is my main.js
$(document).ready(function(){
var dropZone = document.getElementById('drop-zone');
$(".upload-area").on('drop', function(e){
e.preventDefault();
var files_list = e.originalEvent.dataTransfer.files;
var formData = new FormData();
for(i = 0; i < files_list.length; i++){
formData.append('file[]', files_list[i]);
}
$.ajax({
url:"upload.php",
method:"POST",
data:formData,
contentType:false,
cache: false,
processData: false,
dataType: 'json',
success:function(response){
addThumbnail(response);
}
})
});
dropZone.ondragover = function(e){
return false;
}
dropZone.ondragleave = function(e){
return false;
}
});
function addThumbnail(data){
var len = $("#drop-zone div.thumbnail").length;
var num = Number(len);
num = num + 1;
var name = data.name;
console.log(data);
$("#uploaded-image").append('<div id="thumbnail_'+num+'" class="thumbnail"></div>');
$("#thumbnail_"+num).append('<img src="uploads/'+name+'" width="100%" height="78%">');
}
and this is my upload.php
$allowed = ['png', 'jpg'];
foreach($_FILES['file']['name'] as $key => $name)
{
$temp = $_FILES['file']['tmp_name'][$key];
$ext = explode('.', $name);
$ext = strtolower(end($ext));
$return_arr = array();
if(in_array($ext, $allowed) && move_uploaded_file($temp, 'uploads/'.$name))
{
$return_arr = array("name" => $name);
}
echo json_encode($return_arr);
}
$allowed = ['png', 'jpg'];
$return_arr = array();
foreach($_FILES['file']['name'] as $key => $name)
{
$temp = $_FILES['file']['tmp_name'][$key];
$ext = explode('.', $name);
$ext = strtolower(end($ext));
if(in_array($ext, $allowed) && move_uploaded_file($temp, 'uploads/'.$name))
{
$return_arr = array("name" => $name);
}
}
echo json_encode($return_arr);

File path / Directory path not working

I get 500 (Internal Server Error) when loading the file inside Codeigniter controller function. What I did is.
PHP:
public function load () {
$dir = "_resources/documents";
$files = scandir($dir);
$ret = array();
foreach($files as $file) {
if($file == "." || $file == "..")
continue;
$filePath = $dir."/".$file;
$data = array(
'name' => $file,
'path' => $filePath,
'size' => filesize($filePath)
);
$ret[] = $data;
}
echo json_encode($ret);
}
and when I inspect the element of the image it becomes
src = _resources/documents/example.jpg
Now in the console, the path becomes
http://localhost/project/document_items/_resources/documents/example.jpg
I wanted it to be
http://localhost/project/_resources/documents/example.jpg
Note that document_items is the name of my controller.
Jquery:
var baseurl = window.location.protocol + "//" + window.location.host + "/project/";
var loadfile = baseurl + 'document_items/load';
$("#fileuploader").uploadFile({
onLoad:function(obj)
{
$.ajax({
cache: false,
url: loadfile,
dataType: "json",
success: function(data)
{
for(var i=0;i<data.length;i++)
{
obj.createProgress(data[i]["name"],data[i]["path"],data[i]["size"]);
}
}
});
}
});
try using the following code snippet:
$this->load->helper('url');
$dir = base_url("_resources/documents");
$files = scandir("_resources/documents");

how to parse html already store in variable

I want to parse a shoutcast page like this :
http://relay.181.fm:8800/played.html
So, i just make ajax to call a php file. The php file return all the content of the page.
i store the html content to a var in js. Here is the code:
PHP:
function getcontent($server, $port, $file){
$cont = "";
$ip = gethostbyname($server);
$fp = fsockopen($ip, $port);
if (!$fp){
return "Unknown";
}
else{
$com = "GET $file HTTP/1.1\r\nAccept: */*\r\nAccept-Language: de-ch\r\n"
."Accept-Encoding: gzip, deflate\r\nUser-Agent: Mozilla/4.0 (compatible;"
." MSIE 6.0;Windows NT 5.0)\r\nHost: $server:$port\r\n"
."Connection: Keep-Alive\r\n\r\n";
fputs($fp, $com);
while (!feof($fp))
{
$cont .= fread($fp, 500);
}
fclose($fp);
$cont = substr($cont, strpos($cont, "\r\n\r\n") + 4);
return $cont;
}
}
echo (getcontent("relay.181.fm", "8800", "/played.html"));
Here is my js:
var xhr = new XMLHttpRequest();
var parsed;
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
parsed=xhr.response;
}
};
xhr.open("GET", 'http://localhost/getsong.php', true);
xhr.send(null);
And that is what i want to get:
$(document).ready(function(){
var songs=new Array();
var time=new Array();
for (var i = 0; i < 10; i++) {
songs[i]=$('table:eq(2) tr:eq('+(i+1)+') td:eq(1)').text();
time[i]=$('table:eq(2) tr:eq('+(i+1)+') td:eq(0)').text();
};
});
if i copy the xhr.response content and i put it in the html file and i execute this js, it return me exactly what i want.
but i dont get how i can do when the html is in a variable... :'(
PS: i work on a wamp env., And a node.js env.
Since you tagged it with jQuery, why not use the built in ajax functionality:
$.ajax({
url: 'http://localhost/getsong.php',
dataType: 'html'
}).done(function(data){
//do something with the HTML
var $html = $(data),
tdtexts = $html.find('table:eq(2) tr td:first').text();
});
Is this what you're asking for?
I think, you can use innerHTML to resolve
var xhr = new XMLHttpRequest();
var parsed;
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
parsed=xhr.response;
document.getElementById('#div').innerHTML = parsed;
}
};
xhr.open("GET", 'http://localhost/getsong.php', true);
xhr.send(null);
Proceeding further after getting response may help you like,
var xhr = new XMLHttpRequest();
var parsed;
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
parsed=$.parseHTML(xhr.response);
var songs=new Array();
var time=new Array();
for (var i = 0; i < 10; i++) {
songs[i]=$(parsed).find('table:eq(2) tr:eq('+(i+1)+') td:eq(1)').text();// use find function for parsed string
time[i]=$(parsed).find('table:eq(2) tr:eq('+(i+1)+') td:eq(0)').text();
};
}
};
xhr.open("GET", 'http://localhost/getsong.php', true);
xhr.send(null);
By using $.ajax()
$(function(){
$.ajax({
url:'http://localhost/getsong.php',
dataType:'html',
success:function(parsed){
var songs=new Array();
var time=new Array();
for (var i = 0; i < 10; i++) {
songs[i]=$(parsed).find('table:eq(2) tr:eq('+(i+1)+') td:eq(1)').text();// use find function for parsed string
time[i]=$(parsed).find('table:eq(2) tr:eq('+(i+1)+') td:eq(0)').text();
};
}
});
});
I think you're looking for jQuery.parseHTML(). It will parse your string into an array of DOM nodes.
http://api.jquery.com/jQuery.parseHTML/
Here's a quick example for your case:
$.get('http://relay.181.fm:8800/played.html')
.done(function(data) {
var parsed = $.parseHTML(data);
// Now parsed is an array of DOM elements which you can use selectors on, eg:
var song1 = $(parsed).find('table:eq(2) tr:eq(1) td:eq(1)').text();
console.log(song1);
});

Uploading files with XMLHttpRequest

I am new to XMLHttpRequest and I have been using it as a AJAX file uploader using JavaScript's FormData().
The problem I am having is that it seems to upload fine, although I think it is not sending it to the right PHP file or my PHP is wrong because nothing is displayed in the folder where pictures should be.
At the moment, I don't know how to view the returned html data
JavaScript:
$("#form").submit(function(event) {
event.preventDefault();
event.stopPropagation();
var form = $(this);
var file = document.getElementById("file");
var data = new FormData();
var onerror = function(event) {
alert("An error occoured!");
}
var onprogressupdate = function(event) {
if(event.lengthComputable) {
var percent = event.loaded / event.total * 100;
$("#progress").html(percent+"%");
}
}
var onreadystatechange = function(event) {
if(request.status == 200 && request.readyState == 4) {
alert("Uploaded!");
$("#progress").hide();
$("#progress").html("");
}
else {
alert("Alternative state and/or status");
console.log("state: " + request.state);
console.log("readyState: " + request.readyState);
}
}
for(var i = 0; i < file.files.length; i++)
data.append('file[]', file.files[i]);
$("#progress").show();
$("#progress").html("Uploading files...");
var request = new XMLHttpRequest();
request.upload.addEventListener("error", onerror);
request.upload.addEventListener("progress", onprogressupdate);
request.upload.addEventListener("readystatechange", onreadystatechange);
request.open("post", "upload.php");
request.setRequestHeader("Content-type", "multipart/form-data");
request.send(data);
});
Upload page
<?php
if(isset($_FILES["file"])) {
$f = $_FILES["file"];
$dir = "data";
if(!file_exists($dir))
mkdir($dir);
foreach($f["name"] as $k => $name) {
$file = $dir."/".$name;
if($f["error"][$k] == 0 && move_uploaded_file($f["tmp_name"][$k], $file)) {
$uploaded[] = $file;
}
}
die(json_encode($uploaded));
}
?>
Don't set the content type, its set automatically.
Create your FormData object with form element you want to send:
var data = new FormData(this);
instead of
var data = new FormData();
The syntax of the FormData is
new FormData (optional HTMLFormElement form)
without the argument, it is empty, see the reference.

Categories