tags:

views:

166

answers:

5

I am writing an application using CakePHP and I am unsure as to where I should be putting my generateMapUrl function.

function generateMapUrl($id = null) {
    if ( !$id ) {
        $this->Session->setFlash('Invalid Property Id');
    } 
    $this->read(null, $id);
    $url = "http://maps.google.com/maps?oi=map&q=";
    $url .= $this->data['street_num'] . '+';
    $url .= $this->data['street'] . '+';
    $url .= $this->data['city'] . '+';
    $url .= $this->data['province'] . '+';
    $url .= $this->data['country'] . '+';
    $url .= $this->data['postal_code'];

    return $url;
}

I have the following structure:

Booking (Model & Controller) Properties (Model & Controller) Address (Model & Controller)

A Booking hasOne Property and a Property hasOne Address. I would like to be able to call generateMapUrl for any Address. I am unsure as to where to put the method though... Address controller? Address Model? (Note: I am calling this method from the Bookings controller)

+2  A: 

In the Controller, it has session data. The Model should not be aware of any session states.

zodeus
I assume you are referring to the Address Controller ?
Shane
That was my first thought, thanks for the confirmation :)
Shane
A: 

I might consider creating an AddressMapUrlGenerator class and using it to create the URL. You could pass it an Address. That way, you will not be muddling the Model with worries about urls or maps, and you will not have future worries about having the same function spread out in more than one Controller.

RibaldEddie
Perhaps you would also recommend creating an abstract base class called UrlGenerator?
zodeus
Perhaps, but it really depends on the application's business domain. More important, central domain objects should probably have more well-decomposed responsibilities. If it's not as important part of the system, then you probably shouldn't spend as much time on it.
RibaldEddie
I can agree with that.
zodeus
A: 

In the model build a GoogleAddress Class. Then use the GoogleAddress in the controller.

Andrew Clark
A: 

At the very least, there are three things happening:

1) Creation of the URL 2) Error handling 3) And though not explicit, the actual call.

The creation of the URL should be handled by a dedicated helper class. It is likely to best to have the check carried out on the controller, the actual checking code would reside elsewhere. The error handling should be on the controller, as it would have to do anything special required for the specific place the user is at. Lastly, the call itself, should of course take place on the controller.

Saem
A: 

The generateMapUrl() method should be a method in your Address model as it is dealing with fetching and formatting Address data, but should return false and not contain the session calls:

function generateMapUrl($id = null) {
  $this->recursive = -1;
  if (!$this->read(null, $id)) {
    return false;
  } 
  $url = "http://maps.google.com/maps?oi=map&q=";
  $url .= $this->data['street_num'] . '+';
  $url .= $this->data['street'] . '+';
  $url .= $this->data['city'] . '+';
  $url .= $this->data['province'] . '+';
  $url .= $this->data['country'] . '+';
  $url .= $this->data['postal_code'];  
  return $url;
}

You can then call this from any controller and use the session calls there:

function x() {
  if (!$mapUrl = ClassRegistry::init('Address')->generateMapUrl($addressId)) {
    $this->Session->setFlash('Invalid Property Id');
  }
}
neilcrookes
Good answer, this makes the most sense to me as I am just formatting the address data. worth noting that it needs to be data['Address']['street'] rather than data['street'] but that was my fault to start with. Thanks for your answer!
Shane