[ Index ]

PHP Cross Reference of Akelos Framework

title

Body

[close]

/AkActiveRecord/ -> AkObserver.php (source)

   1  <?php
   2  /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
   3  
   4  // +----------------------------------------------------------------------+
   5  // | Akelos Framework - http://www.akelos.org                             |
   6  // +----------------------------------------------------------------------+
   7  // | Copyright (c) 2002-2006, Akelos Media, S.L.  & Bermi Ferrer Martinez |
   8  // | Released under the GNU Lesser General Public License, see LICENSE.txt|
   9  // +----------------------------------------------------------------------+
  10  
  11  /**
  12   * @package ActiveRecord
  13   * @subpackage Base
  14   * @author Bermi Ferrer <bermi a.t akelos c.om>
  15   * @copyright Copyright (c) 2002-2006, Akelos Media, S.L. http://www.akelos.org
  16   * @license GNU Lesser General Public License <http://www.gnu.org/copyleft/lesser.html>
  17   */
  18  
  19  require_once (AK_LIB_DIR.DS.'Ak.php');
  20  require_once (AK_LIB_DIR.DS.'AkInflector.php');
  21  require_once (AK_LIB_DIR.DS.'AkActiveRecord.php');
  22  
  23  /**
  24  * Observer classes respond to life-cycle callbacks to implement trigger-like 
  25  * behavior outside the original class. This is a great way to reduce the clutter
  26  * that normally comes when the model class is burdened with functionality that
  27  * doesn't pertain to the core responsibility of the class. 
  28  * 
  29  * Example:
  30  * 
  31  *     class CommentObserver extends AkObserver
  32  *     {
  33  *         function afterSave($comment)
  34  *         {
  35  *             Ak::mail("admin@example.com", "New comment was posted",
  36  *                     $comment->toString());
  37  *         }
  38  *     }
  39  * 
  40  * This Observer sends an email when a Comment::save is finished.
  41  * 
  42  * ## Observing a class that can't be inferred
  43  * 
  44  * Observers will by default be mapped to the class with which they share a name.
  45  * So CommentObserver will be tied to observing Comment, ProductManagerObserver
  46  * to ProductManager, and so on. If you want to name your observer differently
  47  * than the class you're interested in observing, you can use the
  48  * AkActiveRecord->observe() class method:
  49  * 
  50  *     function afterUpdate(&$account)
  51  *     {
  52  *         $AuditTrail =& new AuditTrail($account, "UPDATED");
  53  *         $AuditTrail->save();
  54  *     }
  55  * 
  56  * If the audit observer needs to watch more than one kind of object, this can be
  57  * specified with multiple arguments:
  58  * 
  59  *     function afterUpdate(&$record)
  60  *     {
  61  *         $ObservedRecord =& new AuditTrail($record, "UPDATED");
  62  *         $ObservedRecord->save();
  63  *     }
  64  * 
  65  * The AuditObserver will now act on both updates to Account and Balance by
  66  * treating them both as records.
  67  * 
  68  * ## Available callback methods
  69  * 
  70  * The observer can implement callback methods for each of these methods:
  71  * beforeCreate, beforeValidation, beforeValidationOnCreate, beforeSave,
  72  * afterValidation, afterValidationOnCreate, afterCreate and afterSave
  73  * 
  74  * ## Triggering Observers
  75  * 
  76  * In order to activate an observer, you need to call create an Observer instance
  77  * and attach it to a model. 
  78  * 
  79  * In the Akelos Framework, this can be done in controllers using the short-hand
  80  * of for example: 
  81  * 
  82  *     $ComentObserverInstance =& new CommentObserver();
  83  *     $Model->addObserver(&$ComentObserverInstance);
  84  *
  85  */
  86  class AkObserver extends AkObject
  87  {
  88      /**
  89       * Models in this array will automatically be observed
  90       * 
  91       * Example:
  92       * 
  93       * var $observe = array('Person','Car');
  94       * 
  95       * @var array
  96       */
  97      var $observe = array();
  98      /**
  99      * $_observing array of models that we're observing
 100      */
 101      var $_observing = array();
 102  
 103      function __construct()
 104      {
 105          $num_args = func_num_args();
 106          for ($i = 0; $i < $num_args; $i++){
 107              $target = func_get_arg($i);
 108              if(is_object($target)){
 109                  $this->observe(&$target);
 110              }else{
 111                  $this->setObservedModels($target);
 112              }
 113          }
 114          $this->_initModelObserver();
 115      }
 116      
 117      /**
 118       * adds itself to the models which are listed
 119       * in var $observe = array(...)
 120       *
 121       */
 122      function _initModelObserver()
 123      {
 124          
 125          $this->observe = Ak::toArray($this->observe);
 126          if (count($this->observe)>0) {
 127              $this->setObservedModels($this->observe);
 128          }
 129          
 130      }
 131      
 132      /**
 133      * Constructs the Observer
 134      * @param $subject the name or names of the Models to observe
 135      */
 136      function observe (&$target)
 137      {
 138          static $memo;
 139          $model_name = $target->getModelName();
 140          $class_name = get_class($this);
 141          if(empty($memo[$class_name]) || !in_array($model_name, $memo[$class_name])){
 142              $memo[$class_name][] = $model_name;
 143              $this->_observing[] = $model_name;
 144              $target->addObserver(&$this);
 145          }
 146      }
 147      
 148      /**
 149      * Constructs the Observer
 150      * @param $subject the name or names of the Models to observe
 151      */
 152      function setObservedModels ()
 153      {        
 154          $args = func_get_args();
 155          $models = func_num_args() == 1 ? ( is_array($args[0]) ? $args[0] : array($args[0]) ) : $args;
 156  
 157          foreach ($models as $class_name)
 158          {   
 159              /**
 160              * @todo use Ak::import() instead.
 161              */
 162              $class_name = AkInflector::camelize($class_name);
 163              if (!class_exists($class_name)){
 164                  require_once(AkInflector::toModelFilename($class_name));
 165              }
 166              $model =& new $class_name();
 167              $this->observe(&$model);
 168          }
 169      }
 170      
 171  
 172      function update($state = '')
 173      {
 174      }
 175  
 176  }
 177  
 178  ?>


Generated: Mon Oct 27 12:43:49 2008 Cross-referenced by PHPXref 0.6