Croogo: How to pass data from a plugin to an existing admin view

Hi fellow bakers, this is meant to be a tiny tutorial on how to pass data from your own plugin to an existing admin view, e.g. your plugin adds an additional tab to the Users edit view, and you want to provide the data displayed in that tab.

I've been searching for the answer on how to achieve this myself for months, and I couldn't believe how easy it actually was. I'm gonna show you how to do that right now.

What you need

You need an element that shall serve as an admin tab, and you need to tell Croogo that it indeed is. I added a new tab to the User admin add and User admin edit views inside the plugins bootstrap file.

Croogo::hookAdminTab('Users/adminadd', 'Pluginname', 'pluginfolder.adminuserextended');
Croogo::hookAdminTab('Users/adminedit', 'Pluginname', 'pluginfolder.adminuserextended');

What does this element contain?

Everything you want to be displayed inside that tab. For testing purposes I think the following piece of cake, er code is good enough:

data); ?>
This will display all data that is available to be displayed - really handy in combination with the form helper!

Now that's just the preparation, now we're going into it. We need a behavior, and we need to bind that behavior to an existing model, which is done inside the plugin bootstrap as well:

Croogo::hookBehavior('User', 'Pluginname.ExtendedUser', array(
    'relationship' => array(
        'hasMany' => array(
            'Customfield' => array(
                'className' => 'Pluginname.Customfield',
                'foreignKey' => 'Pluginname.User_id',
                'conditions' => array('Customfield.status' => 1),

Here you can see how you can bind a behavior, which is part of your plugin, to an existing model provided by Croogo. But that's by far not all: As the third argument an array containing a relationship (this is not limited to just one association, you can set up as many as you want to) is supplied. This array is passed to the behavior and actually serves as an array containing custom data for your personal needs inside the behavior. This also means, that until now, nothing would happen. There is no functionality implemented in your behavior that could handle this tiny array containing the definition of a relationship. Luckily, we can do that ;)

And it might look like this:

<?php class ExtendedUserBehavior extends ModelBehavior {

function setup(&$model, $config = array()) {
    //Merging the specified (or not specified) config array with an array containing default values
    $config = Set::merge(array(
        'relationship' => false,
        'joins' => false,
        'enabled' => true,
        ), $config);
    //Each Model($model->alias) gets its own key containing the specific config array
    $this->settings[$model->alias] = $config;
    //Now let's setup any desired relationships
    $this->_setupRelationships($model, $config);

function _setupRelationships(&$model, $config = array()) {
    if (!empty($this->settings[$model->alias]['relationship'])) {
        //Here we add the specified relationship to our model ON THE FLY
        $model->bindModel($config['relationship'], false);
        //To make sure we really get all the desired data, we need to set the recursive level!
        //This really drove me mad, don't forget to adapt this according to your needs
        $model->recursive = 2;

function beforeFind(&$model, $query) {
    //Needs to be done!
    return $query;


function afterFind(&$model, $results, $primary) {
    return $results;
    //Here we just merge all available fields with the ones the user already has filled out, and return that as a new array


function beforeSave(&$model, $query) {
    //Since save() wont save any associated data, we got to do this on our own
    $temp_data = $model->data['UsersExtendedField'];
    return $query;

} ?>

What this behavior actually does is pretty simple. It fetches the array 'relationships' out of the configuration array specified in the plugin bootstrap and binds those relationships on the fly to the model. Easy, huh?!