File Upload into the Application folder - Zend framework 3 - php

i want to upload a file from the form into my Application folder(public/img/clientes/).
my form file upload field:
$this->add(array(
'name' => 'foto',
'attributes' => array(
'type' => 'file',
),
'options' => array(
'label' => 'Logo da empresa:',
),
));
my add action function on the controller:
public function addAction()
{
$form = new ClienteForm();
if ($this->getRequest()->isPost()) {
$data = $this->params()->fromPost();
$form->setData($data);
if ($form->isValid()) {
$data = $form->getData();
$name = $data['foto'];
if(isset($name)){
if(!empty($name)){
$location = __DIR__."../../../public/img/clientes/";
if(!move_uploaded_file($name, $location)){
return $this->redirect()->toRoute('home');
}
}
}
$this->clienteManager->addNewCliente($data);
return $this->redirect()->toRoute('clientes');
}
}
return new ViewModel([
'form' => $form
]);
}
I cant seam to find the reason for this not to workIf anyone could help me with a solution here i would be incredibly grateful.

Hope everything is self-descriptive here. Just the upload location is a bit strange. As every request is handled through index.php by ZF and this file uses chdir(dirname(__DIR__)) method to go to upper level, so everything is relative to the application root. That's why we can access directly public/img/clientes, in this case. But the recommendation set it via the configuration in module.config.php. And make it available using ServiceManager.
Make sure your upload directory has a right permission.
...
if ($this->getRequest()->isPost()) {
// Merge data thus
$data = array_merge_recursive(
$this->getRequest()->getPost()->toArray(),
$this->getRequest()->getFiles()->toArray()
);
$form->setData($data);
if ($form->isValid()) {
$data = $form->getData();
// Upload path
$location = "public/img/clientes/";
// A bit validation of uploaded file
$allowedExtension = array('jpg', 'jpeg', 'png');
$extension = explode('.', $data['foto']['name']);
$extension = end($extension);
$fileName = time() . '.' . $extension;
// Check if everything is OK!
if (0 === $data['foto']['error'] && in_array($extension, $allowedExtension)) {
move_uploaded_file($data['foto']['tmp_name'], $location . $fileName);
} else {
echo 'Something went wrong!';
}
}
}
...

Related

My update function doesn't set values to null after saving

I received help to solve how to delete files uploaded by using the Cakephp Upload package. However, there seems to be a problem with how I update the values of the photo and dir fields. By using unlink I was able to delete the files perfectly, but there seems to be a problem when I try to set the values to null. I made a function to test it out:
public function deletePhoto2($id)
{
// $this->request->allowMethod(['post']);
if ($this->request->is(['patch', 'post', 'put'])) {
$brigada = $this->Brigadas
->findById($id)
->firstOrFail();
$brigada->dir = null;
$brigada->photo = null;
if ($this->Brigadas->save($brigada)) {
$this->Flash->success(__('Your team data has been saved.'));
return $this->redirect(['action' => 'edit', $brigada->id]);
}
$this->set('brigada', $brigada);
}
}
Before saving I find that the value of $brigada->photo and $brigada->dir are null, but values don't save. I have several possibilities that want to explore but my knowledge of PHP is a hindrance:
I may be doing updates wrong. Link
I may need to use the deleteCallback which is documented here, but I don't know how to do it. I figured that it would be with $this->Brigadas->deleteCallback() or something similar, but I'd like to understand an example first, which is why I'm asking. I found no use of these callbacks in any example on the web, and the documentation on events is still a bit esoteric for me.
Here is how BrigadasTable.php is setup to upload files:
// http://josediazgonzalez.com/2015/12/05/uploading-files-and-images/
$this->addBehavior('Josegonzalez/Upload.Upload', [
'photo' => [
'fields' => [
'dir' => 'dir',
'size' => 'photo_size', // defaults to `size`
'type' => 'photo_type', // defaults to `type`
],
'nameCallback' => function ($table, $entity, $data, $field, $settings) {
if ($entity->gvCode){
$array = explode(".", $data['name']);
return strtolower($entity->gvCode) . '_' . date("Ymd-hisa") . '.jpg';
} else{
$array = explode(".", $data['name']);
$newArray = array_pop($array);
return strtolower(join('_', $array)) . '_' . date("Ymd-hisa") . '.jpg';
}
},
'transformer' => function ($table, $entity, $data, $field, $settings) {
$extension = pathinfo($data['name'], PATHINFO_EXTENSION);
// Store the thumbnail in a temporary file
$tmp = tempnam(sys_get_temp_dir(), 'upload') . '.' . $extension;
// Use the Imagine library to DO THE THING
$size = new \Imagine\Image\Box(640, 640);
$mode = \Imagine\Image\ImageInterface::THUMBNAIL_INSET;
$imagine = new \Imagine\Gd\Imagine();
// Save that modified file to our temp file
$imagine->open($data['tmp_name'])
->thumbnail($size, $mode)
->save($tmp);
$filenameTmp = explode('.', $data['name']);
array_pop($filenameTmp);
$filenameTmp = join('_', $filenameTmp) . '.jpg';
// return debug($filenameTmp);
// Now return the original *and* the thumbnail
return [
$data['tmp_name'] => $filenameTmp,
$tmp => 'thumbnail-' . $filenameTmp,
];
},
'deleteCallback' => function ($path, $entity, $field, $settings) {
// When deleting the entity, both the original and the thumbnail will be removed
// when keepFilesOnDelete is set to false
$entity->{$field} = null;
return [
$path . $entity->{$field},
$path . 'thumbnail-' . $entity->{$field}
];
},
'keepFilesOnDelete' => false
]
]);
Thank you!
You can run an update query straight, instead of fetching the record, setting values and saving it.
$query = $this->Brigadas->query();
$query->update()
->set([
'dir' => null,
'photo' => null,
])
->where(<condition>)
->execute();
Incase any of your columns are json,
$query = $this->Brigadas->query();
$query->update()
->set([
'dir = null',
'photo' => null,
])
->where(<condition>)
->execute();

Unable to save image to database and folder using Slim Framework

I am very new to PHP, I am using PHP Slim Framework. I have tried to research through Stack Overflow but didn't find an answer that answered my question.
I am trying add a car description on my school project, it captures all the fields well but the image is not being saved to the database and not being uploaded to the images folder, instead it saves the image in the database as a json as:
{
"car_images":
[
{
"file":"C:\\xampp\\tmp\\php8F2B.tmp"
}
]
}
instead of a91cffe8c9b5082f.jpg.
when I try to view the image in a browser on my localhost it goes to this path:
http://localhost/carbac/public/category_image/%7B%22car_images%22:[%7B%22file%22:%22C://xampp//tmp//php8F2B.tmp%22%7D]%7D
What could I be doing wrong?
Below is my function for capturing the details:
public function add(Request $request, Response $response, $args){
$car_category_id = $request->getParam('car_category_id');
$name = $request->getParam('name');
$description = $request->getParam('description');
$price = $request->getParam('price');
$mileage = $request->getParam('mileage');
$fuel_type = $request->getParam('fuel_type');
$transmission = $request->getParam('transmission');
$fuel_economy = $request->getParam('fuel_economy');
$air_condition = $request->getParam('air_condition');
$hourly_price = $request->getParam('hourly_price');
$daily_price = $request->getParam('daily_price');
$year = $request->getParam('year');
$directory = __DIR__ . '/../../../public/profile_image';
$uploadedFiles = $request->getUploadedFiles()['category_image'];
$avater = $request->getUploadedFiles();
foreach($uploadedFiles as $uploadedFile) {
if ($uploadedFile->getError() === UPLOAD_ERR_OK) {
$avater[] = \App\Helpers\FileUpload::moveUploadedFile($directory, $uploadedFile, ['png', 'jpeg', 'gif', 'jpg']);
} else {
$Flash = new Flash();
$Flash->addMessage('message', "Sorry, something went wrong from our end, please notify site owner");
$Flash->addMessage('status', "callout-danger");
return $response->withRedirect($this->router->pathFor('car_description'));
}
}
if( ! $avater ) {
$Flash = new Flash();
$Flash->addMessage('message', "Sorry, Please make image you are uploading is either a 'png', 'jpeg' or 'gif'");
$Flash->addMessage('status', "callout-danger");
return $response->withRedirect($this->router->pathFor('car_description'));
}
$car_description = CarDescription::create([
'car_category_id' => $car_category_id,
'name' => $name,
'description' => $description,
'year' => $year,
'mileage' => $mileage,
'price' => $price,
'fuel_type' => $fuel_type,
'transmission' => $transmission,
'fuel_economy' => $fuel_economy,
'air_condition' => $air_condition,
'hourly_price' => $hourly_price,
'daily_price' => $daily_price,
'images' => json_encode($avater)
]);

Image insertion problem into DB in laravel

I am facing this error while uploading an image with a title and description text to DB in PHP Laravel. I am using the same code for other webpage there it is working properly but the same code is not working here.
Below is a function code inside my controller, where I am passing tile, description, img and input names from a form.
public function submitFanfic(Request $request){
$user_id = session('userid');
$name = $_FILES['img']['name'];
$tem_name = $_FILES['img']['tmp_name'];
$dir = 'public/uploads/fanfic/';
$dir1 = $dir.$name;
move_uploaded_file($tem_name, $dir1);
$data = array(
'fanfic_title' => $request['title'],
'fanfic_desc' => $request['description'],
'img' => $name,
'user_id' => $user_id
);
DB::table('fanfic')->insert($data);
Session::flash('message', 'Fanfic Submitted Successfully');
return redirect('/author/write_fanfic');
}
I tried again and again and this code (specifically for image insertion into DB) worked!!
public function submitFanfic(Request $request){
$user_id = session('userid');
$imageName = $request->file('img');
if($imageName!==null){
// get the extension
$extension = $imageName->getClientOriginalExtension();
// create a new file name
$new_name = date( 'Y-m-d' ) . '-' . str_random( 10 ) . '.' . $extension;
// move file to public/images/new and use $new_name
$imageName->move( public_path('uploads/fanfic'), $new_name);
}
$fanfic_data = array(
'fanfic_title' => $request['title'],
'fanfic_desc' => $request['description'],
'img' => $new_name,
'user_id' => $user_id
);
DB::Table('fanfic')->insert($fanfic_data);
Session::flash('message', 'Fanfic Submitted Successfully');

Laravel - Pass uploaded filename to new function

I'm using Laravel 5.3 and need to upload an xml file and then submit the contents to an api. The client wants it as 2 buttons/user functions where the user should first upload the file and then with a second click submit the contents.
The uploading is working fine and the xml reading and submitting to api is also working properly. I just can't get my upload controller to pass the filename over to the submitting controller. There is no need to store the filename for future use and the processes will follow each other - ie user will upload one file and submit, then upload next file and submit.
Any help would be highly appreciated
upload function:
public function handleUpload(Request $request)
{
$file = $request->file('file');
$allowedFileTypes = config('app.allowedFileTypes');
$rules = [
'file' => 'required|mimes:'.$allowedFileTypes
];
$this->validate($request, $rules);
$fileName = $file->getClientOriginalName();
$destinationPath = config('app.fileDestinationPath').'/'.$fileName;
$uploaded = Storage::put($destinationPath, file_get_contents($file->getRealPath()));
if($uploaded) {
$file_Name = ($_FILES['file']['name']);
}
return redirect()->to('/upload');
}
submit function:
public function vendorInvoice()
{
$fileName = $file_Name;
$destinationPath = storage_path('app/uploads/');
$xml = file_get_contents($destinationPath.$fileName);
$uri = "some uri";
try {
$client = new Client();
$request = new Request('POST', $uri, [
'Authorization' => '$username',
'ContractID' => '$id',
'content-type' => 'application/xml'
],
$xml);
$response = $client->send($request);
}
catch (RequestException $re) {
//Exception Handling
echo $re;
}
}

Yii dropzone extention (The CSRF token could not be verified)

I want to post Yii csrftoken with dropzone request here is my code
$this->widget('ext.dropzone.EDropzone', array(
'model' => $model,
'attribute' => 'file',
'url' => $this->createUrl('//media/file'),
'mimeTypes' => array('image/jpeg', 'image/png'),
'options' => array('sending' => 'function(file, xhr, formData) {
formData.append("YII_CSRF_TOKEN", "' . Yii::app()->request->csrfToken . '");
}',),
));
//controller > media (it dose not access the controller )
public function actionFile() {
$save_path = Yii::app()->basePath . '/../media/portfolio/';
$save_url = Yii::app()->createAbsoluteUrl('//media/portfolio/');
if (empty($_FILES) === false) {
$file_name = $_FILES['Company'] ['name']['file'];
$fileType = $_FILES['Company']['type']['file'];
$tmp_name = $_FILES['Company']['tmp_name']['file'];
$file_size = $_FILES['Company']['size']['file'];
$temp_arr = explode(".", $file_name);
$file_ext = array_pop($temp_arr);
$file_ext = trim($file_ext);
$file_ext = strtolower($file_ext);
if (!file_exists($save_path))
mkdir($save_path);
$new_file_name = rand(0,1000) . '.' . $file_ext;
$file_path = $save_path . $new_file_name;
move_uploaded_file($tmp_name, $file_path);
}
}
This is how to stop CsrfValidation for some actions
//main/config
Add the following lines under components
'request' => array(
'class' => 'HttpRequest',
'noCsrfValidationRoutes' => array(
'^site/upload.*$',
),
'enableCookieValidation' => true,
'enableCsrfValidation' => true,
),
Then inside the component folder
class HttpRequest extends CHttpRequest
{
public $prev_url;
public $noCsrfValidationRoutes = array();
protected function normalizeRequest()
{
parent::normalizeRequest();
if(!isset($_SERVER['REQUEST_METHOD']) || $_SERVER['REQUEST_METHOD'] != 'POST')
{
return;
}
$route = Yii::app()->getUrlManager()->parseUrl($this);
if($this->enableCsrfValidation)
{
foreach($this->noCsrfValidationRoutes as $cr)
{
if(preg_match('#'.$cr.'#', $route))
{
Yii::app()->detachEventHandler('onBeginRequest', array($this,'validateCsrfToken'));
Yii::trace('Route "'.$route.' passed without CSRF validation');
break; // found first route and break
}
}
}
}
public function getCurrentUri()
{
// Get HTTP/HTTPS (the possible values for this vary from server to server)
$myUrl = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] && !in_array(strtolower($_SERVER['HTTPS']),array('off','no'))) ? 'https' : 'http';
// Get domain portion
$myUrl .= '://'.$_SERVER['HTTP_HOST'];
// Get path to script
$myUrl .= $_SERVER['REQUEST_URI'];
// Add path info, if any
$get = $_GET; // Create a copy of $_GET
if (count($get)) { // Only add a query string if there's anything left
$myUrl .= '?'.http_build_query($get);
}
return $myUrl;
}
}
This is what I found that worked in my search for getting the CSRF tokens to work with the xupload/blueimp jquery file uploader. Put this in the file "EHttpRequest.php" (or create it) in your components directory.
Source: http://www.yiiframework.com/forum/index.php/topic/14500-re-writing-a-class-method-without-editing-framework-files/
<?php
class EHttpRequest extends CHttpRequest
{
public function validateCsrfToken($event)
{
if($this->getIsPostRequest())
{
$cookies=$this->getCookies();
if($cookies->contains($this->csrfTokenName) && isset($_POST[$this->csrfTokenName]) || isset($_GET[$this->csrfTokenName] ))
{
$tokenFromCookie=$cookies->itemAt($this->csrfTokenName)->value;
$tokenFrom=!empty($_POST[$this->csrfTokenName]) ? $_POST[$this->csrfTokenName] : $_GET[$this->csrfTokenName];
$valid=$tokenFromCookie===$tokenFrom;
}
else
$valid=false;
if(!$valid)
throw new CHttpException(400,Yii::t('yii','Lite: The CSRF token could not be verified.'));
}
}
}
?>
Caution: There could be some security risks in doing this, if anyone sees anything wrong with this security-wise, let me know.

Categories