Search code examples
phpcakephpdirectory-structure

CakePHP Architecture


I'm trying to figure out if there is a way to share controllers, models, and views for multiple CakePHP apps, but override specific methods within them if necessary. So, for example, if I had the following structure...

/my_cool_app
  /core
    /app
      /Model
        Person.php
        ->findPerson();
        ->mapPerson();
  /orgs
    /org_1
     /app
       /Model
         Person.php
         ->mapPerson();

What I would like to do is have the CakePHP app in org_1/app use all of the controllers, models, views, etc. from /core/app, but provide the ability to override any specific method if the file exists in that structure (for example, org_1/app/Model/Person.php).

Is this doable?


Solution

  • Definitely possible. Your directory as such:

    /your_cool_app
        /base
            /app
                /Model
                    AppModel.php
                    BasePerson.php
        /inherited
            /app
                /Model
                    InherietdPerson.php
    

    Then inside of the inherited directory's bootstrap.php you can use App::build() to tell the application where to look for the base models:

    App::build(array(
        'Model' => array(
            //Path to the base models
            $_SERVER['DOCUMENT_ROOT'] . DS 
                ."your_cool_app" . DS 
                    . "base" . DS 
                        . "app" . DS 
                            . "model"
        )
    ));
    

    The BasePerson will extend AppModel:

    <?php
    
        App::uses('AppModel', 'Model');
    
        class BasePerson extends AppModel {
    
        }
    
    ?>
    

    And the InheritedPerson extends the BasePerson:

    <?php
    
        App::uses('AppModel', 'Model');
    
        class InheritedPerson extends BasePerson {
    
        }
    
    ?>
    

    Now to test if it worked just create a controller in the inherited app and check to see what Models your app has loaded:

    $this->set('models', App::objects('Model'));
    

    And the view:

    <?php
        debug($models); 
    ?>
    

    It should print out something like the following:

    array(
        (int) 0 => 'AppModel', //Is in the base app
        (int) 1 => 'BasePerson', //Is in the base app
        (int) 2 => 'InheritedPerson' //Is in the inherited app
    )
    

    Check out CakePhp's App class for more information.