views:

132

answers:

2

This has bothered me for quite a while, but now it is necessity that I find the answer.

We are working on quite a large project using CodeIgniter plus Doctrine.

Our application has a front end and also an admin area for the company to check/change/delete data.

When we designed the front end, we simply consumed most of the Doctrine code right in the controller:

//In semi-pseudocode
function register()
{
  $data = get_post_data();

  if (count($data) && isValid($data))
  {
    $U = new User();
    $U->fromArray($data);
    $U->save();

    $C = new Customer();
    $C->fromArray($data);
    $C->user_id = $U->id;
    $C->save();

    redirect_to_next_step();
  }
}

Obviously when we went to do the admin views code duplication began and considering we were in a "get it DONE" mode so it now stinks with code bloat.

I have moved a lot of functionality (business logic) into the model using model methods, but the basic CRUD does not fit there.

I was going to attempt to place the CRUD into static methods, i.e. Customer::save($array) [would perform both insert and update depending on if prikey is present in array], Customer::delete($id), Customer::getObj($id = false) [if false, get all data]. This is going to become painful though for 32 model objects (and growing).

Also, at times models need to interact (as the interaction above between user data and customer data), which can't be done in a static method without breaking encapsulation.

I envision adding another layer to this (exposing web services), so knowing there are going to be 3 "controllers" at some point I need to encapsulate this CRUD somewhere (obviously), but are static methods the way to go, or is there another road?

Your input is much appreciated.

+1  A: 

I think you need to put that logic to tables class'es

class UserTable extends Doctrine_Table
{
  public function register()
  {
    // There you do data model (not concrete object) related stuff
  }
}

http://www.doctrine-project.org/projects/orm/1.2/docs/cookbook/code-igniter-and-doctrine/en

petraszd
Thanks. You have a good eye. I never noticed that part of the documentation. I'll take it into consideration.
TomWilsonFL
+1  A: 

Why not use a facade?

class RegistrationManager {
 public function register( $postData, $callBack ){
      $data = get_post_data();
      if (count($data) && isValid($data)){
        $U = new User();
        $U->fromArray($data);
        $U->save();
        $C = new Customer();
        $C->fromArray($data);
        $C->user_id = $U->id;
        $C->save();
        $callBack(); //I like this but you need PHP5.3
      }
     }
 }

In your app controllers:

$r = new RegistrationManager;
$r->register( get_post_data(), function(){ redirect_to_next_step(); } );

Facades are Models too (in my opinion), you may use them to hide wirings or complexities and reduce code-duplication.

Gabor de Mooij
That makes sense. I think I get too caught up in thinking that Model has to be in 1:1 object to table relation; need to think more outside the box. Thanks.
TomWilsonFL