How to update session array in laravel 4 - updated with new items - php

I'm using ajax and laravel 4 and I upload files that are arrays - they are multiple. But I'm not sure how to update session array withe the new array. I've tried array_merge but it's overwrited.
My method looks like that:
public function storeFiles() {
$name = Input::get('name');
$input = Input::all();
$current_time = time();
$trim_name = trim($name, '[]');
$corporate_docs = array();
foreach ($input[$trim_name] as $corporate) {
$file_name = $current_time . '_' . $corporate->getClientOriginalName();
$corporate->move(APPLICATIONS_DIR, $file_name);
$corporate_docs[] = $file_name;
}
$session = Session::get($name);
if($session) {
$docs = array_push($session, $corporate_docs);
Session::put($name, $docs);
} else {
Session::put($name, $corporate_docs);
}
}
How should I merge existing session array withe the newly created?
Updated: my code now is:
$trim_name = trim($name, '[]');
$corporate_docs = array();
foreach ($input[$trim_name] as $corporate) {
if ($corporate) {
$file_name = $current_time . '_' . $corporate->getClientOriginalName();
$corporate->move(APPLICATIONS_DIR, $file_name);
$corporate_docs[] = $file_name;
}
}
$session = Session::get($name);
if (Session::has($name)) {
$docs = array_merge($session, $corporate_docs); //dd($docs);
Session::forget($name);
Session::put($name, $docs); dd(Session::get($name));
} else {
Session::put($name, $corporate_docs);
}
But it is everwwriten again. When I add first image, it is stored in session and when I add another, it is merged with the first array but when I add third image, in the newly created session array - it is first image and last image. Second image is overwriten.

Try this:
if(session()->has($name)) {
session()->forget($name);
}
session()->put($name, $corporate_docs);

Related

How to delete folder with images and mysql record news that does not exist

How to delete folder with images and mysql record news that does not exist?
Dont work. Why?
$resnotid = mysqli_query($db, "SELECT id FROM objects");
$idarray[] = array();
$namefolderarray[] = array();
while($rownotid = mysqli_fetch_array($resnotid)) {
$idarray[] = $rownotid['id'];
}
$dir = opendir('upload');
while($folder = readdir($dir)) {
if (is_dir('upload/'.$folder) && $folder != '.' && $folder != '..') {
$namefolderarray[] = $folder;
}
}
$delid = array_diff($namefolderarray, $idarray);
rmdir('upload/'.$delid.'/');
The method array_diff returns an array. So you have to iterate over that array.
$del_arr = array_diff($namefolderarray, $idarray);
foreach ($del_arr as $delid) {
rmdir('upload/'.$delid.'/');
}
Update 1
The previous solution only works for empty folders. If you have any content in the folders you must first delete the content. This can be done with an recursive function that iterates over the contents.
function rmdir_recursively($path) {
if (is_dir($path)){
$list = glob($path.'*', GLOB_MARK);
foreach($list as $item) {
rmdir_recursively($item);
}
rmdir($path);
} else if (is_file($path)) {
unlink($path);
}
}
$del_arr = array_diff($namefolderarray, $idarray);
foreach ($del_arr as $del_id) {
rmdir_recursively('upload/'.$del_id.'/');
}
Update 2
To also delete the database-records without a folder you can extend the code like this:
foreach ($del_arr as $del_id) {
rmdir_recursively('upload/'.$del_id.'/');
$del_id_escaped = mysqli_real_escape_string($del_id);
mysqli_query($db, "DELETE FROM objects WHERE id='$del_id_escaped'");
}

Get googlesheet data by passing spreadsheet id and sheet id

I need to get the google sheet data and then to download it as csv. but the issue is I need to get data by sheet id in the url.
I'm using this package "google/apiclient": "^2.0"
Code
$sheets = new \Google_Service_Sheets($client);
//get spreadsheet id from db
$google_sheet_link = TeamGoogleSheet::where('team_id',$team_id)->first();
$url_array = parse_url($google_sheet_link->url);
$path_array = explode("/",$url_array["path"]);
$spreadsheetId = $path_array[3];
\Log::info('Spreadsheet id');
\Log::info($spreadsheetId);
$range = 'Sheet1';
$rows = $sheets->spreadsheets_values->get($spreadsheetId, $range, ['majorDimension' => 'ROWS']);
if (isset($rows['values'])) {
$filename = storage_path("chat_bots.csv");
if (file_exists($filename))
unlink($filename);
$handle = fopen($filename, 'a');
foreach ($rows['values'] as $key => $data) {
fputcsv($handle, $data);
}
fclose($handle);
$headers = array(
'Content-Type' => 'text/csv',
);
return \Response::download($filename, 'chat_bots.csv', $headers);
}
But this requires the sheet name(range attribute) and also only 1 sheet.I want to make it dynamic. we can get sheetid from url, but didn't find a method to retrieve data by passing this sheet id.
$spreadsheet_data = $sheets->spreadsheets->get($spreadsheetId);
//get sheet titles
$work_sheets = [];
$gid_sheet = '';
foreach($spreadsheet_data->getSheets() as $s) {
$work_sheets[] = $s['properties']['title'];
}
if(preg_match("/[#&]gid=([0-9]+)/", $google_sheet_link->url)){
$explode_array = explode("#gid=",$google_sheet_link->url);
$gid = $explode_array[1];
foreach($spreadsheet_data->getSheets() as $s) {
if($s['properties']['sheetId'] == $gid)
$gid_sheet = $s['properties']['title'];
}
}
if($gid_sheet != ''){
$range = $gid_sheet;
}
else{
$range = $work_sheets[0];
}

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);
}

Phalcon Query super slow inside large loop

I'm using Phalcon 3.0.4. I made a foreach on each file inside my folder. Currently I have just 4000 files. I did a findFirst to check if the filename already exist in MySQL (I have 100 000 rows in my table). But when I use findFirst, the response is super slow (I have to wait 20 minutes to get a response). Here is my code :
$dir = new FilesystemIterator("files/path/to/my/files/");
foreach ($dir as $file) {
if ($file->getExtension() == 'json') {
$filename = $file->getFilename();
$explode_filename = explode("_", $filename);
$date = $explode_filename[0];
$unformatted_date = DateTime::createFromFormat("Ymd-His", $date);
$date_server = $unformatted_date->format("Y-m-d H:i:s");
$timestamp_app = $explode_filename[2];
$date_app = date("Y-m-d H:i:s", $timestamp_app/1000);
echo $date_server;
$json_data = json_decode(file_get_contents($file), true);
$scan = Scans::findFirst(array(
"name = :name:",
"bind" => array("name" => $filename)
));
if (!$scan) {
...
}
}
}
I tried to make my query with the QueryBuilder PHQL but I have the same result:
$scan = $this->modelsManager->createBuilder()
->from("Scans")
->where("name = :name:", ["name" => $filename])
->limit(1)
->getQuery()
->execute();
If I remove the findFirst or queryBuilder the response is ~30ms but with the findFirst it will takes ~20 minutes... How can I do to increase the performance of the search in my table ?
By changing your code to better performing one:
$dir = new FilesystemIterator("files/path/to/my/files/");
$fileNames = [];
foreach ($dir as $file) {
if ($file->getExtension() == 'json') {
$filename = $file->getFilename();
$explode_filename = explode("_", $filename);
$date = $explode_filename[0];
$unformatted_date = DateTime::createFromFormat("Ymd-His", $date);
$date_server = $unformatted_date->format("Y-m-d H:i:s");
$timestamp_app = $explode_filename[2];
$date_app = date("Y-m-d H:i:s", $timestamp_app/1000);
echo $date_server;
$json_data = json_decode(file_get_contents($file), true);
// save the above data to some arrays
$fileNames[] = $fileName;
}
}
$scans = Scans::find([
'columns' => 'check only columns you need, otherwise you will have full models with hydration',
'conditions' => 'name IN ({fileNames:array})',
'group' => 'name',
'bind' => [
'fileNames' => $fileNames
]
]);
foreach($fileNames as $fileName) {
$filteredScans = $scans->filter(function($scan) use ($fileName) {
return $scan->name == $fileName;
}
if(!$filteredScans) {
// do here whatever
}
}
This solution can be memory heavy though, then you could include here some paginations like do some limit like proper for and do 100-10000 rows at once depending how much RAM you have.
create index on Scans.name
use group by Scans.name (if not uniq)
set some columns then be use

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;

Categories