<?php
class AppModel extends Model {

    var $actsAs = array('Containable');

    var $Session = null;                    // Session component
    var $skipUpdateDisplayField = false;    // exit condition for afterSave() when using _updateDisplayField()

    function __construct($id = false, $table = null, $ds = null) {
        parent::__construct($id, $table, $ds);

        // make the session component available in models, too ($this->Session)
		App::import('Component', 'SessionComponent');
		if (class_exists('SessionComponent')) {	// condition is here just to bypass console (bake) error
			$this->Session = & new SessionComponent();
		}
    }

    function beforeSave($options) {
        parent::beforeSave($options);

		// add created_by fields
        if ($this->hasField('created_by') && empty($this->data[$this->alias]['id'])) {
			$this->data[$this->alias]['created_by'] = $this->Session->read('Auth.User.username');
		}

    	// add modified_by fields
        if ($this->hasField('modified_by')) {
			if (!isset($this->data[$this->alias]['modified_by']) || $this->data[$this->alias]['modified_by'] !== false) {
				$this->data[$this->alias]['modified_by'] = $this->Session->read('Auth.User.username');
			} else {
				unset($this->data[$this->alias]['modified_by']);
			}
		}

        return true;
    }

    function afterSave($created) {
        parent::afterSave($created);

        // update 'display' field if exists so find('list') can generates appropriately formatted data
        if ($this->hasField('display') && !$this->skipUpdateDisplayField) $this->_updateDisplayField($this->id);
    }

    function _updateDisplayField($id = null) {

        if (!$this->hasField('display')) return false;

        if ($id === null) $conditions = array();
            elseif (!is_array($id)) $conditions = array("{$this->alias}.id" => array($id));
            else $conditions = array("{$this->alias}.id" => $id);

        $rows = $this->find('all', array('conditions' => $conditions));
        $update = array();
        foreach($rows as $row) {
            $display = $this->_formatDisplayField($row);
            $update[] = array('id' => $row[$this->alias]['id'], 'display' => $display);
        }

        $this->skipUpdateDisplayField = true;
        $this->saveAll($update, array('validate' => false));
        $this->skipUpdateDisplayField = false;

		return true;
    }

    // placeholder function, override in child classes to set appropriate display field format
    function _formatDisplayField($row) {
        return '';
    }

    // unique validation method
    function unique($check) {
		$conditions = array();
		foreach($check as $k => $v) {
			$conditions["{$this->alias}.{$k}"] = $v;
		}
        $exists = $this->find('first', array('fields' => array('id'), 'conditions' => $conditions));
		return (empty($exists) || ($exists[$this->alias]['id'] == $this->id));
    }

	function getGrouped($assoc = null, $value_key = 'id', $value_field = 'name') {
		if (empty($assoc)) $assoc = "{$this->alias}Group";
		if (!isset($this->belongsTo[$assoc])) return false;

		$groups = $this->{$assoc}->find('list');
		$temp = $this->find('list', array('fields' => array(
			"{$this->alias}.{$value_key}",
			"{$this->alias}.{$value_field}",
			"{$this->alias}.{$this->belongsTo[$assoc]['foreignKey']}"))
		);
		$result = array();
		foreach($groups as $group_id => $group_name) {
			$result[$group_name] = (!empty($temp[$group_id]) ? $temp[$group_id] : array());
		}

		return $result;
	}
	
}
?>