Example #1
0
 /**
  * Map 'change' and 'get' methods.
  *
  * @param Model $Model Model using this behavior.
  * @param string $method Real method's name.
  * @return mixed For 'change' operations, returns TRUE on success and FALSE otherwise. For
  *   'get' operations, returns a boolean when a state is provided by comparing it to the
  *   record's state field result, or returns the record's state field result.
  * @throws FatalErrorException If the state's field is not configured as such.
  * @see StateableBehaviorTest for examples of how arguments can be passed.
  */
 public function __call(Model $Model, $method)
 {
     foreach (array('change', 'get') as $do) {
         $field = str_replace($do, '', $method);
         if ($field != $method) {
             $field = Inflector::underscore($field);
             break;
         }
     }
     if (!array_key_exists($field, $this->settings[$Model->alias]['fields'])) {
         throw new FatalErrorException(__d('common', "Missing state field configuration ('%s')", $field));
     }
     $args = func_get_args();
     $id = $Model->getID();
     $state = isset($args[2]) ? $args[2] : null;
     $validate = isset($args[4]) ? $args[4] : true;
     if (isset($args[3])) {
         if (!is_bool($args[3])) {
             $id = $args[2];
             $state = $args[3];
         } else {
             $validate = $args[3];
         }
     } else {
         if (empty($id) && (isset($args[2]) || 'get' == $do) && $Model->exists($state)) {
             $id = $state;
             $state = null;
         }
     }
     if (empty($id) || !$Model->exists($id)) {
         return false;
     }
     $current = $Model->field($field, array($Model->alias . '.' . $Model->primaryKey => $id));
     if ('get' == $do) {
         if (!empty($state)) {
             return $state == $current;
         }
         return $current;
     }
     $Model->id = $id;
     $eventName = 'Model.' . $Model->name . '.';
     $fieldName = Inflector::camelize($field);
     $Event = new CakeEvent($eventName . 'beforeChange' . $fieldName, $Model, compact('field', 'state', 'validate'));
     list($Event->break, $Event->breakOn) = array(true, false);
     $result = $Model->triggerEvent($Event);
     if (false === $result || !($ret = $state != $current && $Model->saveField($field, $state, $validate))) {
         return false;
     }
     $Model->triggerEvent($eventName . 'afterChange' . $fieldName, $Model);
     return true;
 }