1

I'm learning Laravel and I've created a basic blog. Now, I'm trying to create something similar to an autoblog where posts change status based on either start_date or end_date. So I've created an enum table in my migration with the statuses I need to use. Right now, what I'm trying to do is change the post status to Upcoming if the date and time are greater than today but I'm not having any luck. Initially, I created an event and put the code below in the listener but is working (or not working) in the same way as in the observer. I read that it would be better in the observer if there will be several events.

The flow would be, when the post is created, check the start_date and change the status if the date is greater than today. The code below changes the status to Upcoming if I change it to creating, instead of created but it still doesn't take the start_date into account because it adds it to every post, regardless of the start_date. I tried using an if statement but I kept getting stuck. What am I missing or doing wrong?

Eventually, my goal is for the posts to change the status automatically without any user-initiated action. Perhaps, I could use Laravel queues for that but I haven't got that far yet. For the moment, I'm trying to get past this one.

 <?php

 namespace App\Observers;

 use App\Models\Post;
 use Carbon\Carbon;

 class PostObserver
  {
   public function created(Post $post)
    {

     $post = Post::whereDate('start_date', '>', Carbon::now()->toDateString(){

     $post->post_status = 1  // 1 = Upcoming status
    });
  }
}
2
  • You are injecting the post instance, so I think you have to use it instead do a new query to get all posts where start_date greater than now. Try with if(Carbon::parse($post->start_date) > Carbon::now() { $post->post_status = 1 }. Also try with creating instead created Commented Feb 22, 2020 at 16:15
  • This one is having the same result, it adds the status even when the date is less than now, also had to use ->toDateString() Commented Feb 22, 2020 at 20:07

2 Answers 2

1

Got it working like this, kind of a combination of the two responses, for which I'm thankful:

if (Carbon::parse($post->start_date)->greaterThan(Carbon::now()))
   {
    $post->post_status = 1;
   }
Sign up to request clarification or add additional context in comments.

Comments

0

Use method creating

<?php

namespace App\Observers;

use App\Models\Post;
use Carbon\Carbon;

class PostObserver
{
    public function creating(Post $post)
    {
        if ($post->start_date->greaterThan(Carbon::now())) {
            $post->post_status = 1;
        }
    }
}

Creating method will be invoked before post is saved to database. In that point you make check and only in case that start_date is bigger than current timestamp post_status will get value of 1. If you need you can set else block where you give value of 0 to post status in case it is not db default or if there is need for something like that.

2 Comments

Can't get this one to work, keep getting Call to a member function greaterThan() on string, even when using ->toDateString()
Try with if (Carbon($post->start_date)->greaterThan(Carbon::now())) {/** code */} or if (Carbon::createFromFormat('Y-m-d H:i:s', $post->start_date)->greaterThan(Carbon::now())) {/** code */} depending of what is format you are accepting at client side.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.