Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

HarryN's avatar

Get another attribute in mutator?

I currently have a booking form that has two fields.

Date and Time.

Date would return something like 14/04/2015 Time would return 10:30

I'd like to turn this into one field in my database called booking_for had have it an instance of carbon.

Here is my current mutator.

    public function setBookingForAttribute($date)
    {
        $this->attributes['booking_for'] = Carbon::createFromTimestamp(strtotime($date . $time . ":00"));
    }

How would I get the $time variable? I have tried $this->time and including time in the function parameter's with no luck.

0 likes
9 replies
mstnorris's avatar

Where is the $time coming from? This isn't tested, but try:

Carbon::createFromFormat('d/m/Y H:i', $date . ' ' . $time);
kreitje's avatar

You could create a separate method in the model that accepts the date and the time.

    public function setBookingForAttribute($date)
    {
        $this->attributes['booking_for'] = Carbon::createFromTimestamp(strtotime($date));
    }

    public function setBookingDate($date, $time)
    {
        $this->booking_for = $date . ':' . $time . ':00';
    }
mstnorris's avatar

@kreitje that won't work as the syntax is incorrect.

public function setBookingDate($date, $time)
{
    $this->booking_for = $date . ':' . $time . ':00'; // why the extra ':' ?
}
kreitje's avatar

Yeah my bad, it shouldn't have that middle colon.

martinbean's avatar

@Haryke Sounds like you need a class that transforms the data from submitted from your form to a shape suitable for the model. You should not do this transformation in the model, as that means every where you use the model you have to shoe-horn your data into this kludged pattern.

Instead, have a class that takes your attributes as submitted by your form, and then set them on the model as appropriate:

class CreateBookingService
{
    public function create(array $attributes)
    {
        $booking = new Booking();
        $booking->booking_for = $attributes['date'].' '.$attributes['time'];
        $booking->save();

        return $booking;
    }
}

Usage:

$service = new CreateBookingService();
$booking = $service->create($request->all());

This way every thing is isolated and has a single responsibility. Your model doesn’t need modifying just because data’s coming in a different shape, and you can have different adapters per context, i.e. front-end form, back-end form, API etc.

HarryN's avatar

@martinbean That's a great idea. Where would I put that class? Also, where does validation come into it in your example?

martinbean's avatar

@Haryke The class could go where ever you wanted. You could follow Laravel’s lead and place it in the app/Services directory.

Validation you can keep how you’re currently doing it, such as a form request class.

Please or to participate in this conversation.