Handling File Upload Exception - Laravel - php

This is how i upload a file into my database but i am not able to handle my exception when the file uploaded is an invalid format or type.
I am able to handle exception when no file is uploaded but not when the file type is invalid or does not meet the standard.
How do i get this done please?
Controller
public function import($id, Request $request)
{
$country= Country::all()->where('id',$id)->first();
if($request->file('imported-file'))
{
$path = $request->file('imported-file')->getRealPath();
$data = Excel::load($path, function($reader)
{
})->get();
if(!empty($data) && $data->count())
{
foreach ($data->toArray() as $row)
{
if(!empty($row))
{
$dataArray[] =
[
'name' => $row['name'],
];
}
else {
return redirect('admin')->with('error','File format Error');
}
}
if(!empty($dataArray))
{
$country->teams()->createMany($dataArray);
return redirect('admin')->with('status','Countries successfully added');
}
}
}
else {
return redirect('admin')->with('error','No file was uploaded');
}
}

From Laravel's documentation, You can accept only a certain type of file using mime validation rule,
'file' => 'required | mimes:application/vnd.ms-excel',
The mime-type application/vnd.ms-excel will match these file extensions xls xlm xla xlc xlt xlw

I have uploading excel files in one of my project. Hope this will helps you:-
$file = Input::file('imported-file');
Excel::load($file ,function($reader){
$reader->each(function($sheet){
YourMOdelName::firstOrCreate($sheet->toArray());
});
});
YourModelName is your table name suppose if table is users so you have to define User in that case.....
From this way you can get the extenstion of your uploading file:-
$ext= Input::file('imported-file')->getClientOriginalExtension();
echo $ext; //print the extension here
Hope it willl help!

Okay i solved this in a very simple way by checking out the laravel documentation. So here is what i just added
if(($request->file('imported-file')->getClientOriginalExtension() != 'xls, xlm, xla ,xlc, xlt, xlw'))
{
}
else {
//process the file
}

Related

WordPress: functions.php is not in array error message

I do have the following code:
add_filter('upload_mimes','restrict_mimes_for_subscriber');
function restrict_mimes_for_subscriber($mimes) {
if (! current_user_can('delete_posts')) {
return;
}
$mimes = array(
'pdf' => 'application/pdf',
'jpg|jpeg' => 'image/jpeg'
);
return $mimes;
}
and I want to add an error message if the uploaded file is not in the array of allowed mimes for a subscriber. The below snippet is what I found already
if (! in_array("uploaded-file", $mimes)) {
echo "Error: Only PDF and JPG files allowed.";
}
But I do not know how I get the "uploaded-file" to compare it against the array? Any help to complete my code please?
And I think the snippet has to go into my code just before the return statement or?
Many thanks and cheers
Yogie

Inserts with Laravel 5.1 without page reloading

I've been using Dropzone for several days and I faced some issues. The idea is: the user selects his file, it uploads and goes in his file directory and some of the file's properties (size, name) go in the DB. I can't do it because when the user uploads the file, the page does not refresh and nothing goes in Input::file('file'). I just can't do it. Here is the code i'm using:
class UploadController extends Controller {
public function upload() {
if(Input::hasFile('file')){
$file = Input::file('file');
$user = Auth::id();
$file->move('uploads/'.$user, $file->getClientOriginalName());
}
else {
echo 'Please select a file first';
}
}
Here are the two functions in File.php model
public function getFileId(){
$fileName = Input::file('file')->getClientOriginalName();
$files = File::where('filename', $fileName)->get(); //$fileName
foreach ($files as $file) {
$fileid = $file->fileid;
echo $fileid.'<br>';
Input::file('file')->fileid = $file->fileid; // put fileid as an attribute to the object file for futher usage
}
}
public function incrementFileId(){
$files = File::orderBy('fileid', 'desc')->take(1)->get();
foreach($files as $file){
echo $file->fileid + 1 .' incremented file id<br>';
}
}
So how should my third model function look like to upload the file's properties? DropZone uses Ajax and I though that I should get the file attributes from there but could this be done?!
Use Request instead of Input:
public function upload(Request $request)
{
if ($request->hasFile('file'))
{
$file = $request->file('file');
$file->move('uploads/'.$user, $file->getClientOriginalName());
}

naming a file after submitting a form in Symfony

I am working on a form which accepts some user input and an image file, the submission part and the data getting entered into the database is working fine but I am stuck at how to name a file once it is uploaded, right now this is what i see as an image name in database C:\wamp2.5\tmp\phpF360.tmp which obviously is not correct.
This is what my controller looks like DefaultController.php
public function createBlogAction(Request $request)
{
$post = new Post();
$form = $this->createForm(new PostCreate(), $post);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$post->upload();
$post->setDate(date_create(date('Y-m-d H:i:s')));
$post->setAuthor('ClickTeck');
$em->persist($post);
$em->flush();
$this->get('session')->getFlashBag()->add(
'notice',
'Success'
);
}
return $this->render('BlogBundle:Default:blog-create.html.twig', array(
'form' => $form->createView()
)
);
}
This is what my upload() looks like inside Entity/Post.php which is uploading the file and moving it into the folder, the file name that I see in a folder is correct however now the one that goes into the database
public function upload()
{
if (null === $this->getImage()) {
return;
}
// I might be wrong, but I feel it is here that i need to name the file
$this->getImage()->move(
$this->getUploadRootDir(),
$this->getImage()->getClientOriginalName()
);
$this->path = $this->getUploadDir();
$this->file = null;
}
I will really appreciate if someone can push me in right direction, I just need to name the file, a name which gets assigned to the image in database and the file should get uploaded with the same name as well.
UPDATE
I managed to get it to work using the following function, not sure if this is the best practice but it did work, i would love to hear from others on this. please do not provide any links, if you can refine what has already been done that would be great.
public function upload()
{
// the file property can be empty if the field is not required
if (null === $this->getImage()) {
return;
}
$dirpath = $this->getUploadRootDir();
$image = $this->getImage()->getClientOriginalName();
$ext = $this->getImage()->guessExtension();
$name = substr($image, 0, - strlen($ext));
$i = 1;
while(file_exists($dirpath . '/' . $image)) {
$image = $name . '-' . $i .'.'. $ext;
$i++;
}
$this->getImage()->move($dirpath,$image);
$this->image = $image;
$this->path = $this->getUploadDir();
$this->file = null;
}
This topic from documentation may help you : http://symfony.com/doc/current/cookbook/doctrine/file_uploads.html
In addition, you should not put your upload function in the controller but rather use Doctrine events (Lifecycle callbacks) to call your function automatically.
as per suggestion of #theofabry you can check symfony2 documentation How to handle File Uploads with Doctrine, Controller must be thin as much as possible and try to do upload with Doctrine Events.
If you want to continue with your logic you may try following code, I have not tested yet...so please be careful.
// set the path property to the filename where you'ved saved the file
$this->path = $this->file->getClientOriginalName();
instead of
$this->path = $this->getUploadDir();

How to save file to server after checking for validation with PHP

If a user uploads a file and the contents are retrieved like so
$file = $_FILES['uploadedFile'];
Then, the file is sent to a function to make sure it's an accepted file type. If it is, save it on the server
function saveInputFile($file){
if($check->checkFile($file)== TRUE){
//save $file on my server
}
else{
echo "can't be saved!";
}
}
Assuming it passes the checkFile function, how can I then save this file to my server from within the saveInputFile function? Can I set the file equal to a variable, and then save that variable or do I have to save the file directly from the POST data?
I've seen it done like this, but I already have the file passed into this function.
if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {
echo "The file ". basename( $_FILES['uploadedfile']['name']). " has been uploaded";
} else{
echo "There was an error uploading the file, please try again!";
}
When it comes down to it, I want to save a file in the following function. Can I pass the file like a variable as I did in the saveInputFile function above, or does it not work like this?
You can make the upload file a type of it's own that has the methods it needs next to it's data. That will make the usage more flexible:
$upload = new UploadFile($_FILES['uploadedFile']);
$message = saveInputFile($upload);
echo $message;
function saveInputFile(UploadFile $upload)
{
if ($check->checkFile($upload->getBasename()) == TRUE) {
$message = $upload->moveTo($target_path)
? sprintf('The file %s has been uploaded', $upload->getBasename())
: 'There was an error uploading the file, please try again!'
;
} else {
$message = "can't be saved!";
}
return $message;
}
The new type UploadFile represents one file from the the $_FILE array, it is a class that wraps the basic data and methods a file-upload carries. Here is some example code:
class UploadFile
{
protected $file;
private $filename;
public function __construct(array $file)
{
$this->file = $file;
}
public function hasError()
{
return $this->getProperty('error') !== UPLOAD_ERR_OK;
}
public function getError()
{
return $this->getProperty('error');
}
public function getBasename()
{
return basename($this->getProperty('name'));
}
public function getFilename()
{
return $this->filename;
}
/**
* #param $newName
* #return NULL|SplFileInfo
* #throws BadMethodCallException
*/
public function moveTo($newName)
{
$newName = (string)$newName;
$filename = $this->getFilename();
if ($filename !== NULL) {
throw new BadMethodCallException(sprintf('Upload file (%s) has been already moved (%s).', $this->getBasename(), $filename));
}
$tmpName = $this->getProperty('tmp_name');
if (move_uploaded_file($tmpName, $newName)) {
$this->filename = realpath($newName);
}
return $this->getFileInfo();
}
/**
* #return SplFileInfo|NULL
*/
public function getFileInfo()
{
$filename = $this->getFilename();
if ($filename !== NULL) {
return new SplFileInfo($filename);
}
}
protected function getProperty($name, $default = NULL)
{
if (isset($this->file[$name])) {
return $this->file[$name];
}
return $default;
}
}
Use it at your will. See as well SplFileInfo and the documentation about file uploads in the PHP manual which documents the structure of the $_FILE array and the PHP upload error codes (which are important).
Your move_uploaded_file function should take 2 parameters, the source file name and the destination file name.
In PHP the file move function is called rename.

Zend_Progressbar + JQuery + uploading a video

I would like to show a dynamic progressbar in my applciation while uploading a video (*.flv format). I searched on the Web for more than 2 hours but I can't find any tutorial to guide me through this process.
What I have so far:
script that uploads a video
jQuery library included in the section
But what to do next? Here is the controller action for uploading a video I use:
public function uploadPublicVideoAction()
{
$request = $this->getRequest();
$media = $this->_getTable('Media');
$form = $this->_getForm('UploadPublicVideo',
$this->_helper->url('upload-public-video'));
// if POST data has been submitted
if ($request->isPost()) {
// if the UploadPublicVideo form has been submitted and the submitted data is valid
if (isset($_POST['upload_public_video']) && $form->isValid($_POST)) {
$data = $form->getValues();
$data['user_id'] = $this->view->identity->id;
$ext = end(explode('.', $form->video->getFileName()));
$dbTrans = false;
try {
$db = $this->_getDb();
$dbTrans = $db->beginTransaction();
$data['type'] = 'video';
$data['status'] = 'public';
$paths = $media->add($data, $ext);
if (file_exists($paths[0])) {
unlink($paths[0]);
}
if (file_exists($paths[1])) {
unlink($paths[1]);
}
// add filter for renaming the uploaded photo
$form->video->addFilter('Rename',
array('target' => $paths[0],
'overwrite' => true));
// upload the video
$form->video->receive();
// create a thumbnail
//$this->_helper->FlvThumbnail($path[0], $path[1]);
$db->commit();
$form->reset();
$this->view->success = 'Public video successfully uploaded';
} catch (Exception $e) {
if (true === $dbTrans) {
$db->rollBack();
}
$this->view->error = $e->getMessage();
}
}
}
$this->view->headTitle('Upload Public Video');
$this->view->form = $form;
}
Can anyone show me a simple way to use Zend_Progressbar and jQuery together to achieve a dynamic upload progressbar?
You can do either long (comet) or short polling (ajax) to achieve the desired effect. With the former I would suggest making the request in an iFrame and having your code write out JS which will get executed as they come in, with the latter just do something like:
var pollingId = window.setInterval(poll, 250);
function poll(){
//make an AJAX request, do something with it (like update your progress bar).
if(done){
window.clearInterval(pollingId);
}
}

Categories