I'm trying to build an application where there's a device with an expire date:
the expire date must be created with values from 2 other tables: history (last date) & model (interval)
I've create following scope in my Device model:
public function scopeExpiryDate($query, $operator) {
if ($this->histories->last() != null) {
$cal_date = $this->histories->sortBy('date')->last()->date;
$interval = $this->product->interval;
return $query->where($cal_date->addDays($interval), $operator, Carbon::now());
}
return $query;
}
Then I could use the next line:
$devices->ExpiryDate('<=')->get();
Update
like #ceejayoz told in the comments I checked the scopes section on the Laravel-site.
I edited this question.
So how do I get this scope working?
Assuming that $cal_date is a Carbon\Carbon instance, you can use this query:
$query->whereDate($cal_date->addDays($interval), $operator, Carbon::now());
For more information, there's a great tutorial on date filtering here
Ok i've found the solution. It was not found in the scopes, but in adding a attribute.
I did the following in my Device model:
public function getExpirydateAttribute() {
if ($this->histories->last() != null) {
$cal_date = $this->histories->sortBy('date')->last()->date;
$interval = $this->product->interval;
return $cal_date->addDays($interval);
}
return Carbon::now();
}
and in my view I can call something like this:
$devices->filter(function($item){ return $item->Expirydate > now()->modify('last day of this month'); })->count()
Thanks to the people who answered to my question.
Related
I have two tables. One is Device and the other is POS in a many to many relationship. What I need is to get all the devices from the POS id I'm seeking but get the previous device, not the latest one. I wanna use it as a function on my model to have easy access to that element on Device.
Device
--------
- id
- other elements
- pos_id
- function to get the previous device for the above pos_id
POS
--------
- id
- other stuff
Devices_pos
----------
- device_id
- pos_id
I know I can access $pos->devices and get all the elements.
I've tried:
public function scopePrev_dev_pos()
{
if ($this->pos_id > 0){
$pos = Pos::find($this->pos_id);
return $pos->devices->where('device_id', '<', $this->id)->max('device_id');
} else {
return null;
}
}
All it gives me is an Eloquent Builder that apparently doesn't have anything inside.
The query is supposed to be something like this:
SELECT MAX(device_id) FROM devices_pos
WHERE pos_id = 7
AND device_id < 7035;
... but using Eloquent. ids are only an example.
EDIT: Ended up using an accessor:
public function getPreviousDeviceAttribute()
{
if ($this->pos_id > 0){
$pos = Pos::find($this->pos_id);
$prev = DB::table('devices_pos')->where('device_id', '<', $this->id)
->where('pos_id', $this->pos_id)
->max('device_id');
$device = Device::find($prev);
return $device;
} else {
return null;
}
}
I leave the question open because I'm using the facade and not Eloquent but it's a good workaround. A local scope was not useful for my issue (if you need to test for null it won't work).
Try this it must be work
$pos->devices()->newPivot()->where([
['device_id', '<', $this->id],
['pos_id','=', $this->pos_id]
])->max('device_id');
Or you can use
DevicePos::where([
['device_id', '<', $this->id],
['pos_id','=', $this->pos_id]
])->max('device_id');
see related https://laravel.com/docs/5.5/queries#aggregates
Example with DB facade
DB::table('devices_pos')->where([
['device_id', '<', $this->id],
['pos_id','=', $this->pos_id]
])->max('device_id');
I'm stuck on this from a while.Can't figured it out.I reed documantion, tried with several videos and tried like 10 different ways, nothing is working yet.So I have one view/model for one thing, in this example Destination and I have separate files for Offers.The controllers for both are in one file.I want tho the information that is in destination to go to Offers as well.Please help I can't figure out what I'm missing:
So here is the most important parts:
destination_model.php
<?php class Destination_model extends CI_Model
{
public function getDestinationDetails($slug) {
$this->db->select('
id,
title,
information
');
$this->db->where('slug', $slug);
$query = $this->db->get('destinations')->row();
if(count($query) > 0)
{
return $query;
}
else
{
// redirect(base_url());
}
}
public function getOffersByDestination($destination_id)
{
$this->db->select('
o.short_title,
o.price,
o.currency,
o.information,
o.long_title_slug,
oi.image,
c.slug as parent_category
');
$this->db->from('offers o');
$this->db->join('offers_images oi', 'oi.offer_id = o.id', 'left');
$this->db->join('categories c', 'c.id = o.category');
$this->db->group_by('o.id');
$this->db->where('o.destination', $destination_id);
$this->db->where('o.active', '1');
return $this->db->get();
} }
And then in the controller for offers I put this:
$this->load->model('frontend/destination_model');
$this->params['destination'] = $this->destination_model->getOffersByDestination($data->id);
All I need is the title and the information about the destination.
Here is the whole controller for the offers:
$data = $this->slugs_model->getOfferDetails(strtok($this->uri->segment(2), "."));
$this->load->model('frontend/offers_model');
$this->load->model('frontend/destination_model');
$this->params['main'] = 'frontend/pages/offer_details';
$this->params['title'] = $data->long_title;
$this->params['breadcumb'] = $this->slugs_model->getSlugName($this->uri->segment(1));
$this->params['data'] = $data;
$this->params['images'] = $this->slugs_model->getOfferImages($data->id);
$this->params['similar'] = $this->slugs_model->getSimilarOffers($data->category, $data->id);
$this->params['destination'] = $this->destination_model->getOffersByDestination($data->id);
$this->params['offers'] = $this->offers_model->getImportantOffers($data->offers, $data->category, $data->id);
You need to generate query results after you get it from model,
e.g: row_array(), this function returns a single result row.
here's the doc: Generating Query Results
try this:
$this->load->model('frontend/destination_model');
$data['destination'] = $this->destination_model->getOffersByDestination($data->id)->row_array();
$this->load->view('view_name', $data);
And in your view echo $destination['attribut_name'];,
or you can print the array, to see if it's work print_r($destination);
i need help, i'm new in laravel, i want to make query to get year only from table like this
public function index() {
$items = Items::distinct()->orderBy('date','desc')->select(DB::raw('YEAR(`date`) as date'))->get();
$itemDet = Items::where('date', $items->date);
}
then i want to show other value from table based on year above with this function
public function itemDetail($year) {
$itemDet = Items::where('YEAR(`date`)', $year);
return $itemDet;
}
But i don't know how to call it in view, i only know how to call the first function in a view, and I don't know how to pass value year from first function as parameters to second function.
2018
- item2018
- item2018
- item2018
2017
- item2017
2016
-item2016
-item2016
sorry for my bad grammar, thank you!
public function itemDetail($year) {
$itemDet = Items::where('YEAR(`date`)', $year);
//return $itemDet; change it to
return view('yourViewPath',compact('itemDet'));
}
in view you can access like this way
{{ $itemDet }}
You can get that output right away in your index function without passing it to second function, one way to do it.
public function index() {
$arr_container = []; //create array container
$items = Items::distinct()->orderBy('date','desc')->select(DB::raw('YEAR(`date`) as date'))->get();
foreach($items as $val){
$itemDet = Items::select(DB::raw('item'))->where('YEAR(`date`)', $val->year)->get();
if($itemDet->count()>0){
$arr_container[$val->year][] = $itemDet[0]->item;
}
}
return view('view')->with('years',$arr_container);
}
You should get this output when you call {{$years}}.
2018
- item2018
- item2018
- item2018
2017
- item2017
2016
-item2016
-item2016
I am using the Google API PHP client with Google Calendar.
I am having now problems creating the event, but when I try to update the datetime start/end the call just fails and the event is not updated.
I have successfully updated just the summary, but have been unable to update the start/end times.
private function _update_google_event($eventId = '', $updateData = array())
{
if(strlen($eventId) == 0 || empty($updateData)) return false;
$calendar = $this->_get_gcal();
//First get the event
$event = $calendar->events->get($this->calendar_id, $eventId);
var_dump($event->getId());
if(isset($updateData['summary'])) {
$event->setSummary($updateData['summary']);
}
if(isset($updateData['location'])) {
$event->setLocation($updateData['location']);
}
var_dump($event->getEnd());
/*
if(isset($updateData['start'])) {
$start = new Google_Service_Calendar_EventDateTime();
$start->setDateTime($updateData['start']);
$event->setStart($start);
}
*/
if(isset($updateData['end'])) {
var_dump(new Google_EventDateTime());
$end = new Google_Service_Calendar_EventDateTime();
var_dump($end->setDateTime($updateData['end']));
$end->setDateTime($updateData['end']);
var_dump($event->setEnd($end));
}
//Update Sequence
$event->setSequence($event->getSequence() + 1);
echo "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
//var_dump($event);
//Send the update request
//$updatedEvent = new Google_Service_Calendar_Event($calendar->events->update($this->calendar_id, $event->getId(), $event));
$updatedEvent = $calendar->events->update($this->calendar_id, $event->getId(), $event);
echo $updatedEvent->getUpdated();
return false;
}
I have seen some stack overflow questions on updating events that mentioned needing to update the sequence number, so I have done so, but it does not change anything for start/end time.
Any tips/pointers would be much appreciated.
If any other details can help, please just ask.
Thank you!
I realized my problem was not in the function, but in the data that I'm passing itself.
$updateData['start'] and $updateData['end'] was being passed as a DateTime object. I resolved it by using DateTime::format and then passing it into the function.
When I'm using
$collection->getSelect()->group('entity_id')
or
$collection->groupByAttribute('entity_id')
It breaks getSelectCountSql and I'm getting 1 record and 1 page.
Magento does
$countSelect->columns('COUNT(DISTINCT e.entity_id)');
Is there a way to fix it?
I run into it,While overriding _prepareCollection of Mage_Adminhtml_Block_Catalog_Product_Grid
Thanks
I updated the lib/Varien/Data/Collection/Db.php file to allow this as I had to have it work. You'll have to keep track of this for upgrades but it works.
public function getSelectCountSql()
{
$this->_renderFilters();
$countSelect = clone $this->getSelect();
$countSelect->reset(Zend_Db_Select::ORDER);
$countSelect->reset(Zend_Db_Select::LIMIT_COUNT);
$countSelect->reset(Zend_Db_Select::LIMIT_OFFSET);
$countSelect->reset(Zend_Db_Select::COLUMNS);
// Count doesn't work with group by columns keep the group by
if(count($this->getSelect()->getPart(Zend_Db_Select::GROUP)) > 0) {
$countSelect->reset(Zend_Db_Select::GROUP);
$countSelect->distinct(true);
$group = $this->getSelect()->getPart(Zend_Db_Select::GROUP);
$countSelect->columns("COUNT(DISTINCT ".implode(", ", $group).")");
} else {
$countSelect->columns('COUNT(*)');
}
return $countSelect;
}
in some cases, the method from Eric doesn't work.
It's better to rewrite the getSize() method to
public function getSize()
{
if (is_null($this->_totalRecords)) {
$sql = $this->getSelectCountSql();
$result = $this->getConnection()->fetchAll($sql, $this->_bindParams);;
foreach ($result as $row) {
$this->_totalRecords += reset($row);
}
}
return intval($this->_totalRecords);
}
I have solved this using the function below:
public function getSize()
{
return sizeof( $this->getAllIds());
}
This helped me in issue of getSize() returning 1 count of product collection in Magento CE 1.5.
I have overwritten the Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection file and place above function.
Very nice article
Here are few changes I made in order to make it work for me
Changes suggested in Db.php are not required for resolving group by in catalog collection.
I made the similar change in
Catalog->model->Ressource->EAV->Mysql4->product->collection.php
Here is the code I added to getSelectCountSql()
if(count($this->getSelect()->getPart(Zend_Db_Select::GROUP)) > 0) { $countSelect->reset(Zend_Db_Select::GROUP); }
After this things get resolved but a new issue comes in .. In Layered navigation quantities for all the filters is 1.
I made it without touching Core files by overriding the getSize() method of my collection.
public function getSize()
{
if (count($this->getSelect()->getPart(Zend_Db_Select::GROUP)) > 0) {
// Create a new collection from ids because we need a fresh select
$ids = $this->getAllIds();
$new_coll = Mage::getModel('module_key/model')->getCollection()
->addFieldToFilter('id', array('in' => $ids));
// return the collection size
return $new_coll->getSize();
}
return parent::getSize();
}
Tell me if that works for you..
Bouni