PageRenderTime 27ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/atk4-addons/mvc/Controller.php

https://github.com/git86/todo
PHP | 296 lines | 215 code | 9 blank | 72 comment | 23 complexity | 714824fbe3b67119b88174b0c8fa039b MD5 | raw file
Possible License(s): AGPL-3.0
  1. <?php
  2. /*
  3. * Created on 06.04.2009
  4. *
  5. * Responsibilities:
  6. * - gateway beetween model and view objects
  7. */
  8. class Controller extends AbstractController{
  9. protected $type_correspondence=array(
  10. 'grid'=>array(
  11. 'string'=>'text',
  12. 'int'=>'number',
  13. 'numeric'=>'number',
  14. 'real'=>'real',
  15. 'money'=>'money',
  16. 'text'=>'shorttext',
  17. 'reference'=>'text',
  18. 'datetime'=>'timestamp',
  19. 'date'=>'date',
  20. 'daytime'=>'daytime',
  21. 'daytime_total'=>'daytime_total',
  22. 'boolean'=>'boolean',
  23. 'list'=>'text',
  24. 'readonly'=>'text',
  25. 'image'=>'text',
  26. 'file'=>'referenece',
  27. ),
  28. 'tree'=>array(
  29. 'string'=>'text',
  30. 'int'=>'text',
  31. 'numeric'=>'text',
  32. 'money'=>'text',
  33. 'real'=>'text',
  34. 'text'=>'shorttext',
  35. 'reference'=>'text',
  36. 'datetime'=>'timestamp',
  37. 'date'=>'date',
  38. 'boolean'=>'text',
  39. 'list'=>'text',
  40. 'readonly'=>'text',
  41. ),
  42. 'form'=>array(
  43. 'string'=>'line',
  44. 'text'=>'text',
  45. 'int'=>'line',
  46. 'numeric'=>'line',
  47. 'money'=>'line',
  48. 'real'=>'line',
  49. 'date'=>'DatePicker',
  50. 'datetime'=>'DatePicker',
  51. 'daytime'=>'timepickr',
  52. 'boolean'=>'checkbox',
  53. 'reference'=>'readonly',
  54. 'reference_id'=>'reference',
  55. 'password'=>'password',
  56. 'list'=>'reference',
  57. 'radio'=>'Radio',
  58. 'readonly'=>'readonly',
  59. 'image'=>'image',
  60. 'file'=>'upload',
  61. ),
  62. 'filter'=>array(
  63. 'string'=>'line',
  64. 'text'=>'text',
  65. 'int'=>'line',
  66. 'numeric'=>'line',
  67. 'real'=>'line',
  68. 'money'=>'line',
  69. 'date'=>'daterange',
  70. 'datetime'=>'daterange',
  71. 'daytime'=>'timepickr',
  72. 'boolean'=>'AScheckbox',
  73. 'reference'=>'autocomplete',
  74. 'password'=>'password',
  75. 'list'=>'reference',
  76. 'readonly'=>'readonly',
  77. 'image'=>'upload',
  78. ),
  79. );
  80. protected $model_name;
  81. protected $active_fields=null; // If set this defines which fields to display in order
  82. function __call($name,$args){
  83. // some of the methods may be in related Model
  84. if(method_exists($this->getModel(),$name)){
  85. $r=call_user_func_array(array($this->getModel(),$name),$args);
  86. //if($r instanceof Model)return $this;
  87. return $r;
  88. }
  89. if(!method_exists($this,$name))throw new Exception_InitError("Method $name is not defined neither in $this->short_name, " .
  90. "nor in its Model");
  91. }
  92. function init(){
  93. parent::init();
  94. if($this->model_name)//throw new Exception_InitError("Model name is not defined for controller $this->name");
  95. $this->setModel($this->model_name);
  96. }
  97. function debug(){
  98. $this->getModel()->debug();
  99. return $this;
  100. }
  101. function initForm(){
  102. $this->addFormFields();
  103. $this->owner->setTitle($this->getTitle());
  104. // adding DB fields
  105. ////$this->getModel()->dsql($this->owner->name,false)->field(array_keys($this->owner->getAllData()));
  106. $this->getModel()
  107. ->setQueryFields('edit_dsql') // get external fields feature, with needed joins and filtering fields
  108. //->dsql($this->owner->name,false);
  109. ;
  110. //
  111. $this->api->hook('compat-addModelSave',array($this->owner));
  112. //$this->owner->addSubmit('Save');
  113. return $this;
  114. }
  115. function initFilter(){
  116. $this->addFilterFields();
  117. $this->getModel()
  118. ->setQueryFields('edit_dsql') // get external fields feature, with needed joins and filtering fields
  119. ;
  120. return $this;
  121. }
  122. /**
  123. * Adds fields to a form on the basis of model definition
  124. */
  125. function addFormFields(){
  126. foreach($this->getActualFields() as $field_name=>$def){
  127. if(!is_object($def))continue;
  128. //if(!$def->visible())continue;
  129. if(!$def->editable())continue;
  130. //if($def->system()===true)continue;
  131. $this->owner->addFieldMVC($field_name);
  132. // all field's parameters and manipulations are made in MVCForm::addField()
  133. }
  134. }
  135. /**
  136. * Adds columns to a grid on the basis of model definition
  137. */
  138. function addGridFields(){
  139. foreach($this->getActualFields() as $field_name=>$def){
  140. // some field types are not required ???
  141. if(!is_object($def))continue;
  142. // we don't chck system status here, as actual fields contain fields that must be shown
  143. if($def->visible()===true && $def->datatype()!='reference_id')$this->owner->addColumnMVC($field_name);
  144. }
  145. }
  146. /**
  147. * Initialise search filter for this entity list
  148. */
  149. function addFilterFields(){
  150. foreach($this->getActualFields() as $field_name=>$def){
  151. if(!is_object($def))continue;
  152. $this->owner->addFieldMVC($field_name);
  153. }
  154. }
  155. /**
  156. * Returns Model field set
  157. */
  158. function getAllFields(){
  159. return $this->getModel()->getFields();
  160. }
  161. function getTitle(){
  162. $r=explode('_',$this->short_name);
  163. array_shift($r);
  164. return join(' ',$r);
  165. }
  166. function initLister(){
  167. $this->addGridFields();
  168. }
  169. /**
  170. * Returns the string representing the datatype of the field
  171. */
  172. function formatType($type,$object,$field=null){
  173. if($field){
  174. //$arr=$this->model->getField($field)->display();
  175. $arr=$this->getModel()->getField($field)->display();
  176. if(is_array($arr) && $arr[$object]){
  177. return $arr[$object];
  178. }
  179. }
  180. $r=$this->type_correspondence[$object][$type];
  181. if(!$r)throw new Exception_InitError("Type '$type' is not defined for $object");//$r=$type;
  182. return $r;
  183. }
  184. /**
  185. * Previously introduced in Lister, this method executes select query before
  186. * the associated View object will be rendered
  187. */
  188. function execQuery(){
  189. // default fields must be added (if not yet)
  190. if(!$this->getModel()->isFieldsSet($this->owner->name))
  191. $this->getModel()->setQueryFields($this->owner->name);
  192. $this->getModel()->dsql($this->owner->name)->do_select();
  193. }
  194. function update($data=array()){
  195. // if no data passed trying to get it from the Form that owns controller
  196. // $data will be appended to values already set with Controller::set() or Model::set()
  197. if(empty($data)&&($this->owner instanceof Form))$data=$this->owner->getAllData();
  198. $this->getModel()->update($data);
  199. return $this;
  200. }
  201. function _bindView(){
  202. // data was loaded previously
  203. // problem here, isInstanceLoaded is not defined in Controller - it's in Model.. - causing crashing
  204. if (method_exists($this, "isInstanceLoaded")){
  205. if($this->isInstanceLoaded()){
  206. /*
  207. // TODO: test and uncomment this!
  208. if($this->owner instanceof Form){
  209. if(isset($_GET['id']))$this->owner->addConditionFromGET('id');
  210. else $this->owner->addCondition('id',$id);
  211. }
  212. */
  213. if($this->owner instanceof View){
  214. $this->owner->template->set($this->get());
  215. }
  216. }
  217. }
  218. }
  219. /**
  220. * Calls assigned Model loadData() and in addition adds condition to form,
  221. * if form is the owner of this controller
  222. */
  223. function loadData($id=null,$all_fields=false){
  224. $this->getModel()->loadData($id,$all_fields);
  225. if($this->owner instanceof Form){
  226. if(isset($_GET['id']))$this->owner->addConditionFromGET('id');
  227. else $this->owner->addCondition('id',$id);
  228. }
  229. if($this->owner instanceof View){
  230. $this->owner->template->set($this->get());
  231. }
  232. return $this;
  233. }
  234. /**
  235. * Set list of fields which should be displayed by grid or quickedit
  236. */
  237. public function setActualFields($actual_fields){
  238. $this->getModel()->setActualFields($actual_fields);
  239. return $this;
  240. }
  241. /**
  242. * This method used by admin system
  243. * Returns the assoc array of extra action to be added to entity lister near Add button,
  244. * so the core could render entity lister automatically w/o additional page class creation
  245. * No implementation here for the actions listed, all functionality is implemented in
  246. * corresponding page class
  247. * @return false or array($href=>$title), where $href is valid URL in AModules3 style
  248. */
  249. public function getExtraActions(){
  250. return false;
  251. }
  252. /**
  253. * Generates user-friendly string of related entities
  254. * @param array $data entity hash as it returned from Model_Table::getRelatedEntities()
  255. * @return string
  256. */
  257. public function formatRelatedEntities($data){
  258. $result=array();
  259. foreach($data as $entity=>$count){
  260. switch($entity){
  261. case 'docspec':
  262. $name='document line';
  263. break;
  264. case 'timesheet':
  265. $name='timesheet entry';
  266. break;
  267. case 'fixed_asset':
  268. $name='fixed asset';
  269. break;
  270. default:
  271. $name=$entity;
  272. }
  273. $result[]=$count." $name".($count==1?'':'s');
  274. }
  275. return join(', ',$result);
  276. }
  277. public function countRelatedEntities($data){
  278. $result=0;
  279. foreach($data as $count)$result+=$count;
  280. return $result;
  281. }
  282. function __toString(){
  283. return $this->getModel()->__toString();
  284. }
  285. }