Avoiding Fat Controller
So I’m using Zend Framework and I have a question involving preventing fat controllers with one of my actions. Basically I am normalizing a CSV file into my database.
This means that I have to get the feed and then use my model.
The feed grabbing is just there to show how it works, but that is now an Action Helper.
I am using the Data Mapper pattern with Zend Framework. I hate that I am doing this in my Controller. All of those setProperty()->setProperty()->setProperty() look incredibly fugly and I feel like I am doing it in the wrong place? Would it be a better option to just create some kind of service layer where I pass the entire $feed and then in that class I instantiate my Models and my Mapper?
Also, I need to normalize, which means I should be using a transaction, but I’m unsure where I should start my transaction. Because of the way I am doing things currently, the only place I could ever consider is in my Controller. wow.. that would be an awful place.
How can I get the model behaviour and operations out of my controller?
ImportController.php
public function indexAction() {
$start = $this->getRequest()->getParam('start');
$end = $this->getRequest()->getParam('end');
$url = "http://www.domain.com/admin/GetBookingData.aspx";
$client = new Zend_Http_Client();
$client->setParameterGet('dateEnteredMin', $start);
$client->setParameterGet('dateEnteredMax', $end);
$client->setParameterGet('login', 'login');
$client->setParameterGet('password', 'password');
$client->setUri( $url );
$client->setConfig(array(
'maxredirects' => 0,
'timeout' => 30));
// Send the request.
$response = $client->request();
// Grab the feed from ->getBody and add it to $feed
$feed = $this->csv_to_array(trim($response->getBody()));
// The first item in the array is the heading in the CSV, so we can remove it from the array using shift().
$title = array_shift($feed);
// Create my Models and Mappers.
// *** EVERYTHING BELOW HERE IS WHAT I DON'T LIKE ***
$bookings = new Bookings_Models_Bookings();
$property = new Bookings_Models_Property();
$clients = new Bookings_Models_Clients();
$bookingsMapper = new Bookings_Models_Bookings_Mapper();
$propertyMapper = new Bookings_Models_Property_Mapper();
$clientsMapper = new Bookings_Models_Clients_Mapper();
$bookings->setId($feed[9])
->setPropertyId($feed[1])
->setClientId($feed[2])
->setDate($feed[4]);
$bookingsMapper->save($bookings);
$property->setId($feed[1])
->setPropertyName($feed[23])
$propertyMapper->save($bookings);
$clients->setId($feed[2])
->setFirstName($feed[20])
->setLastName($feed[21])
$clientsMapper->save($clients);
}
Service layer is probably the way I’d go. So you’d create a service class that looks something like this:
you’d then move all of your controller method code that’s after the csv_to_array call into that method, leaving the end of your controller method looking something like this:
This makes it easier to test your import code (since it’s in a standalone class) and easier to reuse in other parts of your application.