(1/1) ErrorException Undefined offset: 1 - php

I was trying to update my userprofile with the following controller but the problem is if i update only profile picture it shows the above error..But if i update every value it update successfully. How do i update the userProfile without updating every value :
public function updateUser(Request $request)
{
$this->validate($request, [
'profile_picture' => 'dimensions:width=400,height=400',
'cover_picture' => 'dimensions:width=800,height=400',
'avatar' => 'dimensions:width=80,height=80',
]);
if (\Auth::check())
{
$user= User::find(\Auth::id());
}
$files= [];
if($request->file('profile_picture')) $files[] = $request->file('profile_picture');
if($request->file('cover_picture')) $files[] = $request->file('cover_picture');
if($request->file('avatar')) $files[] = $request->file('avatar');
foreach($files as $file)
{
if(!empty($file))
{
$filename = time().str_random(20). '.' . $file->getClientOriginalExtension();
$file->move('users/',$filename);
$filenames[]=$filename;
}
}
$user->profile_picture = $filenames[0];
$user->cover_picture = $filenames[1];
$user->avatar = $filenames[2];
$user->save();
return redirect::back()->with('Warning',"Profile Updated Successfully");
}

I don't think it's wise using a positional array like this, As you've discovered, what if someone only wants to update their avatar. I feel your assignment into $files[] is redundant and you could go straight into your processing code.
Basically your current implementation means $files can be of a variable length, how do you know which is 0, 1 or 2 etc ?
With my approach, the code is now looping over each type of picture, and assigns it into the user with $user->$type directly by the same matching type property.
foreach( array( 'profile_picture', 'cover_picture', 'avatar' ) as $type)
{
if( $request->file( $type ) )
{
$filename = time() . str_random(20) . '.' . $request->file( $type )->getClientOriginalExtension();
$request->file( $type )->move( 'users/', $filename );
$user->$type = $filename;
}
}
If you find you need to map a different $source to the $type variable, you could do this with an additional array index...
foreach( array(
'profile_picture' => 'profile_picture',
'cover_picture' => 'cover_picture',
'avatar' => 'avatar'
) as $source => $type)
{
if( $request->file( $source ) )
{
$filename = time() . str_random(20) . '.' . $request->file( $source )->getClientOriginalExtension();
$request->file( $source )->move( 'users/', $filename );
$user->$type = $filename;
}
}

I finally came up with a solution mate.
You can try to Include a var_dump of $filenames. I suppose that $filenames[1] doesn't exist at all.

Related

Multiple file upload and location store using laravel

I have an app which stores music from user. User can upload multiple files at once. But while adding this code, the database and the controller only uploads the first file, discarding other files. I need to solve this problem. Any solutions?
UploadController.php
public function store(Request $request)
{
//This is a complex way to store user id. If any easy way, then help me.
$curruser = auth()->user();
$userid = $curruser->id;
$songs = $request->file('songs');
$paths = [];
if(!empty($songs)){
foreach ($songs as $song){
$filename = $song->getClientOriginalName();
$filesize = $song->getSize();
$extension = $song->getClientOriginalExtension();
$paths[] = $song->storeAs('songs',$filename);
$path = new MusicUpload(array(
'user_id' => $userid,
'filename' => $filename,
'extension' => $extension,
'filesize' => $filesize,
));
$path->save();
$paths[] = $path;
return redirect('/fileupload')->with('success','Uploaded successfully');
}
}
}
And also I cannot store the location of the file in the mysql server. Any ideas to do that also. Thanks
Use this
public function store(Request $request)
{
$input = $request->all();
$rules = array(
'songs.*' => 'required|mimes:jpeg,png,jpg,doc,docx,pdf,mp4,mov,ogg,qt', //etc
);
$validator = Validator::make($input, $rules);
if ($validator->fails()) {
$arr = array("status" => 400, "message" => $validator->errors()->first(), "data" => array());
} else {
try {
$datas = [];
$result = [];
if ($request->hasfile('songs')) {
foreach ($request->file('songs') as $key => $file) {
$name = $file->getClientOriginalName();
$extension = $file->getClientOriginalExtension();
$filesize = $file->getSize();
$input['songs'] = time() .uniqid().'.' . $file->getClientOriginalExtension();
$file->move(public_path() . '/images', $input['songs']); // your file path
$datas[$key] = $name;
$datas[$key] = $extension;
$datas[$key] = $filesize;
$file = new MusicUpload();
foreach ($datas as $data) {
$file->user_id = Auth::user()->id;
$file->filename = $name;
$file->extension = $extension;
$file->filesize = $filesize;
$file->save();
}
}
}
$arr = array("status" => 200, "message" => "success", "data" => $output);
} catch (\Exception $ex) {
if (isset($ex->errorInfo[2])) {
$msg = $ex->errorInfo[2];
} else {
$msg = $ex->getMessage();
}
$arr = array("status" => 400, "message" => $msg, "data" => array());
}
}
return \Response::json($arr);
}
Just return the redirection after foreach loop has completed.
public function store(Request $request)
{
//This is a complex way to store user id. If any easy way, then help me.
$curruser = auth()->user();
$userid = $curruser->id;
$songs = $request->file('songs');
$paths = [];
if(!empty($songs)){
foreach ($songs as $song){
$filename = $song->getClientOriginalName();
$filesize = $song->getSize();
$extension = $song->getClientOriginalExtension();
$paths[] = $song->storeAs('songs',$filename);
$path = new MusicUpload(array(
'user_id' => $userid,
'filename' => $filename,
'extension' => $extension,
'filesize' => $filesize,
));
$path->save();
$paths[] = $path;
}
return redirect('/fileupload')->with('success','Uploaded successfully');
}
}

Inserting Empty String or Null Images in Laravel

I can't insert a string or a null value in the database resulting in the following error:
SQLSTATE[HY000]: General error: 1364 Field 'paxsafety_video'
doesn't have a default value (SQL: insert into pax_safeties
(paxsafety_image, updated_at, created_at) values
(Desert_1543390457.jpg, 2018-11-28 15:34:17, 2018-11-28 15:34:17))
Controller
$this->validate($request, [
'paxsafety_image.*' => 'nullable|image|mimes:jpeg,jpg,png',
'paxsafety_video.*' => 'nullable|mimes:mp4,mov,ogg | max:20000'
]);
$paxSafety = [];
$paxSafetyVideo = [];
if ($request->has('paxsafety_image') && $request->has('paxsafety_video'))
{
//Handle File Upload
foreach ($request->file('paxsafety_image') as $key => $file)
{
// Get FileName
$filenameWithExt = $file->getClientOriginalName();
//Get just filename
$filename = pathinfo( $filenameWithExt, PATHINFO_FILENAME);
//Get just extension
$extension = $file->getClientOriginalExtension();
//Filename to Store
$fileNameToStore = $filename.'_'.time().'.'.$extension;
//Upload Image
$path = $file->storeAs('public/paxsafety_folder',$fileNameToStore);
array_push($paxSafety, $fileNameToStore);
}
foreach ($request->file('paxsafety_video') as $key => $file)
{
// Get FileName
$filenameWithExt2 = $file->getClientOriginalName();
//Get just filename
$filename = pathinfo( $filenameWithExt2, PATHINFO_FILENAME);
//Get just extension
$extension2 = $file->getClientOriginalExtension();
//Filename to Store
$fileNameToStore2 = $filename.'_'.time().'.'.$extension2;
//Upload Image
$path = $file->storeAs('public/paxsafety_folder',$fileNameToStore2);
array_push($paxSafetyVideo, $fileNameToStore2);
}
$fileNameToStore = serialize($paxSafety);
$fileNameToStore2 = serialize($paxSafetyVideo);
}
else
{
$paxSafety[]='noimage.jpg';
$paxSafetyVideo[]='noimage.jpg';
}
foreach ($paxSafety as $key => $value) {
$paxSafetyContent = new PaxSafety;
$paxSafetyContent->paxsafety_image = !empty($value) ? $value : '';
foreach ($paxSafetyVideo as $key => $values) {
$paxSafetyContent->paxsafety_video = !empty($values) ? $values : '';
}
$paxSafetyContent->save();
}
change in schema PaxSafety set default nullable.
$table->string('paxsafety_video')->nullable()->change();
otherwise CHANGE IN CONTROLLER..
$paxSafetyContent = new PaxSafety;
$paxSafetyContent->paxsafety_image = !empty($values) ? $values : 'noimage.jpg';
$paxSafetyContent->paxsafety_video = NULL;
$paxSafetyContent->save();
one or more tricks is add $fillable columns in PaxSafety Model
protected $fillable = ['paxsafety_image','paxsafety_video'];
now in controller used like that using create model method
PaxSafety::create(['paxsafety_image' => !empty($values) ? $values : 'noimage.jpg']);
Try this.
$paxSafetyContent = new PaxSafety;
$paxSafetyContent->paxsafety_image = !empty($paxSafety) ? $paxSafetyVideo : '';
$paxSafetyContent->paxsafety_video = !empty($paxSafetyVideo) ? $paxSafetyVideo : '';
$paxSafetyContent->save();
In the PaxSafety add the following:
protected $casts = [
'paxsafety_image' => 'array',
'paxsafety_video' => ' array'
];
Also make sure both are in the $fillable ariae in the model.
This will allow you to save the image and video URLs as an array in the DB.
Hope this helps.

uploading only one image second shows me error in laravel

I'm trying to save array of multi images and values , the values was saving well but when i going to add image it's only save one image and upload only one .
Here's my controller function
public function store(Request $request) {
$parentproduct = new Product();
$parentproduct->id = Input::get('id');
$parentproduct->save();
$insertedId = $parentproduct->id;
$uploadcount=0;
$files = Input::file('main_image');
$file_count = count($files);
foreach($files as $i=>$file) {
$multiupload=new ProductsTranslation();
if($request->hasFile('main_image')){
$destinationPath = 'website/images';
$filename = $file->getClientOriginalName();
$upload_success = $file->move($destinationPath, $filename);
$uploadcount ++;
$multiupload->main_image = $filename;
$multiupload->id = $request->input('id')[$i];
$multiupload->title = $request->input('title')[$i];
$multiupload->language = $request->input('language')[$i];
$multiupload->product_id=$parentproduct->id;
$multiupload->save();
}
}
It's working fine after the final update ...
try this:
if (Input::hasFile('main_image')) {
foreach (Input::file('main_image') as $file) {
$destinationPath = 'website/images';
$filename = $file->getClientOriginalName();
$upload_success = $file->move($destinationPath, $filename);
$uploadcount ++;
// You have to initialize your array out side your loop
$insertprod = [];
foreach ($request->input('language') as $i=>$language) {
$insertprod[] = array(
'id' =>$request->input('id')[$i],
'product_id'=>$parentproduct->id,
'title' =>$request->input('title')[$i],
'language' => $request->input('language')[$i],
//used this line to save the image name path !
'main_image'=>$filename[$i]
);
}
}
DB::table('products_translations')->insert($insertprod);
}

Laravel 5: Insert image urls into column as array

I am building an application using Laravel 5 where I want to insert several image urls within an array separated by commas. This would be placed in a column on the database. The files are successfully uploaded to my AWS S3 bucket, but it's now the input to the database. I tried using Laravel's array_add helper but I get an error stating I am missing argument 2. I am wondering how would I be able to achieve this. My current alternate solution is to put the images with the post id and use the relationship to connect them together.
For reference: The column I intend to place the images is picgallery, and the insert is done using $newproperty['picgallery'] variable.
public function store(Request $request)
{
//establish random generated string for gallery_id
$rando = str_random(8);
//input all data to database
$data = $request->all();
$newproperty['title'] = $data['title'];
$newproperty['address'] = $data['address'];
$newproperty['city'] = $data['city'];
$newproperty['province'] = $data['province'];
$newproperty['contact_person'] = Auth::user()->id;
$newproperty['gallery_id'] = $rando;
$newproperty['property_description'] = $data['description'];
if($request->hasfile('images')) {
$files = $request->file('images');
//storage into AWS
foreach ($files as $file) {
$uploadedFile = $file;
$upFileName = time() . '.' . $uploadedFile->getClientOriginalName();
$filename = strtolower($upFileName);
$s3 = \Storage::disk('s3');
$filePath = 'properties/' . $rando . '/' . $filename;
$s3->put($filePath, file_get_contents($uploadedFile), 'public');
$propicurl = 'https://s3-ap-southeast-1.amazonaws.com/cebuproperties/' . $filePath;
$array = array_add(['img'=> '$propicurl']);
$newproperty['picgallery'] = $array;
}
}
Properties::create($newproperty);
return redirect('/properties');
}
array_add requires 3 parameters
$array = array_add($array, 'key', 'value');
(https://laravel.com/docs/5.1/helpers#method-array-add)
For example
$testArray = array('key1' => 'value1');
$testArray = array_add($testArray, 'key2', 'value2');
and you will get
[
"key1" => "value1",
"key2" => "value2",
]
You might not be able to use array_add in this case.
I think in order to fix your issue, fix your foreach loop to be something like this
//storage into AWS
// init the new array here
$array = [];
foreach ($files as $file) {
$uploadedFile = $file;
$upFileName = time() . '.' . $uploadedFile->getClientOriginalName();
$filename = strtolower($upFileName);
$s3 = \Storage::disk('s3');
$filePath = 'properties/' . $rando . '/' . $filename;
$s3->put($filePath, file_get_contents($uploadedFile), 'public');
$propicurl = 'https://s3-ap-southeast-1.amazonaws.com/cebuproperties/' . $filePath;
// change how to use array_add
array_push($array, array('img' => $propicurl));
// remove the below line
// $array = array_add($array, 'img', $propicurl);
}
// move this assignment out of foreach loop
$newproperty['picgallery'] = $array;

Using same function 2nd time

I'm declaring the following function to get a random image from a directory. I want to use the same function in same code to get random image from a different directory. Now the problem is that I have to change $path but I have already used it in declaration while i want to use the different path when I use the function 2nd time
Declaration part
function getImagesFromDir($path) {
$images = array();
if ( $img_dir = #opendir($path) ) {
while ( false !== ($img_file = readdir($img_dir)) ) {
// checks for gif, jpg, png
if ( preg_match("/(\.gif|\.jpg|\.png)$/", $img_file) ) {
$images[] = $img_file;
}
}
closedir($img_dir);
}
return $images;
}
I use it this way 1st time
$root = '';
$path = 'frames/';
$imgList = getImagesFromDir($root . $path);
$img = getRandomFromArray($imgList);
How shud i use it 2nd time so that it chooses image from different directory.
Probably you don't call the function twice, but declare it twice.
declaration:
function getImagesFromDir($path) {
$images = array();
if ( $img_dir = #opendir($path) ) {
while ( false !== ($img_file = readdir($img_dir)) ) {
// checks for gif, jpg, png
if ( preg_match("/(\.gif|\.jpg|\.png)$/", $img_file) ) {
$images[] = $img_file;
}
}
closedir($img_dir);
}
return $images;
}
calls:
$images1 = getImagesFromDir("/var/www/images1");
$images2 = getImagesFromDir("/var/www/images2");
if you write
function getImagesFromDir($path) ....
again anywhere it gets redeclared and PHP don't supports this
this also happens if you require the file, which declares the function, more than once.
-- edit ---
$strRoot = '';
$astrImages = array();
$astrImages[] = array( 'path' => 'frames/', 'image' => '' );
$astrImages[] = array( 'path' => 'etc1/', 'image' => '' );
$astrImages[] = array( 'path' => 'etc2/', 'image' => '' );
$astrImages[] = array( 'path' => 'etc3/', 'image' => '' );
foreach( $astrImages as $nIndex => $astrImage )
{
$imgList = getImagesFromDir($strRoot . $astrImage['path']);
$astrImages[$nIndex]['image'] = getRandomFromArray($imgList);
}

Categories