Laravel Collections: Finding the intersection - laravel

Here is how I currently find the intersection of multiple Laravel collections:
$stuff = [
collect(['a','b','c','d']),
collect(['b','c','d','e']),
collect(['c','d','e','f']),
];
$i = 0;
foreach ($stuff as $current) {
$i++;
if ($i === 1) {
$common = $current;
} else {
$common = $common->intersect($current);
}
}
dd($common);
Is there a more efficient method? It seems a bit clumsy to have to treat the first collection differently (via the if...else...).
Laravel has so many good collection methods I suspect there is a more elegant approach to this problem.

Reduce may be a option for this:
$intersection = collect([
collect(['a','b','c','d']),
collect(['b','c','d','e']),
collect(['c','d','e','f']),
])->reduce(function ($carry, $item) {
return $carry->empty() ? $item : $carry->intersect($item);
});

Related

Laravel group by date and count

I'm trying to add extra information to a Laravel eloquent collection based on the counting number of start(date) field. so the scenario is I have an "appointments" table, I want to add extra attributes to the object in the collection that's returned by eloquent if any days have more than 10 appointments. I have tried many ways like group by and count but didn't work. anyway I have the code below that's I think I'm so close to it but I have been working on it but couldn't find how to make it achieve what I want. I think I'm stuck and I can't think any more. I have commented most of the lines.
$allAppointments = Appointment::get($columns); //returning all the appointments
$days = Appointment::get()->groupBy(function ($val) {
return Carbon::parse($val->start)->format('d');
}); //here I'm returning appointments by group without the count
$counter = [];
foreach ($days as $day => $appointments) {
foreach ($appointments as $appointment) {
if (Carbon::parse($appointment->start)->format('d') == $day) {
$counter = [Carbon::parse($appointment->start)->format('d') => $day]; //here I'm trying to make an array and count the days but not working
}
dd($counter);
foreach ($allAppointments as $allAppointment) {
if (Carbon::parse($allAppointment->start)->format('d') == $day && count($counter) == 10) //here I want to compare the dates and check if that day have more than 10 appointments
$allAppointment->setAttribute('backgroundColor', 'red'); //here I want to add the extra information
}
}
}
Try the following:
Appointment::select(DB::raw('if(count(*) > 10, true, false) as more_than_ten_appointment'))->groupBy(function ($val) {
return Carbon::parse($val->start)->format('d');
})->get();
if DB class isn't exist add after namespace:
use DB;
It's strange after working on it more than almost 10 hours, just 20 minutes after posting it here I could make it work. the code is below:
public function all()
{
$columns = [
'id',
'title',
'start',
'end',
'note',
'allDay',
'editable',
];
$allAppointments = Appointment::get($columns);
$days = Appointment::get()
->groupBy(function ($val) {
return Carbon::parse($val->start)->format('d');
});
foreach ($days as $day => $appointments) {
foreach ($appointments as $appointment) {
foreach ($allAppointments as $key => $allAppointment) {
if (Carbon::parse($allAppointment->start)->format('d') == $day && $appointments->count() >= 10){
$allAppointment->setAttribute('backgroundColor', 'red');
}
}
}
}
return $allAppointments;
}
Do this
$allAppointments = Appointment::get($columns); //returning all the appointments
$days = Appointment::get()->groupBy(function ($val) {
return Carbon::parse($val->start)->format('d');
}); //returning appointments by group without the count
foreach ($days as $day => $appointments) {
foreach ($appointments as $appointment) {
$counter = 0;
if (Carbon::parse($appointment->start)->format('d') == $day) {
$counter = count($appointments); //appointments counter
}
foreach ($allAppointments as $allAppointment) {
if (Carbon::parse($allAppointment->start)->format('d') == $day && $counter >= 10) //compare the date and check if that day have more than 10 appointments
$allAppointment->setAttribute('backgroundColor', 'red'); //add the extra information here
}
}
}

Get object value from array in cache laravel

I have an array in Redis cache like that
127.0.0.1:6379> MGET laravel:campaign1107
1) "a:1:{s:21:\"unsubscriberCount1107\";i:2;}"
127.0.0.1:6379>
Now I need to get unsubscriber1107 value. I tried to this way
dd(cache()->get($arrayCacheKey[$cacheKey]));
but, it's doesn't work. How can I access this object?
My code for set cache
public function updateUnsubscriberCountCache($campaign_id, $type)
{
$assoc = [];
$arrayCacheKey = 'campaign'.$campaign_id.'';
$cacheKey = 'unsubscriberCount'.$campaign_id.'';
if($type == 'unsubscriberLogCount') {
$cacheKey = 'unsubscriberCount'.$campaign_id.'';
if( cache()->get($cacheKey) > 0) {
cache()->increment($cacheKey);
//cache()->forget($cacheKey);
} else {
$total = UnsubscribeLog::select('unsubscribe_logs.*')->leftJoin('tracking_logs', 'tracking_logs.message_id', '=', 'unsubscribe_logs.message_id')->where('tracking_logs.campaign_id', '=', $campaign_id)->distinct('subscriber_id')->count('subscriber_id');
//cache()->forever($cacheKey, $total);
$assoc[$cacheKey] = $total;
cache()->forever($arrayCacheKey, $assoc);
}
}
}
You're storing the value as an array using $arrayCacheKey but earlier in the code you're trying to access it using the $cacheKey which has a different value.
If you want to get the value of unsubscriber1107 you will need to use a combination of both keys:
$campaignData = cache()->get($arrayCacheKey); //To get the array value from the cache
$count = $campaignData ? $campaignData[$cacheKey] : null; //get the count
The above assumes that the va

Self calling array return php

i am writing a module that sorts through categories and returns me the lowest possible subcategory.
private function getChild($array){
foreach($array as $item){
if(is_array($item)){
$this->getChild($item);
} else {
array_push($this->catsToReturn, $item);
}
}
}
So my actual issue and question is why can't i return value in else enclosure? I would like to return $item and push that value to array, that would give me a better code readability, since now i have
$this->getChild($this->postCategories);
Hanging randomly in my code.
The strange and new thing for me is that i can echo the value but i can't return it, i know it's an issue with scope, but can't find any info on how to solve it.
Just wanted to know how to improve this.
Cheers
You could change your code by adding $item in an array and doing an array_merge to take results from subsequent calls.
<?php
private function getChild($array){
$result = [];
foreach($array as $item){
if(is_array($item)){
$result = array_merge($result,$this->getChild($item));
} else {
$result[] = $item;
}
}
return $result;
}
From wherever you are calling in your class, you can just do
$this->catsToReturn = $this->getChild($array)

Laravel get cache key using regex or like operator

I want to get Laravel Redis cache key using regex or like key operator.
I have tried everything and spend lost of time but no luck with that can anyone please help on this.
$redis = Cache::getRedis();
$keys = $redis->keys("*$key_name*");
$count = 0;
$result = [];
foreach ($keys as $key) {
$result[$key] = $redis->get($key);
}
return $result;
I have tried above code but no luck. can any one help on this?
You can implement something like
$redis = Cache::getRedis();
$keys = $redis->keys("*$key_name*");
$count = 0;
$result = [];
foreach ($keys as $key) {
$result[$key] = $redis->get($key);
}
return $result;

is OrderByRaw() safe?

Is the below code safe from SQL injection?
if ($request->has('sort')) {
$s = $request->sort;
if ($request->has('asc')) {
$a = $request->asc;
} else {
$a = 'asc';
}
$query->orderByRaw("ISNULL({$s}), {$s} " . $a);
}
No. As the name suggests, it inserts a raw expression. That is, unsanitized.
If you’re wanting to sort a query, just sort when the require query string parameter(s) are provided:
if ($sort = $request->query('sort')) {
$direction = $request->query('direction');
if (! in_array($direction, ['asc', 'desc'])) {
$direction = 'asc'; // default direction
}
$query->orderBy($sort, $direction);
}
The problem with RAW queries are much more in the bindings (user data) than in the sql query itself, that's why you should avoid them. But it is safer if you add the bindings separately:
public function orderByRaw($sql, $bindings = []) {...}
There is a better approach to achieve this kind of conditional query using when for example:
// You have the $query instance already...
$sort = $request->get('sort');
$query->when($sort, function($query) use($request) {
$order = $request->asc ?: 'asc';
return $query->orderBy($sort, $order);
});
Now, the orderBy will be applied only when the $sort is available and you can add more query constrains further and execute it like:
// $query->where(...);
$result = $query->get();

Resources