PageRenderTime 56ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/scaffolding/libraries/Scaffolding.php

https://github.com/MHordecki/milionkostek
PHP | 506 lines | 396 code | 84 blank | 26 comment | 37 complexity | 0922fe697d397021c70348a2f74f1375 MD5 | raw file
  1. <?php
  2. class Scaffolding_Core
  3. {
  4. // Model object that needs to be scaffolded.
  5. protected $model;
  6. protected $session;
  7. protected $db;
  8. protected $inspector;
  9. //protected $contr;
  10. protected $columns;
  11. // from class User_Model:
  12. protected $tablename=''; // users
  13. protected $prettyname=''; // User
  14. protected $prettyplural=''; // Users
  15. protected $tableplurar=''; // users
  16. protected $base; //base url
  17. function __construct(&$model)
  18. {
  19. $this->model=&$model;
  20. // $this->contr=&$controller;
  21. $t=Model_Inspect::byModel(get_class($model));
  22. //$t=new Model_Inspector($model);
  23. $this->db=new Database();
  24. $this->session=new Session();
  25. $this->base=url::base(TRUE).url::current().'/';
  26. $this->tablename = inflector::plural(strtolower(substr(get_class($this->model),0,strpos(get_class($this->model),'_Model'))));
  27. $this->prettyname = ucfirst(inflector::singular($this->tablename));
  28. $this->prettyplural = inflector::plural($this->prettyname);
  29. $this->tableplural=strtolower($this->prettyplural);
  30. $this->inspector=new Model_Inspector($model);
  31. $this->columns=$this->inspector->inspect();
  32. }
  33. public function scaffold($args)
  34. {
  35. if(count($args)==0)
  36. return $this->_index();
  37. switch($args[0])
  38. {
  39. case 'manage':
  40. return $this->_manage();
  41. break;
  42. case 'addnew':
  43. return $this->_addnew($args);
  44. break;
  45. case 'edit':
  46. return $this->_edit($args);
  47. break;
  48. case 'delete':
  49. return $this->_delete($args);
  50. break;
  51. case 'relationship':
  52. return $this->_relationship($args,false,false);
  53. break;
  54. case 'relationshiphabtm':
  55. return $this->_relationship($args);
  56. break;
  57. case 'relationshiphabtmdelete':
  58. return $this->_relationshipdelete($args,TRUE);
  59. break;
  60. case 'relationshipdelete':
  61. return $this->_relationshipdelete($args);
  62. break;
  63. default:
  64. return $this->_index();
  65. break;
  66. }
  67. }
  68. protected function _index()
  69. {
  70. $ret='<h1>'.$this->prettyplural.' management</h1><p> Welcome to managment page for '.$this->tablename.' table.Choose your action:</p>
  71. <p>
  72. <ul>
  73. <li><a href="'.$this->base.'manage">Manage '.$this->tableplural.'</a></li>
  74. <li><a href="'.$this->base.'addnew">Add new '.inflector::singular($this->tableplural).'</a></li>
  75. ';
  76. return $ret;
  77. }
  78. protected function getOption($col,$key)
  79. {
  80. if(!array_key_exists('options',$col))
  81. return false;
  82. if(!array_key_exists($key,$col['options']))
  83. return false;
  84. return $col['options'][$key];
  85. }
  86. protected function _manage()
  87. {
  88. // Initial
  89. $this->base=explode('manage',$this->base);
  90. $this->base=$this->base[0];
  91. $db = new Database;
  92. $count = $db->count_records($this->tablename);
  93. $pag = new Pagination(array(
  94. // 'base_url' => 'welcome/pagination_example/page/', // base_url will default to current uri
  95. 'uri_segment' => 'manage', // pass a string as uri_segment to trigger former 'label' functionality
  96. 'total_items' => $count, // use db count query here of course
  97. 'items_per_page' => 50, // it may be handy to set defaults for stuff like this in config/pagination.php
  98. 'style' => 'digg' // pick one from: classic (default), digg, extended, punbb, or add your own!
  99. ));
  100. $ret='<h1>'.$this->prettyplural.' management</h1><a href="'.$this->base.'">Back to the management page.</a><br/><p> Here you can view and edit existing '.$this->tableplural.'.</p>';
  101. $ret.=(string) $pag;
  102. $ret.='<table border="1"><tr>';
  103. //Columns headers
  104. $columns=array();
  105. foreach($this->columns as $column)
  106. {
  107. if($this->getOption($column,'hide'))
  108. {
  109. continue;
  110. }
  111. $ret.='<th>'.$column['name'].'</th>';
  112. $columns[]=$column[0];
  113. }
  114. $ret.='<th>Edit</th><th>Delete</th></tr>';
  115. //Get rows
  116. $db = new Database();
  117. $result=$this->inspector->getList(Query::query($db)->limit(50)->offset($pag->sql_offset));
  118. //Rows processing
  119. foreach($result as $row)
  120. {
  121. $ret.='<tr>';
  122. foreach($columns as $col)
  123. {
  124. if($this->getOption($this->columns[$col],'hide'))
  125. continue;
  126. $ret.='<td>';
  127. if(strpos($this->columns[$col][1],'relationship')===0)
  128. {
  129. if($this->columns[$col][1]=='relationship_has_and_belongs_to_many')
  130. {
  131. $ret.='<a href="'.$this->base.'relationshiphabtm/'.$row['id'].'/'.$this->columns[$col]['has_and_belongs_to_many'].'">A total of '.$row[$col].'</a></td>';
  132. }
  133. else
  134. $ret.='<a href="'.$this->base.'relationship/'.$row['id'].'/'.$this->columns[$col]['has_many'].'">A total of '.$row[$col].'</a></td>';
  135. continue;
  136. }
  137. if(strlen($row[$col])>50)
  138. $ret.=substr($row[$col],0,47).'<b>...</b>';
  139. else
  140. $ret.=$row[$col];
  141. $ret.='</td>';
  142. }
  143. $ret.='<td><a href="'.$this->base.'edit/'.$row['id'].'">E</a></td>';
  144. $ret.='<td><a href="'.$this->base.'delete/'.$row['id'].'">X</a></td></tr>';
  145. }
  146. $ret.="</table>";
  147. return $ret;
  148. }
  149. protected function Col2Field($col,&$form)
  150. {
  151. if($col[0]=='id')
  152. {
  153. return $form->hidden('_id');
  154. }
  155. if($l=$this->getOption($col,'load'))
  156. {
  157. var_dump($l);
  158. }
  159. switch($col[1])
  160. {
  161. case 'varchar':
  162. return $form->input('_'.$col[0]);
  163. break;
  164. case 'text':
  165. return $form->textarea('_'.$col[0])->rows(6)->cols(35);
  166. break;
  167. case 'foreign':
  168. return $form->dropdown('_'.$col[0]);
  169. break;
  170. default:
  171. return $form->input('_'.$col[0]);
  172. break;
  173. }
  174. }
  175. protected function Fieldval2Dbval(&$field,$col)
  176. {
  177. switch($col[1])
  178. {
  179. case 'text':
  180. return implode("\r\n",explode("\n",$field->value));
  181. break;
  182. default:
  183. return $field->value;
  184. break;
  185. }
  186. }
  187. protected function Dbval2Fieldval(&$field,$col,$value=false)
  188. {
  189. switch($col[1])
  190. {
  191. case 'foreign':
  192. $in=Model_Inspect::byTable($col['foreign']);
  193. $res=$in->getKeyList(new Query(new Database));
  194. $opts=array();
  195. $selected=false;
  196. foreach($res as $val)
  197. {
  198. $opts[$val['id']]=$val['_key'];
  199. if($val['_key']==$value) $selected=$val['id'];
  200. }
  201. $field ->options($opts);
  202. if($selected)
  203. $field->selected($selected);
  204. break;
  205. default:
  206. if($value)
  207. $field->value($value);
  208. else
  209. $field->value('');
  210. break;
  211. }
  212. }
  213. protected function _delete($args)
  214. {
  215. //Initial
  216. $this->base=explode('delete',$this->base);
  217. $this->base=$this->base[0];
  218. $db = new Database();
  219. $db->delete($this->tablename,array('id'=>$args[1]));
  220. url::redirect($this->base.'manage');
  221. }
  222. protected function _edit($args)
  223. {
  224. //Initial
  225. $this->base=explode('edit',$this->base);
  226. $this->base=$this->base[0];
  227. //Get result
  228. $qr=new Query(new Database());
  229. $qr->where($this->tablename.'.id',$args[1]);
  230. $result=$this->inspector->getOne($qr);
  231. if(count($result)==0)
  232. return 'This record does not exist.';
  233. $result=$result[0];
  234. //More initial stuff
  235. $ret='<h1>Editing '.strtolower($this->prettyname).' '.$result['_keyfield'].'</h1><a href="'.$this->base.'manage">Back to the '.$this->tableplural.' list .</a><p>';
  236. $form=new Forge(NULL,'');
  237. //Get fields and their values
  238. foreach($this->columns as $col)
  239. {
  240. if($this->getOption($col,'hide_edit'))
  241. continue;
  242. if(strpos($col[1],'relationship_')===0) continue;
  243. $field=$this->Col2Field($col,$form);
  244. $this->Dbval2Fieldval($field,$col,$result[$col[0]]);
  245. $field->label($col['name']);
  246. }
  247. $form->submit('Submit');
  248. //Process input
  249. if($form->validate())
  250. {
  251. $updates=array();
  252. foreach($this->columns as $col)
  253. {
  254. if($this->getOption($col,'hide_edit'))
  255. continue;
  256. //Get actual db value
  257. if(strpos($col[1],'relationship_')===0) continue;
  258. $formfield='_'.$col[0];
  259. $formfield=$form->$formfield;
  260. if($col[1]=='foreign')
  261. {
  262. $dbvalue=$result['_inspector_'.$col[0]];
  263. }
  264. else
  265. $dbvalue=$result[$col[0]];
  266. //Get actual field value
  267. $formfield=$this->Fieldval2Dbval($formfield,$col);
  268. //Check whether needs to be updated
  269. if($formfield!=$dbvalue)
  270. {
  271. if($sav=$this->getOption($col,'save'))
  272. {
  273. $formfield=call_user_func($sav,$formfield);
  274. }
  275. $updates[$col[0]]=$formfield;
  276. }
  277. }
  278. //Run sql query
  279. if(count($updates)>0)
  280. {
  281. $db=new Database();
  282. if( $db->update($this->tablename,$updates,array($this->tablename.'.id' => $args[1])))
  283. Message::add('Data changed successfully.');
  284. else
  285. Message::add('There was an error in the processing.');
  286. }
  287. }
  288. return $ret.$form->render().'</p>';
  289. }
  290. protected function _addnew($args)
  291. {
  292. $this->base=explode('addnew',$this->base);
  293. $this->base=$this->base[0];
  294. $ret='<h1>Adding new '.strtolower($this->prettyname).'</h1><a href="'.$this->base.'">Back to the management page.</a><p>';
  295. $form=new Forge(NULL,'');
  296. foreach($this->columns as $col)
  297. {
  298. if($this->getOption($col,'hide_edit'))
  299. continue;
  300. $field=$this->Col2Field($col,$form);
  301. $this->Dbval2Fieldval($field,$col);
  302. $field->label($col['name']);
  303. }
  304. $form->submit('Submit');
  305. if($form->validate())
  306. {
  307. $inserts=array();
  308. foreach($this->columns as $col)
  309. {
  310. if($this->getOption($col,'hide_edit'))
  311. continue;
  312. $formfield='_'.$col[0];
  313. $formfield=$form->$formfield;
  314. $formfield=$this->Fieldval2Dbval($formfield,$col);
  315. if($formfield!='')
  316. {
  317. if($sav=$this->getOption($col,'save'))
  318. {
  319. $formfield=call_user_func($sav,$formfield);
  320. }
  321. $inserts[$col[0]]=$formfield;
  322. }
  323. }
  324. if(count($inserts)>0)
  325. {
  326. $db=new Database();
  327. if($db->insert($this->tablename,$inserts))
  328. Message::add('Data changed successfully.');
  329. else
  330. Message::add('There was an error in the processing.');
  331. }
  332. }
  333. return $ret.$form->render().'</p>';
  334. }
  335. protected function _relationship($args,$del=true,$add=true)
  336. {
  337. //Initial
  338. $this->base=explode('relationship',$this->base);
  339. $this->base=$this->base[0];
  340. $roles=array();
  341. //Get result
  342. $result=$this->inspector->getRelated(new Query(new Database()),$args[1],$args[2]);
  343. $ret='<h1>Editing relationships of '.strtolower($this->prettyname).'</h1><a href="'.$this->base.'manage">Back to the '.$this->tableplural.' list .</a><p>';
  344. if(count($result)==0)
  345. {
  346. $ret.='This relationship is empty.<br/>';
  347. }else
  348. {
  349. //More initial stuff
  350. $relname=Model_Inspect::byTable($args[2])->getKeyField();
  351. $relname=$relname['name'];
  352. $ret.='<table border="1"><tr><th>Id</th><th>'.$relname.'</th>'.($del ? '<th>Delete</th>' : '').'</tr>';
  353. $id=1;
  354. foreach($result as $row)
  355. {
  356. $ret.='<tr><td>'.($id++).'</td><td>'.$row['name'].'</td>'.($del ? '<td><a href="'.$this->base.'relationship'.($del ? 'habtm':'').'delete/'.$args[1].'/'.$args[2].'/'.$row['id'].'">X</a>':'').'</tr>';
  357. $roles[]=$row['id'];
  358. }
  359. $ret.='</table>';
  360. }
  361. $ret.='</p>';
  362. if($add)
  363. {
  364. $ret.='<br/><h2>Add new relationship</h2><p>';
  365. $form=new Forge();
  366. $field=$form->dropdown('_'.$args[2]);
  367. //Fooling Dbval2Fieldval
  368. $col=array();
  369. $col[1]='foreign';
  370. $col['foreign']=$args[2];
  371. $this->Dbval2Fieldval($field,$col);
  372. $form->submit('Submit');
  373. if($form->validate())
  374. {
  375. var_dump($field->value);
  376. if(in_array($field->value,$roles))
  377. {
  378. Message::add('This relationship is present.');
  379. } else
  380. {
  381. $tabrel=$this->tablename.'_'.$args[2];
  382. $db=new Database();
  383. $db->insert($tabrel,array(
  384. substr($this->tablename,0,-1).'_id'=>$args[1],
  385. substr($args[2],0,-1).'_id'=>$field->value
  386. ));
  387. Message::add_flash('Relationship has been added.');
  388. if($del and $add)
  389. url::redirect($this->base.'relationshiphabtm/'.$args[1].'/'.$args[2]);
  390. else
  391. url::redirect($this->base.'relationship/'.$args[1].'/'.$args[2]);
  392. }
  393. }
  394. }
  395. return $ret.(isset($form) ? $form->render() : '');
  396. }
  397. protected function _relationshipdelete($args,$habtm=false)
  398. {
  399. //Initial
  400. $this->base=explode('relationshipdelete',$this->base);
  401. $this->base=$this->base[0];
  402. $tabrel=$this->tablename.'_'.$args[2];
  403. //Get result
  404. $db=new Database();
  405. $db->delete($tabrel,
  406. array(
  407. $tabrel.'.'.substr($this->tablename,0,-1).'_id' => $args[1],
  408. $tabrel.'.'.substr($args[2],0,-1).'_id' => $args[3]
  409. ));
  410. Message::add_flash('Relationship has been deleted.');
  411. if($habtm)
  412. {
  413. $this->base=explode('relationshiphabtmdelete',$this->base);
  414. $this->base=$this->base[0];
  415. url::redirect($this->base.'relationshiphabtm/'.$args[1].'/'.$args[2]);
  416. }
  417. else
  418. url::redirect($this->base.'relationship/'.$args[1].'/'.$args[2]);
  419. }
  420. }