1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<?php
/**
 * After Find Behavior adds in the ability to trigger behaviors of recursive
 * results. Currently, if you have User->Profile and do a find on User, the
 * behaviors on User will be called. None of the behaviors on Profile will be
 * triggered.
 *
 * This Behavior allows you to recursively call those afterFind behaviors that
 * would effect your afterFind result.
 *
 * Examples:
 *
 * 1. Run on all model associations, but not recursive (default):
 * $actsAs = array('AfterFind' => array('enabled'=>1,'associations'=>TRUE));
 *
 * 2. Run all Profile behaviors on results
 * $actsAs = array('AfterFind' => array('enabled'=>1,'associations'=>array('Profile')));
 *
 * 3. Run all Profile behaviors AND Avatar behaviors on results
 * $actsAs = array('AfterFind' => array('enabled'=>1,'associations'=>array('Profile'=>array('Avatar'))));
 *
 * Possible issues:
 * - The default AfterFind behavior configuration is altered and not restored
 *
 * Future features:
 * - specify Behaviors to ignore (detatch) e.g. Containable
 * - add recursive field to work in conjunction with associations=TRUE
 */
class AfterFindBehavior extends ModelBehavior {
   
    var $settings = array();
   
    function setup(&$model,$settings) {
        if (!isset($this->settings[$model->alias])) {
            $this->settings[$model->alias] = array(
                'enabled' => TRUE,
                'associations' => TRUE
            );
        }
       
        $this->settings[$model->alias] = array_merge(
            $this->settings[$model->alias],
            $settings
        );
    }
   
    /**
     * Process running the behaviors for each alias the model has that is in the result
     * @param object $model reference to model
     * @param array $results result set
     * @param bool $primary [optional] usuall false for sets of data. See manual
     * @return array modified $results
     */
    function afterFind(&$model,$results,$primary = false) {
        if ($primary !== TRUE) return;
       
        foreach($results as $key=>$value) {
            foreach(array_keys($value) as $model_alias) {
                if ($model_alias !== $model->alias &&
                    ( $this->settings[$model->alias]['associations'] === TRUE ||
                        ( is_array($this->settings[$model->alias]['associations']) && in_array($model_alias,array_keys($this->settings[$model->alias]['associations']))))) {
                    $alias_result = array($model_alias => $value[$model_alias]);
                    // check for recursive definition and bind this behavior with local settings
                    if (is_array($this->settings[$model->alias]['associations'][$model_alias])) {
                        $model->{$model_alias}->Behaviors->attach('AfterFind',array('enabled'=>TRUE,'associations'=>$this->settings[$model->alias]['associations'][$model_alias]));
                    }
                    $return = $model->{$model_alias}->Behaviors->trigger($model->{$model_alias},'afterFind',array($alias_result,$primary),array('modParams' => TRUE));
                    if ($return !== FALSE) $results[$key][$model_alias] = $return;
                }
            }
        }
        return $results;
    }
}
?>