how can i increment 6 months selecting from database to_date field? - laravel-5

I'm making my project,and want to increment date from fetching to_date filed with 6 months if last to_date is gone then add more 6 months and so on what can i do for this?
$abc=(Session::get('email'));
$email= $request->input('email');
if (Maintenance::where('email', '=', $email)) {
$users=Carbon::create(2019,0,30)->addMonths(6)->toDatestring();
if (Maintenance::where('maintenance_status', '=', 'PAID')->orderBy('todate','DESC')) {
$check = Maintenance::select('to_date')->where('maintenance_status', '=', 'PAID')->orderBy('to_date','DESC')->get();
// $users= Carbon($check[0])->addmoths(6);
$users = Carbon::addMonths(6)->toDatestring();
i expect the output of 30-06-2019,30-12-2019 and so on but the actual output is only increment one time using Carbon and i want to increment fetching from database date

It looks like you are overwriting your variable instead of adding to it.
$users = Carbon\Carbon::create(2019,0,30)->addMonths(6)->toDatestring();
returns 2019-06-30.
$users = Carbon\Carbon::addMonths(6)->toDatestring(); would overwrite it, but it actually breaks "PHP Error: Call to a member function addMonths() on string".
Don't store the string as your variable. Instead, keep it as a instance of Carbon so that you can call functions on it. Then when you need to use it call toDatestring().
It would look something like this:
$date_to_increment = Carbon\Carbon::create(2019,0,30)->addMonths(6);
echo($date_to_increment->toDatestring()); // 2019-06-30
if ($your_condition) {
$date_to_increment->addMonths(6);
echo($date_to_increment->toDatestring()); // 2019-12-30
}
As far as applying it to your case, there are a few issues. Your first condition is invalid. I believe it will always return true as you never execute the query. I'm also assuming since you are matching an email that there will only be one result. So lets use the query builder method first() to save a step as this will return a single entry instead of an array.
$maintenance = Maintenance::where('email', '=', $email)->first();
if ($maintenance) {
// do stuff
}
Then you have a few more conditions that have similar issues, but more importantly, they are re-querying so you are losing the restrictions in your collection each time.
Instead:
$maintenance = Maintenance::where('email', '=', $email)->first();
if ($maintenance) {
if ($maintenance->maintenance_status === 'PAID') {
// do something
}
}
Finally, to use the value from the database:
if ($maintenance->maintenance_status === 'PAID') {
$date = Carbon\Carbon::parse($maintenance->to_date)->addMonths(6);
$maintenance>to_date = $date->toDatestring();
$maintenance->save();
}

Related

In laravel livewire, I want to get the user only if it's value changed from specific value to another specific value

Here is the code in which I get the user if it's g10_eng_unwh is equal to 1.
public function purchased(User $user)
{
if ($user->g10_eng_unwh == 1) {
$token = "g10_eng_unwh";
}
if ($user->g7_eng_unwh == 1) {
$token = "g7_eng_unwh";
}
$time = Carbon::now()->format('Y-m-d');
dd($user->email, $time, $token);
}
Instead, I want to get the user only when it's g10_eng_unwh value changes from 0 to 1.
Is there any way?
You need to get the past value at the beginning so that you can apply the condition, it will have to be stored somewhere. Most likely you will need to create g10_eng_unwh_old or something like that. I assume that g10_eng_unwh is a column in the database, in this case create g10_eng_unwh_old and store the old value in it.
In this case, you could get it even on request. For example
DB::query()
->where('g10_eng_unwh', 1)
->where('g10_eng_unwh_old', 0)
->get();

Update Laravel model from external API

I have a Coin model with id,name,price.
In a function, I extract all the coins and create a comma separated string with all the ids:
$coins = Coin::all();
$coinsIds = $coins->pluck('id')->toArray();
$coinsIdsString = implode(',', $coinsIds);
After that I make a call to an external API:
$url = 'https://myapi.com?ids' . $coinsIdsString;
$response = Http::get($url)->json();
$response value is an array of coins, something like:
[
{
"id":"1",
"name":"A",
"price":"1.2",
},
...
]
What would be the best way to update and save my Coin model with the price value from API?
Unfortunately, you're not going to be able to do anything other than update a single record at a time. That is, loop through the results of the array and perform a database update on each record. My recommendation is
$results = ... // Result of API call;
foreach ($results as $result) {
DB::table('coins')
->where('id', $result['id'])
->update(['price' => $result['price']]);
}
I would then create a scheduled command to periodically perform the update since it is likely to be resource intensive depending on the volume of calls.
https://laravel.com/docs/8.x/scheduling#scheduling-artisan-commands

How to order messages by dates in Laravel

Im building the chat section of my app with vueJs and laravel backend. I want to fetch my messages grouped by days. So when messages display, I want them to look something like this.
`Today
**All messages sent and received today, ordered by time**
Yesterday
**Yesterday's messages**
9/12/2018
**Messages for that day**
In my Chat model, I wrote an accessor for this like so;
public function getMessagesAttribute(){
return $this
->groupBy(function($q){
return $q->created_at->format('Y-m-d');
});
However, this does not give anything different from what I got when I use orderBy('created_at', 'ASC') in the controller. I will appreciate any assistance/guidance to achieve what I want please.
You could feed the results of your function into a loop that starts with the first date, sets the date as a variable, then compares it to the next date, which, if the next date has a smaller value, it gets preceded with a header field to result in grouping.
$date=null;
$next_date=null;
while($this) {
$date = $this->created_at;
if($next_date != null && $next_date<$date) {
*put your group title here*;
*put date/message here*;
} else {
*put date/message here*;
}
$next_date=$date;
}
Maybe build an array out of it, or something like that.
What about
$today = \Carbon\Carbon::now()->format('Y-m-d');
$yesterday = \Carbon\Carbon::yesterday()->format('Y-m-d');
$any_day = \Carbon\Carbon::createFromFormat('d/m/Y', '9/12/2018')->format('Y-m-d'); //used your example date
$messages_today = Message::where('created_at', 'like', "{$today}%")->orderBy('created_at', 'desc')->get();
$messages_yesterday = Message::where('created_at', 'like', "{$yesterday}%")->orderBy('created_at', 'desc')->get();
$messages_any_day = Message::where('created_at', 'like', "{$any_day}%")->orderBy('created_at', 'desc')->get();
It needs some tweeking according to your needs. But that should do the trick for you.

How to increment a column using Eloquent Model in Laravel 4

I am not sure how to increment the value in a column using Eloquent Model in Laravel 4?
This is what I currently have and I am not sure how correct is this.
$visitor = Visitor::where('token','=','sometoken')->first();
if(isset($visitor)){
$visitor->increment('totalvisits');
}else{
Visitor::create(array(
'token'=>'sometoken',
'totalvisits'=>0
));
}
With Query Builder we could do it using
DB::table('visitors')->increment('totalvisits');
Looks like the code that I posted worked after all
$visitor = Visitor::where('token','=','sometoken')->first();
if(isset($visitor)){
$visitor->increment('totalvisits');
}else{
Visitor::create(array(
'token'=>'sometoken',
'totalvisits'=>0
));
}
Prior to a fix a few weeks ago the increment method actually fell through to the query builder and would be called on the entire table, which was undesirable.
Now calling increment or decrement on a model instance will perform the operation only on that model instance.
Laravel 5 now has atomic increment:
public function increment($column, $amount = 1, array $extra = [])
{
if (! is_numeric($amount)) {
throw new InvalidArgumentException('Non-numeric value passed to increment method.');
}
$wrapped = $this->grammar->wrap($column);
$columns = array_merge([$column => $this->raw("$wrapped + $amount")], $extra);
return $this->update($columns);
}
which essentially works like:
Customer::query()
->where('id', $customer_id)
->update([
'loyalty_points' => DB::raw('loyalty_points + 1')
]);
Below is old answer for Laravel 4 where the built-in increment was a seperate select and then update which of course leads to bugs with multiple users:
If you'd like to accurately count your visitors by ensuring the update is atomic then try putting this in your Visitor model:
public function incrementTotalVisits(){
// increment regardless of the current value in this model.
$this->where('id', $this->id)->update(['totalVisits' => DB::raw('last_insert_id(totalVisits + 1)')]);
//update this model incase we would like to use it.
$this->totalVisits = DB::getPdo()->lastInsertId();
//remove from dirty list to prevent any saves overwriting the newer database value.
$this->syncOriginalAttribute('totalVisits');
//return it because why not
return $this->totalVisits;
}
I'm using it for a change tag system but might work for your needs too.
Does anyone know what to replace the "$this->where('id',$this->id)" with because since dealing with $this Visitor it should be redundant.

codeigniter count_all_results

I'm working with the latest codeIgniter released, and i'm also working with jquery datatables from datatables.net
I've written this function: https://gist.github.com/4478424 which, as is works fine. Except when I filter by using the text box typing something in. The filter itself happens, but my count is completely off.
I tried to add in $res = $this->db->count_all_results() before my get, and it stops the get from working at all. What I need to accomplish, if ($data['sSearch'] != '') then to utilize the entire query without the limit to see how many total rows with the search filter exists.
If you need to see any other code other than whats in my gist, just ask and I will go ahead and post it.
$this->db->count_all_results() replaces $this->db->get() in a database call.
I.E. you can call either count_all_results() or get(), but not both.
You need to do two seperate active record calls. One to assign the results #, and one to get the actual results.
Something like this for the count:
$this->db->select('id');
$this->db->from('table');
$this->db->where($your_conditions);
$num_results = $this->db->count_all_results();
And for the actual query (which you should already have):
$this->db->select($your_columns);
$this->db->from('table');
$this->db->where($your_conditions);
$this->db->limit($limit);
$query = $this->db->get();
Have you read up on https://www.codeigniter.com/userguide2/database/active_record.html#caching ?
I see you are trying to do some pagination where you need the "real" total results and at the same time limiting.
This is my practice in most of my codes I do in CI.
$this->db->start_cache();
// All your conditions without limit
$this->db->from();
$this->db->where(); // and etc...
$this->db->stop_cache();
$total_rows = $this->db->count_all_results(); // This will get the real total rows
// Limit the rows now so to return per page result
$this->db->limit($per_page, $offset);
$result = $this->db->get();
return array(
'total_rows' => $total_rows,
'result' => $result,
); // Return this back to the controller.
I typed the codes above without testing but it should work something like this. I do this in all of my projects.
You dont actually have to have the from either, you can include the table name in the count_all_results like so.
$this->db->count_all_results('table_name');
Count first with no_reset_flag.
$this->db->count_all_results('', FALSE);
$rows = $this->db->get()->result_array();
system/database/DB_query_builder.php
public function count_all_results($table = '', $reset = TRUE) { ... }
The
$this->db->count_all_results();
actually replaces the:
$this->db->get();
So you can't actually have both.
If you want to do have both get and to calculate the num rows at the same query you can easily do this:
$this->db->from(....);
$this->db->where(....);
$db_results = $this->get();
$results = $db_results->result();
$num_rows = $db_results->num_rows();
Try this
/**
* #param $column_name : Use In Choosing Column name
* #param $where : Use In Condition Statement
* #param $table_name : Name of Database Table
* Description : Count all results
*/
function count_all_results($column_name = array(),$where=array(), $table_name = array())
{
$this->db->select($column_name);
// If Where is not NULL
if(!empty($where) && count($where) > 0 )
{
$this->db->where($where);
}
// Return Count Column
return $this->db->count_all_results($table_name[0]);//table_name array sub 0
}
Then Simple Call the Method
Like this
$this->my_model->count_all_results(['column_name'],['where'],['table name']);
If your queries contain a group by, using count_all_results fails. I wrote a simple method to work around this. The key to preventing writing your queries twice is to put them all inside a private method that can be called twice. Here is some sample code:
class Report extends CI_Model {
...
public function get($page=0){
$this->_complex_query();
$this->db->limit($this->results_per_page, $page*$this->results_per_page);
$sales = $this->db->get()->result(); //no table needed in get()
$this->_complex_query();
$num_results = $this->_count_results();
$num_pages = ceil($num_results/$this->results_per_page);
//return data to your controller
}
private function _complex_query(){
$this->db->where('a', $value);
$this->db->join('(subquery) as s', 's.id = table.s_id');
$this->db->group_by('table.column_a');
$this->db->from('table'); //crucial - we specify all tables here
}
private function _count_results(){
$query = $this->db->get_compiled_select();
$count_query = "SELECT count(*) as num_rows FROM (".$query.") count_wrap";
$r = $this->db->query($count_query)->row();
return $r->num_rows;
}
}

Resources