Laravel 4 TokenMissMatchException with Plupload - php

I'm trying to upload files with Plupload but I always get TokenMissMatchException.
// Route
Route::post("/posts/gallery", "PostsController#uploadGallery");
// Controller action
public function uploadGallery(){
$file = Input::file('file');
$destinationPath = public_path() . '/imgs';
$extension = $file->getClientOriginalExtension();
$filename = "post-" . str_random(12) . "." . $extension;
$inFile = $file->getRealPath();
$outFile = public_path() . "/imgs/" . $filename;
$image = new Imagick($inFile);
$image->thumbnailImage(550, 0);
if($image->writeImage($outFile)){
return Response::json(["response" => "ok", "img" => $filename]);
}else{
return Response::json(["response" => "error"]);
}
}
This is my attempt to fix this. I tried to add _token to request but it's not picking it up:
$("#uploader").pluploadQueue({
runtimes : 'html5,flash,silverlight,html4',
url : "{{ URL::action('PostsController#uploadGallery') }}",
chunk_size: '1mb',
rename : true,
dragdrop: true,
filters : {
max_file_size : '3mb',
mime_types: [
{title : "Image files", extensions : "jpg,gif,png"},
]
},
resize : {width : 320, height : 240, quality : 90},
flash_swf_url : "<?php echo public_path() . '/js/Moxie.swf'; ?>",
silverlight_xap_url : "<?php echo public_path() . '/js/Moxie.xap'; ?>",
prevent_duplicates: true,
multipart_params : {
"_token" : $("[name=_token]").val()
}
});
In filters.php I have this:
Route::filter('csrf', function() {
$token = Request::ajax() ? Request::header('x-csrf-token') : Input::get('_token');
if (Session::token() != $token){
throw new Illuminate\Session\TokenMismatchException;
}
});
Can someone help me with this?
UPDATE:
Html form for uploading files:
<div class="imageGallery">
{{ Form::open() }}
<div id="uploader">
<p>Your browser doesn't have Flash, Silverlight or HTML5 support.</p>
</div>
{{ Form::close() }}
</div>
// hidden input field
<input type="hidden" value="VJRUpvq92oYxCsNHVBi5TqqkU6I6CQayay6x7L0m" name="_token">

If the upload is being done via ajax, your csrf filter is expecting the token to be in the 'x-csrf-token' header, not the input.
Instead of adding the token to the multipart_params, try adding it to the headers:
$("#uploader").pluploadQueue({
runtimes : 'html5,flash,silverlight,html4',
url : "{{ URL::action('PostsController#uploadGallery') }}",
chunk_size: '1mb',
rename : true,
dragdrop: true,
filters : {
max_file_size : '3mb',
mime_types: [
{title : "Image files", extensions : "jpg,gif,png"},
]
},
resize : {width : 320, height : 240, quality : 90},
flash_swf_url : "<?php echo public_path() . '/js/Moxie.swf'; ?>",
silverlight_xap_url : "<?php echo public_path() . '/js/Moxie.xap'; ?>",
prevent_duplicates: true,
headers: {
"x-csrf-token" : $("[name=_token]").val()
}
});
Edit
In addition to the above change, it was determined that the javascript was not finding the _token input element to get the value. The solution to that issue was to add quotes around the value in the CSS attribute selector.
The javascript that ended up working:
$("input[name='_token']").val()
The CSS3 docs regarding attribute selectors can be found here. Although some browsers work without the quotes, the examples they provide show the selector values being quoted.

Related

Plupload not uploading ({FileName}.part)

I'm using Laravel Plupload Library in my Laravel app.
It returns that in response when I'm trying to upload images:
jsonrpc:"2.0"
result : null
and It seems everything is ok.But still uploading like {FileName}.part in my upload dir.
I've checked my php.ini and nothing wrong.
(upload_max_filesize : 200M,max_upload_files: 200,post_max_size=200M)
My js codes :
$("#image_uploader").pluploadQueue({
runtimes : 'html5,flash,silverlight,html4',
url : url,
chunk_size : '1mb',
rename : 'false',
dragdrop: 'true',
multiple_queues : true,
filters : {
max_file_size : '80mb',
mime_types: [
{title : "Image Files", extensions : "jpg,gif,png,jpeg"},
]
},
resize: {
width : '300',
height : '450',
quality : '90',
crop: 'true'
},
flash_swf_url : '/plupload/js/Moxie.swf',
silverlight_xap_url : '/plupload/js/Moxie.xap',
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
I had this same issue with Plupload and the issue with the PHP rename function
rename("{$filePath}.part", $filePath);
It failed and the .part extension remained on the uploaded file. Not sure if your upload script has this step but thought it worth mentioning in case!

How to get absolute url for a widget assets in Yii

I want to create a Widget in Yii framework that uploads multiple files (I`m using uploadify js/swf plugin). So I defined my widget class something like this:
<?php
class MultipleUploads extends CWidget {
public $assetsPath;
public $assetsDir;
public function init()
{
parent::init();
$this->assetsDir = $this->assetsPath ? $this->assetsPath : dirname(__FILE__) . '/assets/multipleUploads';
$dir = Yii::app()->assetManager->publish($this->assetsDir);
$cs = Yii::app()->clientScript;
$cs->registerCoreScript('jquery');
$cs->registerScriptFile($dir . '/jquery.uploadify.min.js', CClientScript::POS_HEAD);
$cs->registerCssFile($dir . '/uploadify.css', CClientScript::POS_END);
}
public function run() {
$this->render('multipleUploads/index', array('dir' => Yii::app()->getAssetManager()->publish($this->assetsDir)));
}
}
?>
and the view is:
<script type="text/javascript" src="http://localhost/arhitect/assets/be04804/jquery.uploadify.min.js"></script>
<link rel="stylesheet" type="text/css" href="http://localhost/arhitect/assets/be04804/uploadify.css"/>
<h1>Upload files</h1>
<form>
<div id="queue"></div>
<input id="file_upload" name="file_upload" type="file" multiple="true">
</form>
<script type="text/javascript">
$(function() {
$('#file_upload').uploadify({
'formData' : {
'token' : 'xxx',
'action' : 'upload'
},
'auto' : false,
'queueSizeLimit' : 20,
'removeCompleted' : false,
'swf' : 'http://localhost/arhitect/assets/be04804/uploadify.swf',
'uploader' : '<?php echo Yii::app()->createAbsoluteUrl('project/index');?>',
'fileTypeExts' : '*.gif; *.jpg; *.jpeg; *.png',
'fileSizeLimit' : '10MB',
'progressData' : 'all',
'onFallback' : function() {
alert('Flash was not detected.');
},
'onUploadSuccess' : function(file, data, response) {
console.log('response ' + response);
},
'onUploadError' : function(file, errorCode, errorMsg, errorString) {
console.log('The file ' + file.name + ' could not be uploaded: ' + errorString);
},
'onQueueComplete' : function(queueData) {
parent.validate('refresh');
}
});
});
Note the hardcoded paths in the view file (the .js and .css files): if Im using the hardcoded path, the widget is rendered correctly. Is there any way to get the absolute url path to the assets widget folder?
Thanks.

How pass and receive formData values in Uploadify?

I have been trying to pass and modify data from the client side of uploadify to the server file uploadify.php using the formData setting. I have tried many of the solutions posted on here and the uploadify forums but with no avail.
Initially both formData values are set to the string 'empty' and then when an upload starts, eAlias is set to 2 and eDate to a date. The server script then receives these values by POST and echos them back to the client script which displays this data in an alert (in onUploadSuccess). In all the possible solutions tried the values are either "" or 'empty', ie the setting on the formData keys in onUploadStart doesn't work.
I have included most of the client script and the server script below.
Any help or advice would be greatly appreciated, thank you.
Client-side script:
<script type="text/javascript">
$(document).ready(function()
{
$(".uploadifyfile").uploadify(
{
'swf' : '/xx/uploadify.swf',
'uploader' : '/xx/uploadify.php',
'auto' : true,
'height' : 15,
'method' : 'POST',
'multi' : false,
'uploadLimit' : 10,
'formData' : { 'eAlias' : 'empty', 'eDate' : 'empty' },
'onUploadSuccess' : function(file, data, response)
{
alert('The file ' + file.name + ' was successfully uploaded with a response of ' + response + ' : ' + data);
document.getElementById("adminForm")[buttonPressed].value = data;
},
'onUploadStart' : function(file)
{
var eventDate = "<?php echo $this->row->dates; ?>";
var eventVenue = 'test';
alert('Venue Alias: ' + eventVenue + '\neventDate: ' + eventDate);
//**** The line below is the one in question ****//
$(".uploadifyfile").uploadify("settings", "formData", {"eAlias": 2, "eDate" : eventDate});
},
'onSelect' : function(event, ID, fileObj)
{
var eid = event.id;
if(eid == "SWFUpload_0_0")
{
window.buttonPressed = "custom01";
alert('1');
}
...
}
});
});
</script>
Server-side script
$targetFolder = '/xx/uploads'; // Relative to the root
if (!empty($_FILES)) {
$tempFile = $_FILES['Filedata']['tmp_name'];
$targetPath = $_SERVER['DOCUMENT_ROOT'] . $targetFolder;
$targetFile = rtrim($targetPath,'/') . '/' . $_FILES['Filedata']['name'];
// Set $someVar to 'someValue'
$eventAlias = $_POST['eAlias'];
$eventDate = $_POST['eDate'];
// Validate the file type
$fileTypes = array('jpg','jpeg','gif','png'); // File extensions
$fileParts = pathinfo($_FILES['Filedata']['name']);
if (in_array($fileParts['extension'],$fileTypes)) {
move_uploaded_file($tempFile,$targetFile);
echo $targetFolder . '/' . $_FILES['Filedata']['name'];
echo ' eventAlias: '.$eventAlias.' eventDate: '.$eventDate;
} else {
echo 'Invalid file type.';
}
}
The problem was as I thought; it was because I was using multiple instances of the uploadify button and referring to them using the .uploadifyfile class. Uploadify doesn't seem to work fully when using classes.
The, probably rudimentary, solution I came up with was to use the 'onSelect' function to store the id of the button pressed into a global variable (window.uploadid) and then use this in the 'onUploadStart' function. Now, for example, when the 2nd button is pressed, the fileType attribute is changed to finalDetails successfully.
I had looked at using jQuery selectors, but they didn't seem to work in this case for id's, just classes.
I've no doubt that there will be several optimisations do be made to the below code, but I hope it will save anyone who was in the same situation as I was many hours of work.
<script type="text/javascript">
$(document).ready(function()
{
$(".uploadifyfile").uploadify(
{
...
'method' : 'post',
'formData' : { 'eventDate' : 'notSet', 'eventVenue' : 'notSet', 'fileType' : 'notSet' },
'onUploadStart' : function(file)
{
var eventDate = "<?php echo $this->row->dates; ?>";
var eventVenue = "<?php echo JFilterOutput::stringURLSafe($this->row->venue); ?>";
$(uploadid).uploadify('settings','formData',{ 'eventDate' : eventDate, 'eventVenue' : eventVenue, 'fileType' : fileType });
},
'onSelect' : function(event, ID, fileObj)
{
alert('event.id:' + event.id);
var eid = event.id; // To determine which button was pressed
if(eid == "SWFUpload_0_0") // Flyer upload
{
window.buttonPressed = "custom01";
window.uploadid = "#file_upload";
window.fileType = "flyer";
}
else if(eid == "SWFUpload_1_0") // Final Details upload
{
window.buttonPressed = "custom02";
window.uploadid = "#file_upload2";
window.fileType = "finalDetails";
}
...
}
});
});
</script>
...
<input type="file" name="file_upload" id="file_upload" class="uploadifyfile" />
...
<input type="file" name="file_upload2" id="file_upload2" class="uploadifyfile" />
your clientSide code is right.i use the same code ,and it works well.so you'd better use id to generate a uploadify instance instead of class

plupload error generation

I am trying to solve a problem with plupload where i show an error in the upload window, generated by upload.php. No matter what i do, i am not able to create the error icon in the window. Although the alerts work fine, the file is always marked as success. Can someone please tell me what am i doing wrong here?
The error from my upload.php is die('{"jsonrpc" : "2.0", "error" : {"code": 500, "message": "File upload failed."}, "id" : "id"}');
And this is the javascript:
// Convert divs to queue widgets when the DOM is ready
$(function() {
// Setup html5 version
$("#html5_uploader").pluploadQueue({
// General settings
runtimes : 'html5',
url : 'upload.php',
max_file_size : '2000mb',
chunk_size : '1mb',
unique_names : false,
// Specify what files to browse for
filters : [
{title : "Video Clips", extensions : "mov,avi,mpg,flv,mp4"},
{title : "Audio Files", extensions : "mp3,wav"},
{title : "Executable Files", extensions : "exe"},
{title : "Zip Files", extensions : "zip,rar"}
],
preinit: attachCallbacks
});
// attach callbacks for FileUploaded and Error
function attachCallbacks(uploader) {
uploader.bind('FileUploaded', function(up, file, response) {
response = jQuery.parseJSON( response.response );
alert(response.error.code);
if (response.error.code == '500') {
alert (response.error.message);
//alert (file.id);
$('#' + file.id).attr('class', 'plupload_failed').find('a').css('display', 'none').attr('title', response.error.message);
file.status = plupload.FAILED;
} else {
alert("yoohoo");
$('#' + file.id).attr('class', 'plupload_done').find('a').css('display', 'none').attr('title', 'Success');
file.status = plupload.DONE;
}
});
}
});
Thanks.
In case anyone else is looking for the solution to this, it's here: http://www.plupload.com/punbb/viewtopic.php?id=1710
The problem is that you're using the FileUploaded event inside the preinit section. You should bind your event on the init section.
(answer from LeandroJF)

Uploadify file uploading

i am trying to use uploadify, to upload pdf or txt files, but without success. Uploadify 2.1.4 uploads just image files. I tried to just rename file extensions, tried to allow ., tried to namely allow pdf or other formats, but Uploadify uploads just F******g images and i do not know why...
Please help me.
I use these settings:
public function show()
{
if(!$this->dir) throw new exception("Upload dir is not set");
if(!$this->url) throw new exception("Upload url is not set");
$rem=(isset($_POST[$this->name."-rem"]))?$_POST[$this->name."-rem"]:"";
$tpl='<div id="'.$this->name.'-queue" class="upload-queue">'.$this->fillQueue().'</div>';
$tpl.='<input id="'.$this->name.'-uploadify" name="'.$this->name.'-uploadify" type="file" />';
$tpl.='<input id="'.$this->name.'-files" name="'.$this->name.'-files" type="hidden" />';
$tpl.='<input id="'.$this->name.'-rem" name="'.$this->name.'-rem" type="hidden" value="'.$rem.'"/>';
//$tpl.='<link rel="stylesheet" type="text/css" href="/uploadify/uploadify.css" />';
$tpl.="<script type=\"text/javascript\"><!--
var ".$this->name."Files=".$this->currentCount.";
function ".$this->name."DeleteFile(where)
{
var rem=$('#".$this->name."-rem').val();
if(rem!='') rem+=',';
$('#".$this->name."-rem').val(rem+$(where).parent().attr('id'));
$(where).parent().remove();
".$this->name."Files--;
if(".$this->name."Files<".$this->count.") $(\"#".$this->name."-uploadifyUploader\").show();
}
$(document).ready(function() {
$(\"#".$this->name."-uploadify\").uploadify({
'uploader' : '/uploadify/uploadify.swf',
'script' : '".$this->url."',
'scriptData' : {'".session_name()."':'".session_id()."'},
'cancelImg' : '/uploadify/cancel.png',
'folder' : '".$this->dir."/thumb',
'queueID' : '".$this->name."-queue',
'auto' : true,
'multi' : ".(($this->count>1)?"true":"false").",
'buttonText' : '".$this->buttonName."',
'fileExt' : '".rtrim($this->fileExt,";")."',
'fileDesc' : '".rtrim($this->fileDesc,",")."',
onError : function (a, b, c, d) {
if (d.status == 404)
alert('Could not find upload script. Use a path relative to: '+'<?= getcwd() ?>');
else if (d.type === \"HTTP\")
alert('error '+d.type+\": \"+d.status);
else if (d.type ===\"File Size\")
alert(c.name+' '+d.type+' Limit: '+Math.round(d.sizeLimit/1024)+'KB');
else
alert('error '+d.type+\": \"+d.text);
},
onComplete : function(event, queueID, fileObj, response, data){
$(\"#".$this->name."-queue\").append('<div id=\"'+fileObj.filePath+'\" class=\"item\"><div style=\"background: url('+fileObj.filePath+') no-repeat 50% 50%\"></div><img src=\"/uploadify/cancel.png\" class=\"delete-file\" onclick=\"".$this->name."DeleteFile(this);\"></div>');
$('#".$this->name."-queue').sortable('refresh');
".$this->name."Files++;
if(".$this->name."Files>=".$this->count.") $(\"#".$this->name."-uploadifyUploader\").hide();
},
onInit : function(){setTimeout(function(){if(".$this->name."Files>=".$this->count.") $(\"#".$this->name."-uploadifyUploader\").hide();},500);}
});
$('#".$this->name."-queue').sortable();
$('#".$this->name."-queue').disableSelection();
$('form').submit(function(){
$('#".$this->name."-files').val($('#".$this->name."-queue').sortable('toArray'));
});
});
--></script>";
return array("",$tpl);
}
...
Thank you!
var settingObject = {
'uploader' : '/uploadify/uploadify.swf', // set your path
'checkScript':'/uploadify/check.php', // set your path
'script' : '/uploadify/uploadify.php', // set your path
'cancelImg' : '/uploadify/cancel.png', // set your path
'folder' : '/files/useruploads',
'auto' : true,
'fileExt' : '*.jpg;*.gif;*.png;*.txt;*.pdf;*.doc;*.docx', // any extension you want to allow
'fileDesc' : 'Upload Files (.JPG, .GIF, .PNG, .TXT, .PDF, .DOC, .DOCX)',
'removeCompleted': false
};
$("#file-1").uploadify(settingObject);
Reference : (File-Extension) http://www.uploadify.com/documentation/options/fileext/
This should work for you..
There might be an issue of Size Limit for each file. Try adding the following
'sizeLimit': 500000
Try to edit upload_max_filesize in your php.ini
Change your current options to these:
$('#file_upload').uploadify({
'uploader' : '/uploadify/uploadify.swf',
'script' : '/uploadify/uploadify.php',
'cancelImg' : '/uploadify/cancel.png',
'folder' : '/uploads',
'fileTypeExt' : '*.jpg;*.gif;*.png', <== this line
'fileTypeDesc' : 'Image Files'
});
For reference: http://www.uploadify.com/documentation/uploadify/filetypeexts/
Change these lines:
'fileTypeExt' : '*.txt;*.pdf;',
'fileTypeDesc' : '*.txt and *.pdf',
Use 'fileExt' : '*.pdf;*.jpg;*.jpeg;*.png', instead of the filename that reads it.

Categories