Request too heavy - php

I try to retrieve for each region the number of cities with current events.
So I started doing this:
$regionCities = [];
foreach ($regions as $region) {
$regionCities[$region->getId()] = $cityRepository->getCitiesByRegion($region);
}
dump($regionCities);
$regionCitiesNumber = [];
foreach ($regionCities as $index => $region) {
foreach ($region as $city) {
$regionCitiesNumber[$index] = count($city->getCurrentEvents());
}
}
My dump returns me this:
dump
The problem is, it crashes my script, and I suddenly get a blank page when I dump regionCitiesNumber.
getCurrentEvents is a method of my City entity that will retrieve all current events.
public static function createCurrentEventsCriteria(): Criteria
{
return Criteria::create()
->where(Criteria::expr()->gte('endDate', new DateTime('00:00:00')))
->orderBy(['id' => 'DESC'])
;
}
public function getCurrentEvents(): Collection
{
$criteria = EventRepository::createCurrentEventsCriteria();
return $this->events->matching($criteria);
}

Use error logs or try using "Try Catch" wrapper
$regionCities = [];
foreach ($regions as $region) {
$regionCities[$region->getId()] = $cityRepository->getCitiesByRegion($region);
}
//dump($regionCities);
try {
$regionCitiesNumber = [];
foreach ($regionCities as $index => $region) {
foreach ($region as $city) {
$regionCitiesNumber[$index] = count($city->getCurrentEvents());
}
}
} catch (\Throwable $t) {
dd($t);
}

So I tried:
return $this->events->matching($criteria)->count();
And I dumped on regionCitiesNumber, it gave me a totally wrong result:
For example for the ARA region, I end up with 0 as a result while there are 1895 events distributed over all the departments ...
As a result, most regions result in 0, sometimes 1, sometimes 2 ...
In addition, it takes a long time to load my page, isn't there a softer solution?

Related

Why is my code running from bottom to top

I am trying to do a transaction in the db with Eloquent ORM following the instructions here: https://stackoverflow.com/a/15105781/5649969
I notice that the code throws a Throwable, so I put it in a try...catch block to go for an early return if there is an exception.
try {
DB::transaction(function () use ($user, $attributes) {
$validUserAttributes = $user->getFillable();
$updatable = [];
foreach ($attributes as $key => $value) {
if (in_array($key, $validUserAttributes)) {
$updatable[$key] = $value;
}
}
$user->update($updatable);
$validRoleAttributes = $user->role->getFillable();
$updatable = [];
foreach ($attributes as $key => $value) {
if (in_array($key, $validRoleAttributes)) {
$updatable[$key] = $value;
}
}
$user->role()->update($updatable);
});
} catch (Throwable $_) {
dd(1000);
return new UpdateUserResult(false, UpdateUserResult::UPDATE_FAILED);
}
dd(2000);
return new UpdateUserResult(true, UpdateUserResult::UPDATE_SUCCESS);
This is where my problem is, it seems that the early return does not work for whatever reason, when I remove the dd(2000), dd(1000) will run, why does the code seem like it is running from the bottom to the top?

how to add array or row to array while foreach looping laravel 5.8

I need to get all products for category and sub categories when click on parent category
so i make loop or recursive loop to get all id for category and subcategory to search for its products
public function tree($category, $cats = array())
{
$items = category_model::select('id')->where('parent_id', $category)->get();
foreach ($items as $key=>$value)
{
//$cats = $value;
$cats = Arr::add($cats, 'id', $value);
self::tree($value, $cats);
}
return $cats;
}
public function allproduct(Request $request)
{
return self::tree($request->id);
}
I have tried this code but looping with our result
I need to add this all id to make search for products through this array
You can improve your own code and make it work by taking all the category ids at once, instead of making a for each loop there.
Also, you are missing a terminating condition which is a must when using recursive functions.
Also, you don't need to process the same ids again and again if they have already been processed.
Taking all those points in mind, do something like this:
public function tree($cats, $alreadyProcessedCats = [])
{
if (empty($cats)) {
return [];
}
$newCatIds = [];
foreach ($cats as $catId) {
//do not process it if it was alreadt processed
if (in_array($catId, $alreadyProcessedCats)) {
continue;
}
//fetch all the categories id where parent id is one of the id which is present in the $cats
$items = category_model::where('parent_id', $category)->pluck('id');
if (empty($items)) {
continue;
}
$items = $items->toArray();
$newCatIds = array_merge($newCatIds, $items);
}
//terminal condition
if (empty($newCatIds)) {
return $cats;
}
$newCats = array_merge($cats, $newCatIds);
return self::tree($newCats, $cats);
}
public function allproduct(Request $request)
{
$allCategoriesIds = [$request->id];
$allCategoriesIds = self::tree($allCategoriesIds);
}
Fix your foreach loop.
foreach ($items as $key=$value)
should be
foreach ($items as $key => $value)
I can't comment on that static Arr function (a Laravel thing I guess? due to the misuse of statics everywhere?)

How to fix laravel collection chunk loop once?

I have a problem with laravel collection with chunk result. It run only one time in loop.
I have 204 elements in array and I want to split it as 100 each by using laravel collection helper. It must run in three times but I got only once.
private function __migrateDistricts()
{
DB::beginTransaction();
try {
$file = 'resources/csv/districts.csv';
$csv = array_map('str_getcsv', file($file));
$table = 'districts';
$collection = collect($csv);
$arr_districts = array();
foreach ($collection->chunk(100) as $districts) {
foreach ($districts as $dist) {
array_push($arr_districts, $this->__transformDistricts($dist));
}
DB::table($table)->insert($arr_districts);
DB::commit();
}
} catch (\Exception $e) {
DB::rollBack();
}
}
private function __transformDistricts($district)
{
$code = substr($district[3],0,2);
$pro = DB::table('provinces')->where('code', $code)->first();
return [
'province_id' => $pro->id,
'name_kh' => $district[1],
'name_en' => $district[2],
'code' => $district[3],
];
}
After I run the I got only 100 records in table. It should be 204 records in table. What is wrong with my code? Thanks
In your code...
$arr_districts = array();
foreach ($collection->chunk(100) as $districts) {
foreach ($districts as $dist) {
array_push($arr_districts, $this->__transformDistricts($dist));
}
DB::table($table)->insert($arr_districts);
DB::commit();
}
in each inner loop, you add the data to $arr_districts, which on the second time of your outer loop, will still contain the data from the first loop.
You should reset this array for each main loop to clear the data out...
foreach ($collection->chunk(100) as $districts) {
$arr_districts = array(); // Move to here
foreach ($districts as $dist) {
array_push($arr_districts, $this->__transformDistricts($dist));
}
DB::table($table)->insert($arr_districts);
DB::commit();
}

How to correctly use the chunk method in laravel to update thousands of rows?

I have written a method to update a json string in my database with translations. Some categories have ~300.000 products that need to be updated.
This is my method:
public function generateDutchAttributes(Category $category)
{
$category->products()->chunk(100, function ($products) {
foreach ($products as $product) {
$attributesArray = [];
foreach ($product->attributes as $attribute) {
$attributesArray[Translation::translateNL($attribute['attribute'])] = Translation::translateNL($attribute['value']);
}
//dd($attributesArray);
$product->update(['dutch_attributes' => $attributesArray]);
}
});
return redirect()->route('backend.import');
}
}
After ~10.000 rows, I get a HTTP 500 error because too much memory was used.

Add object to php array in symfony

I currently have 2 classes:
workerListClass
workerClass
The workerListClass gets a list of work with ids from database. For each of these the workerClass is called
foreach ($query as $value) {
$result = $this->worker->getWorkerById($value['ID']); // DB Call to get additional data
$this->addData($result);
vardumper::dump($result->getId());
// This results in 1031 and 1528
}
addDate is very simple
public function addData(workerClass $worker): void
{
$this->data[] = $worker;
}
But if i try to go through this array something strange happens
$result = $this->workerListClass->getWorker()->getData();
foreach ($result as $worker) {
vardumper::dump([
$worker->getId() // this outputs 1528 twice!!!
]);
}
getData does nothing special
public function getData(): array
{
return $this->data;
}
Can someone help me why this outputs 1528 twice?
Problem found. The issues was that the same class was changed and not a new class was setup.
Using clone on the workerlist helped fixing this:
foreach ($query as $value) {
$localWorker = clone $this->worker; //starts a new instance so that it is not referenced
$result = $localWorker->getWorkerById($value['ID']);
$this->addData($result);
vardumper::dump($result->getId());
}

Categories