i'm trying to use pionl/laravel-chunk-upload and Resumable.js to upload large file into server
i implemented view, controller and route and now when i try to upload file i get this error:
Symfony\Component\HttpFoundation\File\Exception\FileException: The
file "XXXXXXXX" was not uploaded due to an unknown error. in file
C:\xampp\htdocs\XXX\vendor\symfony\http-foundation\File\UploadedFile.php
on line 213
and i can't fix this error:
view:
<div class="form-group">
<div class="resumable-error">
Your browser, unfortunately, is not supported by Resumable.js. The library requires support for the HTML5 File API along with file slicing.
</div>
<div class="resumable-drop">
Drop video files here to upload or <a class="resumable-browse"><u>select from your computer</u></a>
</div>
<div class="resumable-progress">
<table>
<tr>
<td style="width: 100%"><div class="progress-container"><div class="progress-bar"></div></div></td>
<td class="progress-text" nowrap="nowrap"></td>
<td class="progress-pause" nowrap="nowrap">
<img src="/assets/global_assets/images/icons/resume.png" title="Resume upload" />
<img src="/assets/global_assets/images/icons/pause.png" title="Pause upload" />
<img src="/assets/global_assets/images/icons/cancel.png" title="Cancel upload" />
</td>
</tr>
</table>
</div>
<ul class="nav nav-sidebar mb-2 resumable-list p-0 pl-3 m-0" data-nav-type="accordion"></ul>
</div>
<script>
var r = new Resumable({
target: '/panel/uploadRadioChannelFile',
chunkSize: 1 * 1024 * 1024,
testChunks: false,
throttleProgressCallbacks: 1,
headers:{
'X-CSRF-Token' :"{{ csrf_token() }}"
},
query:{
_token : "{{ csrf_token() }}"
}
});
// Resumable.js isn't supported, fall back on a different method
if (!r.support) {
$('.resumable-error').show();
} else {
// Show a place for dropping/selecting files
$('.resumable-drop').show();
r.assignDrop($('.resumable-drop')[0]);
r.assignBrowse($('.resumable-browse')[0]);
// Handle file add event
r.on('fileAdded', function (file) {
// Show progress pabr
$('.resumable-progress, .resumable-list').show();
// Show pause, hide resume
$('.resumable-progress .progress-resume-link').hide();
$('.resumable-progress .progress-pause-link').show();
// Add the file to the list
$('.resumable-list').append('<li class="nav-item resumable-file-' + file.uniqueIdentifier + '">Uploading <span class="resumable-file-name"></span> <span class="resumable-file-progress"></span>');
$('.resumable-file-' + file.uniqueIdentifier + ' .resumable-file-name').html(file.fileName);
// Actually start the upload
r.upload();
});
r.on('pause', function () {
// Show resume, hide pause
$('.resumable-progress .progress-resume-link').show();
$('.resumable-progress .progress-pause-link').hide();
});
r.on('complete', function () {
// Hide pause/resume when the upload has completed
$('.resumable-progress .progress-resume-link, .resumable-progress .progress-pause-link').hide();
});
r.on('fileSuccess', function (file, message) {
// Reflect that the file upload has completed
$('.resumable-file-' + file.uniqueIdentifier + ' .resumable-file-progress').html('(completed)');
});
r.on('fileError', function (file, message) {
// Reflect that the file upload has resulted in error
$('.resumable-file-' + file.uniqueIdentifier + ' .resumable-file-progress').html('(file could not be uploaded: ' + message + ')');
});
r.on('fileProgress', function (file) {
// Handle progress for both the file and the overall upload
$('.resumable-file-' + file.uniqueIdentifier + ' .resumable-file-progress').html(Math.floor(file.progress() * 100) + '%');
$('.progress-bar').css({width: Math.floor(r.progress() * 100) + '%'});
});
r.on('cancel', function () {
$('.resumable-file-progress').html('canceled');
});
r.on('uploadStart', function () {
// Show pause, hide resume
$('.resumable-progress .progress-resume-link').hide();
$('.resumable-progress .progress-pause-link').show();
});
}
</script>
route:
Route::post('uploadRadioChannelFile', 'UploadController#upload');
and controller:
class UploadController extends Controller
{
public function upload(Request $request)
{
try {
$receiver = new FileReceiver("file", $request, HandlerFactory::classFromRequest($request));
if ($receiver->isUploaded() === false) {
return response()->json([
"done" => '',
'status' => false
]);
}
$save = $receiver->receive();
if ($save->isFinished()) {
return $this->saveFile($save->getFile());
}
$handler = $save->handler();
return response()->json([
"done" => $handler->getPercentageDone(),
'status' => true
]);
} catch (UploadFailedException $e) {
}
}
protected function saveFile(UploadedFile $file)
{
$fileName = $this->createFilename($file);
//$mime = str_replace('/', '-', $file->getMimeType());
$dateFolder = Carbon::now()->year;
$public_html = config('app.public_path');
$filePath = "upload/{$dateFolder}/";
$file->move($public_html.$filePath, $fileName);
return response()->json([
'path' => $filePath,
'name' => $fileName,
'ffff' => $file->getClientOriginalName(),
]);
}
protected function createFilename(UploadedFile $file)
{
//$extension = $file->getClientOriginalExtension();
//$filename = str_replace("." . $extension, "", $file->getClientOriginalName()); // Filename without extension
//$filename .= "_" . md5(time()) . "." . $extension;
return time() . '.' . $file->getClientOriginalExtension();
}
}
Related
Trying to upload a photo locally using Laravel with Vuejs
I am sending the file from the Vue component to the backend like the code below:
<div class="form-group">
<label for="photo">photo</label>
<input
type="file"
class="form-control"
id="photo"
name="photo"
ref="inputFile"
/>
<hr />
</div>
<button
type="submit"
class="btn btn-primary">
Add
</button>
</form>
and this is the script in the same component
import { mapActions } from "vuex";
export default {
data() {
return {
category: {
photo: this.$refs.inputFile,
csrf: document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
config: {
headers: { 'content-type': 'multipart/form-data' }
}
},
};
},
methods: {
...mapActions(["createCategory"]),
submitForm() {
const form_data = new FormData();
form_data.append('photo', this.category.photo);
form_data.append('csrf', this.category.csrf);
// The following method is the mapped action
this.createCategory(form_data);
}
},
};
</script>
The mutations.js file
createCategory(state, category) {
axios.post('http://127.0.0.1:8000/api/categories', category).then(res => {
console.log("Response: " + res);
}).catch(res => {
console.log("Exp: " + res);
});
}
The actions.js file
createCategory(context, category) {
context.commit('createCategory', category);
}
At the backend I am using categories driver in
> filesystems.php as the following:
'categories' => [
'driver' => 'local',
'root' => base_path() . '/images/categories',
'url' => env('APP_URL').'/public',
'visibility' => 'public',
],
uploading the file using $request->photo->store method as the code in the following Controller
public function store(CategoryRequest $request) {
try {
// Start Uploading File
$file = "";
if($request->has('photo')) {
$file = $request->photo;
$folder = 'categories';
$file->store('/', $folder);
$filename = $file->hashName();
$path = 'images/' . $folder . '/' . $filename;
}
// End Uploading File
// Start creating category
$category = new Category();
$category->photo = $path;
$category->save();
// End creating category
return response()->json(['message' => 'Created Successfully'], 200);
} catch(\Exception $ex) {
return $ex;
}
}
I tried several ways to make a chunked upload but did not work with me anyway and I still try but without benefit, Any help, I want to use this package:
pionl/laravel-chunk-upload
Upload files via AJAX with jQuery and chunked upload,
That's what I tried:
<script type="text/javascript" src="{{ asset('js/jquery.iframe-transport.js') }}"></script>
<script type="text/javascript" src="{{ asset('js/jquery.fileupload.js') }}"></script>
<script type="text/javascript" src="{{ asset('js/jquery.ui.widget.js') }}"></script>
<div class="text-center">
<input id="fileupload" type="file" name="file" data-url="{{ url('upload') }}" style="display: inline;">
<ul id="file-upload-list" class="list-unstyled">
</ul>
</div>
<script type="text/javascript">
var $ = window.$; // use the global jQuery instance
var $uploadList = $("#file-upload-list");
var $fileUpload = $('#fileupload');
if ($uploadList.length > 0 && $fileUpload.length > 0) {
var idSequence = 0;
// A quick way setup - url is taken from the html tag
$fileUpload.fileupload({
maxChunkSize: 1000000,
method: "POST",
// Not supported
sequentialUploads: false,
formData: function (form) {
// Append token to the request - required for web routes
return [{name: '_token', value: $('input[name=_token]').val()}];
},
progressall: function (e, data) {
var progress = parseInt(data.loaded / data.total * 100, 10);
$("#" + data.theId).text('Uploading ' + progress + '%');
},
add: function (e, data) {
data._progress.theId = 'id_' + idSequence;
idSequence++;
$uploadList.append($('<li id="' + data.theId + '"></li>').text('Uploading'));
data.submit();
},
done: function (e, data) {
console.log(data, e);
$uploadList.append($('<li></li>').text('Uploaded: ' + data.result.path + ' ' + data.result.name));
}
});
}
</script>
My Controller:
public function upload(Request $request) {
// create the file receiver
$receiver = new FileReceiver("file", $request, HandlerFactory::classFromRequest($request));
// check if the upload is success, throw exception or return response you need
if ($receiver->isUploaded() === false) {
throw new UploadMissingFileException();
}
// receive the file
$save = $receiver->receive();
// check if the upload has finished (in chunk mode it will send smaller files)
if ($save->isFinished()) {
// save the file and return any response you need, current example uses `move` function. If you are
// not using move, you need to manually delete the file by unlink($save->getFile()->getPathname())
return $this->saveFile($save->getFile());
}
// we are in chunk mode, lets send the current progress
/** #var AbstractHandler $handler */
$handler = $save->handler();
return response()->json([
"done" => $handler->getPercentageDone(),
'status' => true
]);
}
Any successful way to do that?
I am trying to upload image but getting the error Uncaught (in promise) Error: Request failed with status code 404
Here is my code
<input type="file" id="file" class="form-control-file" v-on:change="onFileChange">
methods:{
goToLogin(){
this.upload();
},
onFileChange(e){
console.log('onFileChange');
let files = e.target.files || e.dataTransfer.files;
if(!files.length){
return;
}
this.createImage(files[0]);
},
createImage(file){
console.log('createImage');
let reader = new FileReader();
let vm = this;
reader.onload = (e) =>{
vm.image = e.target.result;
};
reader.readAsDataURL(file);
},
upload(){
console.log('upload image= '+this.image);
axios.post('/storage/images',{image: this.image}).then(response => {
console.log(response.data);
});
}
}
public function saveImage(Request $request){
$image = $request->file('image');
$filename = time() . '.' . $image->getClientOriginalExtension();
$path = public_path('images/' . $filename);
$user->image = $filename;
$user->save();
}
In upload method i am getting data in image but issue is within '/storage/images'. Can anybody please help me to fix it.
Why is it the file i upload not reflecting on the request even though the file is uploaded successfully?
HTML
<div id="upload_excel" class="dropzone form-control">
<div class="fallback">
<input name="file" type="file" multiple />
</div>
</div>
JS
var baseUrl = "{{ url('/') }}";
var token = "{{ Session::getToken() }}";
Dropzone.autoDiscover = false;
var myDropzone = new Dropzone("#upload_excel", {
paramName: "file",
acceptedFiles: ".xls,.xlsx",
maxFiles: 1,
maxFilesize: 10,
url: baseUrl + "/upload",
params: {
_token: token
}
});
Controller
class UploadsController extends Controller
{
public function upload(Request $request) {
return $file = $request->all();
}
}
Request Preview
[
Request Response
{"_token":"ePssa9sPZxTcRR0Q4Q8EwWKjODXQ8YpCcH8H9wRP","upload_date":"2016-08-02","file":{}}
Did i miss something or what?
I have a controller like this
public function upload(Request $request) {
// validation etc
// ...
// I have a table and therefore model to list all excels
$excelfile = ExcelFile::fromForm($request->file('file'));
// return whater ...
}
In my ExcelFile Model
protected $baseDir = 'uploads/excels';
public static function fromForm(UploadedFile $file) {
$excelfile = new static;
$name = time() . $file->getClientOriginalName();
$name = preg_replace('/\s+/', '', $name);
$excelfile->path = $excelfile->baseDir . '/' . $name;
$file->move($excelfile->baseDir, $name);
return $excelfile;
}
You will also need to add UploadedFile in your Model
use symfony\Component\HttpFoundation\File\UploadedFile;
My dropzone is defined like this to ensure correct token handling
<form action="/users/{{ $id }}/media/excelupload" id="drop-zone" class="dz dropzone">
{{ csrf_field() }}
</form>
<script>
new Dropzone("#drop-zone", {
maxFilesize: 3, // MB
maxFiles: 10,
dictDefaultMessage: "Upload Excel.",
init: function() {
var known = false;
this.on("success", function(file, responseText) {
// do stuff
});
this.on('error', function() {
// aler stuff
});
this.on("addedfile", function() {
if (this.files[10]!=null){
this.removeFile(this.files[0]);
if (known === false) {
alert('Max. 10 Uploads!')
known = true;
}
}
});
}
});
</script>
I hope this helps
I want to get value from file input from angularjs form in laravel, but i can't get the value.
why?
angularjs:
<div ng-controller="UploadImgController" >
<div ng-repeat="image in images">
<img ng-src="{{image.image}}" />
</div>
<form ng-submit="uploadImg()" method="post" enctype="multipart/form-data">
Select image to upload:
<input type="file" name="path" id="path" ng-model="addimages.path" accept="image/*" app-filereader>
<input type="text" name="propertyid" ng-model="addimages.propertyid">
<input type="submit" value="Upload Image" name="submit" class="btn btn-primary" >
</form>
</div>
laravel (UploadImgController.php):
public function store()
{
$file = Input::file('path');
echo "file: ".$file;
}
(routes.php):
Route::resource('img','UploadImgController');
I got no value. What should I do? Thank you. :)
I recommend using ng-file-upload.
View
<button ng-file-select ng-model="myFiles" ng-file-change="upload($files)">Upload</button>
Angular JS
var app = angular.module('fileUpload', ['angularFileUpload']);
app.controller('MyCtrl', ['$scope', '$upload', function ($scope, $upload) {
$scope.upload = function (files) {
if (files && files.length){
for (var i = files.length - 1; i >= 0; i--) {
var file = files[i];
$upload.upload({
url: '/upload',
fields: {key: 'value'},
file: file
})
.progress(function (evt) {
var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
console.log('File upload ' + progressPercentage + "% complete.");
})
.success(function (data, status, headers, config) {
console.log(data);
})
.error(function(data, status, headers, config) {
console.log(data);
});
}
}
};
}
]);
Laravel Route
Route::post('upload', [
'uses' => 'FileUploadController#upload'
]);
Laravel Controller
public function upload() {
$file = \Input::file('file');
return $file;
}
You can pull that off without a plugin actually. I did face a similar problem once and this is how I went about it.
View
<input type="file" name="file" onchange="angular.element(this).scope().uploadImage(this.files)"/>
Angularjs Controller
$scope.uploadavtar = function (files) {
var fd = new FormData();
//Take the first selected file
fd.append("file", files[0]);
$http.post("/upload-url" + $scope.school.profile.id, fd, {
withCredentials: true,
headers: {'Content-Type': undefined},
transformRequest: angular.identity
}).then(function successCallback(response) {
$scope.result = response;
// this callback will be called asynchronously
// when the response is available
}, function errorCallback(response) {
console.log(response);
// called asynchronously if an error occurs
// or server returns response with an error status.
});
}
Routes.php
Route::post('/upload-url', 'UsersController#uploadFile');
Laravel Controller
// Upload files
public function uploadFile(Requests\UpdateuploadfileRequest $request, $id)
{
$extension = Input::file('file')->getClientOriginalExtension();
$fileName = time().'.'.$extension; // renameing image
$destination = 'uploads/img'. $fileName;
move_uploaded_file($_FILES['file']['tmp_name'], $destination);
}
}
Request validation file (UpdateuploadfileRequest.php)
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
$rules = [
];
return $rules;
}