PageRenderTime 42ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/webphp/lib/recordsettable.php

http://webpy-php-port.googlecode.com/
PHP | 421 lines | 215 code | 69 blank | 137 comment | 33 complexity | eada2a396c67bc3bab8f430ae8c29cf7 MD5 | raw file
  1. <?php
  2. /**
  3. * RecordSetTable
  4. */
  5. class RecordSetTable
  6. {
  7. protected $RecordSetPager;
  8. private $rs;
  9. private $show_record_count = true;
  10. private $fields_to_hide = array();
  11. private $header_names = array();
  12. private $actions = array();
  13. private $primary_key = false;
  14. private $rs_callback = false;
  15. private $escape_html = true;
  16. private $max_download_rows = 1000; // max no of rows to download
  17. private $num_block_rows = 20; // number of rows for rstohtml
  18. private $no_escape_fields = array(); // fields you do not want to htmlspecialchars
  19. //private $sortable_columns = false;
  20. function __construct(RecordSetPager $RecordSetPager)
  21. {
  22. $this->RecordSetPager = $RecordSetPager;
  23. $this->num_block_rows = $RecordSetPager->rows;
  24. }
  25. /**
  26. * show or hide record count at bottom
  27. *
  28. * @param string $onoff
  29. * @return void
  30. * @author Kenrick Buchanan
  31. */
  32. function showRecordCount($onoff = true)
  33. {
  34. $this->show_record_count = $onoff;
  35. }
  36. /**
  37. * set num of rows to download
  38. *
  39. * @param string $num
  40. * @return void
  41. * @author Kenrick Buchanan
  42. */
  43. function setMaxDownloadRows($num)
  44. {
  45. $this->max_download_rows = $num;
  46. }
  47. /**
  48. * set a function to be used on escaping fields upon display
  49. * by defaults uses htmlspecialchars
  50. *
  51. * @param string $escape_function
  52. * @return void
  53. * @author Kenrick Buchanan
  54. */
  55. function escapeHtml($onoff=true)
  56. {
  57. $this->escape_html = $onoff;
  58. }
  59. /**
  60. * set which fields to not run htmlspecialchars on
  61. *
  62. * @param array $fields
  63. * @return void
  64. * @author Kenrick Buchanan
  65. */
  66. function setNoEscape(array $fields)
  67. {
  68. $this->no_escape_fields = $fields;
  69. }
  70. /**
  71. * use this function to hide certain fields from becoming
  72. * columns in the table
  73. *
  74. * @param string $array
  75. * @return void
  76. * @author Kenrick Buchanan
  77. */
  78. function hideFields(array $fields)
  79. {
  80. $this->fields_to_hide = $fields;
  81. }
  82. /**
  83. * in case it is a pain to alias your SQL and give nice names
  84. * you can achieve the same thing here:
  85. * array('sql key name' => 'new header name');
  86. * array('created' => 'Time Form Submitted');
  87. *
  88. * @param string $array
  89. * @return void
  90. * @author Kenrick Buchanan
  91. */
  92. function humanHeaders(array $headers)
  93. {
  94. $this->header_names = $headers;
  95. }
  96. /**
  97. * specify a function to be called on each row.
  98. *
  99. * @param string $callback
  100. * @return void
  101. * @author Kenrick Buchanan
  102. */
  103. function setCallback($callback)
  104. {
  105. $this->rs_callback = $callback;
  106. }
  107. /**
  108. * call RecordSetPager's method to gen the records
  109. *
  110. * @author Kenrick Buchanan
  111. */
  112. protected function getRecords()
  113. {
  114. $this->rs = $this->RecordSetPager->getRecords();
  115. }
  116. /**
  117. * set the primary key for the action forms
  118. *
  119. * @param string $key
  120. * @return void
  121. * @author Kenrick Buchanan
  122. */
  123. function setPrimaryKey($key)
  124. {
  125. $this->primary_key = $key;
  126. }
  127. /**
  128. * if there are actions, new cell on the row is created
  129. * where in a form is created with a submit button
  130. * if their is not a primary key set for the record set
  131. * the actions will not be rendered. the primary key can be
  132. * singular or an array, and it will be written as hidden
  133. * fields in this form
  134. *
  135. * @param string $type
  136. * @param string $action
  137. * @param string $method
  138. * @return void
  139. * @author Kenrick Buchanan
  140. */
  141. public function setAction($type, $action, $method='get')
  142. {
  143. $this->actions[$type] = array('action' => $action,
  144. 'method' => $method);
  145. }
  146. /**
  147. * write the forms to the table row
  148. *
  149. * @param string $rs
  150. * @param string $rowid
  151. * @return $s string html
  152. * @author Kenrick Buchanan
  153. */
  154. function writeActions($fields)
  155. {
  156. $s = '';
  157. if(!empty($this->actions)){
  158. foreach($this->actions as $k=>$v){
  159. $class = 'submit';
  160. $onclick = '';
  161. $method = $v['method'];
  162. if ( strcasecmp(strtolower($k),'delete') == 0 )
  163. {
  164. $class = 'submit_delete';
  165. $onclick = "onclick=\"return confirm('Are you sure you want to delete this?');\"";
  166. $method = 'post';
  167. }
  168. $s .="<form method='$method' action='{$v['action']}' style='display:inline'>";
  169. if(!empty($this->primary_key)){
  170. if(is_array($this->primary_key)){
  171. foreach($this->primary_key as $key){
  172. $s .= "<input type='hidden' name='$key' value='{$fields[$key]}' />";
  173. }
  174. } else {
  175. $s .= "<input type='hidden' name='{$this->primary_key}' value='".$fields[$this->primary_key]."' />";
  176. }
  177. }
  178. $s .= "<input type='submit' name='submit' value='$k' class='$class' $onclick /></form>";
  179. }
  180. }
  181. return $s;
  182. }
  183. /**
  184. * render an HTML table
  185. * most of this was ripped from adodb_pager, but made
  186. * for my tastes.
  187. *
  188. * @return string $html table
  189. * @author Kenrick Buchanan
  190. */
  191. private function renderTable()
  192. {
  193. $s = '';
  194. $rows = 0;
  195. $temphdr = '';
  196. if (!$this->rs) {
  197. throw new Exception("Bad recordset given to ".__CLASS__);
  198. return false;
  199. }
  200. $rowclass = array('at-row0','at-row1');
  201. $rowcounter = 0;
  202. $typearr = array();
  203. $ncols = $this->rs->FieldCount();
  204. // write column headers
  205. $temp_col_attribute = array();
  206. #$col_sort_options = array();
  207. for ($i=0; $i < $ncols; $i++) {
  208. $field = $this->rs->FetchField($i);
  209. if(!empty($this->fields_to_hide)){
  210. if(in_array($field->name, $this->fields_to_hide)) continue; // move to next iteration
  211. }
  212. // get meta type of column
  213. $typearr[$i] = $this->rs->MetaType($field->type,$field->max_length);
  214. // rename headers using header_names
  215. if (isset($this->header_names[$field->name])){
  216. $fname = $this->header_names[$field->name];
  217. }else{
  218. $fname = htmlspecialchars($field->name);
  219. }
  220. if (strlen($fname)==0) $fname = '';
  221. // sorting
  222. /*
  223. if ($this->sortable_columns) {
  224. if (in_array($field->name, $this->sortable_columns)) {
  225. $_GET['sort_by'] = htmlspecialchars($field->name);
  226. $_GET['dir'] =
  227. $fname = "<a href=\"\">$fname</a>";
  228. }
  229. }
  230. */
  231. $temp_col_attribute[] = '<col />';
  232. $temphdr .= "<td>$fname</td>\n";
  233. }
  234. if(!empty($this->actions)){
  235. #$col_sort_options[] = 'None';
  236. $temphdr .= "<td>Actions</td>\n";
  237. }
  238. $html = "<table class='at-table'>".
  239. implode("\n",$temp_col_attribute).
  240. "<thead><tr>$temphdr</tr></thead>\n";
  241. // smart algorithm - handles ADODB_FETCH_MODE's correctly by probing...
  242. $numoffset = isset($this->rs->fields[0]) || isset($this->rs->fields[1]) || isset($this->rs->fields[2]);
  243. $idcounter = 1;
  244. while (!$this->rs->EOF) {
  245. $myrowclass = $rowclass[$rowcounter];
  246. $rowcounter = 1 - $rowcounter;
  247. $rowid = "at-{$idcounter}";
  248. $s .= "\n<tr class='$myrowclass' id='$rowid'>\n";
  249. // user defined Call back function
  250. if($this->rs_callback){
  251. call_user_func_array($this->rs_callback, array(&$this->rs->fields));
  252. }
  253. for ($i=0; $i < $ncols; $i++) {
  254. if ($i===0) {
  255. $v = ($numoffset) ? $this->rs->fields[0] : reset($this->rs->fields);
  256. } else {
  257. $v = ($numoffset) ? $this->rs->fields[$i] : next($this->rs->fields);
  258. }
  259. // skip ones to be hidden
  260. $field = $this->rs->FetchField($i);
  261. if(!empty($this->fields_to_hide)){
  262. if(in_array($field->name, $this->fields_to_hide)) continue;
  263. }
  264. $type = isset($typearr[$i]) ? $typearr[$i] : '';
  265. $fieldval = '';
  266. switch($type) {
  267. case 'D':
  268. if (!strpos($v,':')) {
  269. $fieldval = $this->rs->UserDate($v,"Y-m-d");
  270. break;
  271. }
  272. case 'T':
  273. $fieldval = $this->rs->UserTimeStamp($v,"Y-m-d h:i:s");
  274. break;
  275. case 'I':
  276. case 'N':
  277. $fieldval = trim($v);
  278. break;
  279. default:
  280. $v = trim($v);
  281. // call user defined escape function
  282. if ($this->escape_html) {
  283. if (!in_array($field->name, $this->no_escape_fields)) {
  284. $v = htmlspecialchars($v, ENT_QUOTES);
  285. }
  286. }
  287. if (strlen($v) == 0) $v = '';
  288. $fieldval = $v;
  289. }
  290. $s .= "<td>$fieldval</td>\n";
  291. } // for
  292. // actions
  293. if(!empty($this->actions)){
  294. $s .= "<td nowrap='nowrap' width='1%'>".$this->writeActions($this->rs->fields)."</td>";
  295. }
  296. $s .= "</tr>\n";
  297. $rows += 1;
  298. if ($rows >= $this->max_download_rows) {
  299. $rows = "<p>Truncated at {$this->max_download_rows}</p>";
  300. break;
  301. } // switch
  302. $this->rs->MoveNext();
  303. // additional EOF check to prevent a widow header
  304. if (!$this->rs->EOF && $rows % $this->num_block_rows == 0) {
  305. $html .= "<tbody>\n".$s."</tbody>\n</table>\n\n";
  306. $s = $hdr;
  307. }
  308. $idcounter++;
  309. } // while
  310. $html .= "<tbody>\n".$s."</tbody>\n</table>\n\n";
  311. if ($this->show_record_count) $html .= "<h2 class='at-rows'>".$this->RecordSetPager->totalRows()." Rows</h2>";
  312. return $html;
  313. }
  314. function __toString()
  315. {
  316. try {
  317. $this->getRecords();
  318. } catch (Exception $e) {
  319. return $e->getMessage();
  320. }
  321. $header = $this->RecordSetPager->navigation();
  322. $footer = $this->RecordSetPager->pageCount().' '.$header;
  323. $grid = $this->renderTable();
  324. ob_start();
  325. echo "<div class='at-container'><div class='at-header'>",
  326. $header,
  327. "</div>",
  328. $grid,
  329. "<div class='at-footer'>",
  330. $footer,
  331. "</div></div>\n";
  332. $table = ob_get_contents();
  333. ob_end_clean();
  334. return $table;
  335. }
  336. /**
  337. * sortableColumns
  338. * needs to be an array of the SQL columns according to
  339. * your SQL statement that you want to order by
  340. *
  341. * @param array $sortable array of headers you want to be able to sort by
  342. * @return void
  343. * @author Kenrick Buchanan
  344. */
  345. /*
  346. function sortableColumns(array $sortable)
  347. {
  348. if (empty($sortable)) return;
  349. $this->sortable_columns = $sortable;
  350. }
  351. */
  352. }