Reputation:
I have a controller with a method to process a booking. The method is getting quite large and after developing a good handful of apps I realized I'm doing something wrong because many of my controllers methods are large and messy.
For example
function processBooking($id) {
// validate
// if validaton fails return errors
// if validation pass do the following
$booking = getDetailsFromRepository($id)
// check if client is paying with credits
// process booking with credits
// update client credids
// check if any errors with stripe and return readable message to user
// else process booking with credit card
// set all date for Stripe::charge
// capture charge
// check if any errors with stripe and return readable message to user
// if everything went well
// save payment in db
// save booking
// return success message to user
}
most steps are functions from repository class. The whole method is about 300 lines.
After a bit of research I came across services so I created a ProcessBookingService.php class in which I chunck all ifs and checks down to multiple functions and I reduced the controller method down to 50 lines which makes it clean and readable.
The problem is that on the old method I would return a different message back to the user based on what went wrong ex: the card was declined, not enough points, etc.
Since most of the logic happens in the Service class, on the functions that I need to return a message back to the user I set a variable with a message and return that. Now the controllers gets lots of ifs ex:
$booking = $booking->process($data);
if($booking['success']) // redirect with success
else if($booking['card_declined']) // redirect with error
else if($booking['not_enough_points']) // redirect with error
else if($booking['stripe_request_error']) // redirect with error
else // unknown error on the server redirect with error
Is this correct from design and programming point of view? Any other suggestions would be much appreciated.
Thanks
Upvotes: 1
Views: 243
Reputation: 12090
You can use exceptions to cleanly solve the problem. It could be as simple as:
try
{
$bookingService->book($data);
}
catch(BookingException $e)
{
// redirect as error, possibly using $e->getMessage()
}
// redirect as success
You may want to have a hierarchy of exceptions if you want to redirect to different locations. If you're using language strings for localization, you can use the error code in the redirection:
redirect('error_page', ['code' => $e->getCode()]);
Where this gets translated to something like example.com/book/error?code=1234
and then you use the code to display the correct, localized message.
Upvotes: 1