laravel get items from two separate table and merge the result with pagination - laravel

I have two tables, one of them is "posts" and the other one is "notifications". I want to show the users a list of posts and notifications with pagination. how can I do that efficiently?
I have this code that works fine but it is not efficient because I get all the data and then slice them. I want to do the pagination, using MYSQL
public function list_post_notification(Request $request , $page_number = 1 , $per_page=10 , $brand_id = null ){
$brand =$this->brandRepository->getMagazinBrand() ;
$posts = $brand->posts()->orderBy('posts.created_at' , 'desc')->take($page_number * $per_page) ;
$notifs = $brand->notifications()->orderBy('notifications.created_at' , 'desc')->take($page_number * $per_page) ;
$result = [] ;
foreach ($posts->get() as $k=>$v){
$item = [
'type'=>'post' ,
'uuid'=>$v->uuid,
'title'=>$v->title,
'created_at'=>strtotime($v->created_at),
'creator'=>$v->brand->fa_name,
'brand_id'=>$v->brand->id,
];
$result[$item['created_at']] =$item ;
}
foreach ($notifs->get() as $k=>$v){
$item = [
'type'=>'notification' ,
'uuid'=>$v->uuid,
'title'=>$v->title,
'created_at'=>strtotime($v->created_at),
'creator'=>$v->brand->fa_name,
'brand_id'=>$v->brand->id,
];
$result[$item['created_at']] =$item ;
}
krsort($result) ;
$start = 0 ;
if ($page_number > 1)
$start = ($page_number -1 ) * $per_page ;
return response()
->json(array_slice($result , $start , $per_page)) ;
}

You can merge all your items and create one Collection.
$resultCollection = collect($result).
Than use forPage method.

Related

Loop through collection in laravel and get specific data from the collection

I'm trying to go through a collection and I need to get a list of products according to certain keys. but I get the following error when I print the list with dd:
"array_key_exists(): The first argument should be either a string or an integer"
this is my function
public function reemplazaCostoZona($zona, $destino, $especie, $costo, $transporCollect){
$productos = $transporCollect->where([['zona',$zona],['destino', $destino],['especie',$especie]])
->pluck('producto');
dd($productos );
}
Collection:
I need to obtain the list of products for destination zone and species, That is to say that for my example of collection, for zone 1 destination 5 specie 1 I would have in my list product 1 and there may be more.
function where Im obtain collection:
public function storeTranspor3($request){
DB::table('transpor')->truncate();
$var = DB::select("select flu.zona, flu.destino, flu.producto, pro.especie, sup.codigo, dtr.cod_fundo, sup.sup_ha, dtr.dist_pavimento, dtr.dist_no_pavimento, dtr.peaje
from flujos flu
left join super sup on (sup.zona = flu.zona)
left join d_transporte dtr on (dtr.cod_fundo = (sup.codigo / 1000000) and dtr.destino = flu.destino)
left join productos pro on (pro.producto = flu.producto)
left join especies esp on (esp.especie = pro.especie)
order by flu.zona, dtr.cod_fundo, flu.producto, flu.destino, sup.codigo");
$tansporCollect = collect();
$tansporCollectsinCosto = collect();
foreach ($var as $f) {
if($f->codigo != null){
if($f->especie == 1){
$a = 0.177548*$f->dist_no_pavimento;
$b = 0.0746*$f->dist_pavimento;
$c = 0.0333*$f->peaje;
$costoFundo = ($a + $b + 1.1191 + 0.399 + $c)*$f->sup_ha;
}
else{
$a = 0.1652*$f->dist_no_pavimento;
$b = 0.0694*$f->dist_pavimento;
$c = 0.0357*$f->peaje;
$costoFundo = ($a + $b + 1.0421 + 0.599 + $c)*$f->sup_ha;
}
$tansporC =[
'zona' => $f->zona,
'destino' => $f->destino,
'producto' => $f->producto,
'especie' => $f->especie,
'costo' => $costoFundo
];
$tansporCollect->push($tansporC);
$tansporsinCosto = [
'zona' => $f->zona,
'destino' => $f->destino,
'producto' => $f->producto,
'especie' => $f->especie,
];
$tansporCollectsinCosto->push($tansporsinCosto);
}
}
$zonas = $tansporCollect->pluck('zona')->unique();
$destinos = $tansporCollect->pluck('destino')->unique();
$especies = $tansporCollect->pluck('especie')->unique();
$transporCollectUnique = $tansporCollectsinCosto->unique();
foreach($zonas as $zon){
$costoZona = $tansporCollect->where('zona',$zon);
foreach($destinos as $destin){
$costoDestino = $costoZona->where('destino',$destin);
foreach($especies as $espec){
$costoEspecie = $costoDestino->where('especie',$espec)->avg('costo');
/*HERE IM CALL OTHER FUNCTION */
$this->reemplazaCostoZona($zon, $destin, $espec, $costoEspecie, $transporCollectUnique);
}
}
}
}
I'm with laravel 5.8
You are not using the where function of collections correctly. For collections you need the following:
$productos = $transporCollect->where('zona', $zona)
->where('destino', $destino)
->where('especie',$especie)
->pluck('producto');
Hope that helps!

Lumen: Auto increment and Reset Transaction_ID Automatically every month

I trying to generate random transaction_id, with format "2000-yymmm-0000".
I already know how to set the transaction_id, but I have a problem with the auto-increment from "2000-yymm-0000" to "2000-yymm-0001", and reseting automatically to "2000-yymm-0000" at every new month.
I put this logic in different path of controller.
PS: I'm using Lumen 6.0 with Laravel 6.0.
I'm trying to create the increment with:
$number = sprintf('%04d', 0000);
$number++;
but it didn't work.
$year = 2000;
$time = date('ym');
$number = sprintf('%04d', 0000);
$transaction_id = $year . '-' . $time . '-' . $number;
$transaction_data = explode('-', $transaction_id);
$month = date("m", strtotime($transaction_data[0]));
I expect the result to automatically increment every time a new data is stored to the database. But the actual result is transaction_id being having always the same value 2000-yymm-0000.
What am I doing wrong?
I know it's weird to answer my own question, but i already find the solution.
in Models/Order.php
i create a function like this.
public function count()
{
$this->where(transaction_id)->count();
}
after that i call the function from Model/Order.php to OrdersController.php
public function create(Request $request)
{
$year = 2000;
$date = date('ym');
$total_data = $this->table->count();
$number = str_pad($total_data + 1, 4, 0, STR_PAD_LEFT);
$transaction_id = $year . '-' . $date . '-' . $number;
return $this->success('count all transaction id', $t_id);
}

Doctrin's Query Builder. Query with AND in where clause

I have a query in Query Builder in Doctrine. My query is:
$result = $this->entityManager->createQueryBuilder()
->select('cc', 'cct', 'cces')->from('App\Http\Entities\Cic\CaseCategory', 'cc')
->innerJoin('cc.type', 'cct')
->leftJoin('cc.eventSubject', 'cces')
->orderBy('cc.title')
->where('cc.active = 1')
->getQuery();
How Could I get query with AND clause? I mean to replace cc.active = 1 AND system_category=1' instead cc.active = 1 in where clause.
I'm trying in that way:
$result = $this->entityManager->createQueryBuilder()
->select('cc', 'cct', 'cces')->from('App\Http\Entities\Cic\CaseCategory', 'cc')
->innerJoin('cc.type', 'cct')
->leftJoin('cc.eventSubject', 'cces')
->orderBy('cc.title')
->where('cc.active = 1 AND system_category=1')
->getQuery();
But in that way it's dosen't work. How could I do that correctly?
I would be greateful for help.
Best regards
try this:
$result = $this->entityManager->createQueryBuilder()
->select('cc', 'cct', 'cces')->from('App\Http\Entities\Cic\CaseCategory', 'cc')
->innerJoin('cc.type', 'cct')
->leftJoin('cc.eventSubject', 'cces')
->orderBy('cc.title')
->where('cc.active = 1')
->andWhere('system_category=1')
->getQuery();
I suggest to you to use parameters like this:
$result = $this->entityManager->createQueryBuilder()
->select('cc', 'cct', 'cces')->from('App\Http\Entities\Cic\CaseCategory', 'cc')
->innerJoin('cc.type', 'cct')
->leftJoin('cc.eventSubject', 'cces')
->orderBy('cc.title')
->where('cc.active = :active')
->andWhere('system_category=:system_category')
->setParameters(
[
'active' => 1,
'system_category' => 1
]
)
->getQuery();

Magento get manufacturer labels ONLY for a particular store

I'm trying to get manufacturer labels only for a particular store, but it's not working and I always get all manufacturers (of all stores). Any ideas? Thats my code:
$entityTypeIdentifier = 'catalog_product';
$attributeCode = 'manufacturer';
$storeId = 2;
$attributeModel = Mage::getModel('eav/entity_attribute');
$attributeId =
$attributeModel->getIdByCode($entityTypeIdentifier,$attributeCode);
$attribute = $attributeModel->load($attributeId);
$attribute->setStoreId( $storeId );
$attributeOptionsModel = Mage::getModel('eav/entity_attribute_source_table');
$attributeTable = $attributeOptionsModel->setAttribute($attribute);
$options = $attributeOptionsModel->getAllOptions(false);
echo '<pre>';
print_r($options);
$attribute->setStoreId( $storeId ); is ignored and thats the result:
Array
(
[0] => Array
(
[value] => 204
[label] => 3M ESPAÑA
)
.
.
.
Thats eav_attribute_option_value table:
value_id
option_id
store_id
value
1263
204
0
3M ESPAÑA
1264
204
1
3M ESPAÑA
In getAllOptions function of Mage_Eav_Model_Entity_Attribute_Source_Table class, an option's value will be returned whether it has store specific value or not.
For example, if you have 100 options for an attribute and store #2 has values for 20 of them, option model will return 100 options whether you setStoreId(2) or not. If you set store id, model will return 20 of them in store #2 value, other 80 options in default value.
But if you need an answer to get only that 20 values, here you are my friend:
$entityTypeIdentifier = 'catalog_product';
$attributeCode = 'manufacturer';
$storeId = 2;
$resource = Mage::getSingleton('core/resource');
$connection = $resource->getConnection('read');
$query = $connection->select()
->from(array('e' => $resource->getTableName('eav/attribute')), array())
->joinLeft(array(
'f' => $resource->getTableName('eav/entity_type')),
"e.entity_type_id = f.entity_type_id AND f.entity_type_code = '$entityTypeIdentifier'",
array()
)
->joinLeft(array(
'g' => $resource->getTableName('eav/attribute_option')),
'e.attribute_id = g.attribute_id',
array()
)
->joinRight(
array('h' => $resource->getTableName('eav/attribute_option_value')),
"g.option_id = h.option_id AND h.store_id = $storeId",
array('h.option_id', 'h.value')
)
->where('e.attribute_code = ?', $attributeCode);
$options = $connection->fetchAssoc($query);
echo '<pre>';
print_r($options);

Timepicker that removes times as they're selected (ajax)

I'm building a booking form for a moving business that uses a calendar combined with a start and end time. I built the timepicker with Formidable Pro, and it allows me to check "unique" on time fields which automatically removes them on the selected date. However it doesn't automatically remove the times from within the range between start and end times (ie: if someone chooses to rent a truck from 1am-3am I need 1am,2am,and 3am to be removed from future options but right now it only removes 1am and 3am) . I need to write ajax to remove the in-between times from the options. I'm not sure where to begin. This is the current ajax_time_ options function. Any push in the right direction would be appreciated.
function ajax_time_options(){
global $frmpro_settings, $frmdb, $wpdb;
//posted vars = $time_field, $date_field, $step, $start, $end, $date, $clock
extract($_POST);
$time_key = str_replace('field_', '', $time_field);
$date_key = str_replace('field_', '', $date_field);
if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', trim($date)))
$date = FrmProAppHelper::convert_date($date, $frmpro_settings->date_format, 'Y-m-d');
$date_entries = FrmEntryMeta::getEntryIds("fi.field_key='$date_key' and meta_value='$date'");
$opts = array('' => '');
$time = strtotime($start);
$end = strtotime($end);
$step = explode(':', $step);
$step = (isset($step[1])) ? ($step[0] * 3600 + $step[1] * 60) : ($step[0] * 60);
$format = ($clock) ? 'H:i' : 'h:i A';
while($time <= $end){
$opts[date($format, $time)] = date($format, $time);
$time += $step;
}
if($date_entries and !empty($date_entries)){
$used_times = $wpdb->get_col("SELECT meta_value FROM $frmdb->entry_metas it LEFT JOIN $frmdb->fields fi ON (it.field_id = fi.id) WHERE fi.field_key='$time_key' and it.item_id in (". implode(',', $date_entries).")");
if($used_times and !empty($used_times)){
$number_allowed = apply_filters('frm_allowed_time_count', 1, $time_key, $date_key);
$count = array();
foreach($used_times as $used){
if(!isset($opts[$used]))
continue;
if(!isset($count[$used]))
$count[$used] = 0;
$count[$used]++;
if((int)$count[$used] >= $number_allowed)
unset($opts[$used]);
}
unset($count);
}
}
echo json_encode($opts);
die();
}

Resources