Location: PHPKode > projects > Agile Toolkit > atk4-atk4-addons-efc6814/mvc/Controller.php
<?php
/*
 * Created on 06.04.2009
 *
 * Responsibilities:
 *  - gateway beetween model and view objects
 */

class Controller extends AbstractController{
	protected $type_correspondence=array(
		'grid'=>array(
			'string'=>'text',
			'int'=>'number',
			'numeric'=>'number',
			'real'=>'real',
			'money'=>'money',
			'text'=>'shorttext',
			'reference'=>'text',
			'password'=>'text',
			'datetime'=>'timestamp',
			'date'=>'date',
			'daytime'=>'daytime',
			'daytime_total'=>'daytime_total',
			'boolean'=>'boolean',
			'list'=>'text',
			'readonly'=>'text',
			'image'=>'text',
			'file'=>'referenece',
		),
		'tree'=>array(
			'string'=>'text',
			'int'=>'text',
			'numeric'=>'text',
			'money'=>'text',
			'real'=>'text',
			'text'=>'shorttext',
			'reference'=>'text',
			'datetime'=>'timestamp',
			'date'=>'date',
			'boolean'=>'text',
			'list'=>'text',
			'readonly'=>'text',
		),
		'form'=>array(
			'string'=>'line',
			'text'=>'text',
			'int'=>'line',
			'numeric'=>'line',
			'money'=>'line',
			'real'=>'line',
			'date'=>'DatePicker',
			'datetime'=>'DatePicker',
			'daytime'=>'timepickr',
			'boolean'=>'checkbox',
			'reference'=>'readonly',
			'reference_id'=>'reference',
			'password'=>'password',
			'list'=>'reference',
			'radio'=>'Radio',
			'readonly'=>'readonly',
			'image'=>'image',
			'file'=>'upload',
		),
		'filter'=>array(
			'string'=>'line',
			'text'=>'text',
			'int'=>'line',
			'numeric'=>'line',
			'real'=>'line',
			'money'=>'line',
			'date'=>'daterange',
			'datetime'=>'daterange',
			'daytime'=>'timepickr',
			'boolean'=>'AScheckbox',
			'reference'=>'autocomplete',
			'password'=>'password',
			'list'=>'reference',
			'readonly'=>'readonly',
			'image'=>'upload',
		),
	);
	protected $model_name;
	protected $active_fields=null;				// If set this defines which fields to display in order

	function __call($name,$args){
		// some of the methods may be in related Model
		if(method_exists($this->getModel(),$name)){
			$r=call_user_func_array(array($this->getModel(),$name),$args);
			//if($r instanceof Model)return $this;
			return $r;
		}
		if(!method_exists($this,$name))throw new Exception_InitError("Method $name is not defined neither in $this->short_name, " .
				"nor in its Model");
	}

	function init(){
		parent::init();
		if($this->model_name)//throw new Exception_InitError("Model name is not defined for controller $this->name");
			$this->setModel($this->model_name);
	}
    function debug(){
        $this->getModel()->debug();
        return $this;
    }

	function initForm(){
		$this->addFormFields();
		$this->owner->setTitle($this->getTitle());
		// adding DB fields
		////$this->getModel()->dsql($this->owner->name,false)->field(array_keys($this->owner->getAllData()));

		$this->getModel()
			->setQueryFields('edit_dsql')  // get external fields feature, with needed joins and filtering fields
			//->dsql($this->owner->name,false);
		;
		//
        $this->api->hook('compat-addModelSave',array($this->owner));
		//$this->owner->addSubmit('Save');
		return $this;
	}
	function initFilter(){
		$this->addFilterFields();
		$this->getModel()
			->setQueryFields('edit_dsql')  // get external fields feature, with needed joins and filtering fields
		;
		return $this;
	}
	/**
	 * Adds fields to a form on the basis of model definition
	 */
	function addFormFields(){
		foreach($this->getActualFields() as $field_name=>$def){
			if(!is_object($def))continue;
			//if(!$def->visible())continue;
			if(!$def->editable())continue;
			//if($def->system()===true)continue;
			$this->owner->addFieldMVC($field_name);
			// all field's parameters and manipulations are made in MVCForm::addField()
		}
	}
	/**
	 * Adds columns to a grid on the basis of model definition
	 */
	function addGridFields(){
		foreach($this->getActualFields() as $field_name=>$def){
			// some field types are not required ???
			if(!is_object($def))continue;
			// we don't chck system status here, as actual fields contain fields that must be shown
			if($def->visible()===true && $def->datatype()!='reference_id')$this->owner->addColumnMVC($field_name);
		}
	}
	/**
	  * Initialise search filter for this entity list
	  */
	function addFilterFields(){
		foreach($this->getActualFields() as $field_name=>$def){
			if(!is_object($def))continue;
			$this->owner->addFieldMVC($field_name);
		}
	}
	/**
	 * Returns Model field set
	 */
	function getAllFields(){
		return $this->getModel()->getFields();
	}
	function getTitle(){
		$r=explode('_',$this->short_name);
		array_shift($r);
		return join(' ',$r);
	}
	function initLister(){
		$this->addGridFields();
	}
	/**
	 * Returns the string representing the datatype of the field
	 */
	function formatType($type,$object,$field=null){
        if($field){
			//$arr=$this->model->getField($field)->display();
			$arr=$this->getModel()->getField($field)->display();
            if(is_array($arr) && $arr[$object]){
                return $arr[$object];
            }
        }
		$r=$this->type_correspondence[$object][$type];
		if(!$r)throw new Exception_InitError("Type '$type' is not defined for $object");//$r=$type;
		return $r;
	}
	/**
	 * Previously introduced in Lister, this method executes select query before
	 * the associated View object will be rendered
	 */
	function execQuery(){
		// default fields must be added (if not yet)
		if(!$this->getModel()->isFieldsSet($this->owner->name))
			$this->getModel()->setQueryFields($this->owner->name);
		$this->getModel()->dsql($this->owner->name)->do_select();
	}
	function update($data=array()){
		// if no data passed trying to get it from the Form that owns controller
		// $data will be appended to values already set with Controller::set() or Model::set()
		if(empty($data)&&($this->owner instanceof Form))$data=$this->owner->getAllData();
		$this->getModel()->update($data);
		return $this;
	}
    function _bindView(){
        // data was loaded previously
        // problem here, isInstanceLoaded is not defined in Controller - it's in Model.. - causing crashing
        if (method_exists($this, "isInstanceLoaded")){
            if($this->isInstanceLoaded()){
                /*

                   // TODO: test and uncomment this!

                if($this->owner instanceof Form){
                    if(isset($_GET['id']))$this->owner->addConditionFromGET('id');
                    else $this->owner->addCondition('id',$id);
                }
                */
                if($this->owner instanceof View){
                    $this->owner->template->set($this->get());
                }
            }
        }
    }
	/**
	 * Calls assigned Model loadData() and in addition adds condition to form,
	 * if form is the owner of this controller
	 */
	function loadData($id=null,$all_fields=false){
		$this->getModel()->loadData($id,$all_fields);
		if($this->owner instanceof Form){
			if(isset($_GET['id']))$this->owner->addConditionFromGET('id');
			else $this->owner->addCondition('id',$id);
		}
		if($this->owner instanceof View){
			$this->owner->template->set($this->get());
		}
		return $this;
	}

	/**
	  * Set list of fields which should be displayed by grid or quickedit
	  */
	public function setActualFields($actual_fields){
		$this->getModel()->setActualFields($actual_fields);
		return $this;
	}
	/**
	 * This method used by admin system
	 * Returns the assoc array of extra action to be added to entity lister near Add button,
	 * so the core could render entity lister automatically w/o additional page class creation
	 * No implementation here for the actions listed, all functionality is implemented in
	 * corresponding page class
	 * @return false or array($href=>$title), where $href is valid URL in AModules3 style
	 */
	public function getExtraActions(){
		return false;
	}
	/**
	 * Generates user-friendly string of related entities
	 * @param array $data entity hash as it returned from Model_Table::getRelatedEntities()
	 * @return string
	 */
	public function formatRelatedEntities($data){
		$result=array();
		foreach($data as $entity=>$count){
			switch($entity){
				case 'docspec':
					$name='document line';
					break;

				case 'timesheet':
					$name='timesheet entry';
					break;

				case 'fixed_asset':
					$name='fixed asset';
					break;

				default:
					$name=$entity;
			}
			$result[]=$count." $name".($count==1?'':'s');
		}
		return join(', ',$result);
	}
	public function countRelatedEntities($data){
		$result=0;
		foreach($data as $count)$result+=$count;
		return $result;
	}
	function __toString(){
		return $this->getModel()->__toString();
	}
}
Return current item: Agile Toolkit