PageRenderTime 53ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/forms/table.php

https://github.com/PorteroGCooper/zoop-helios
PHP | 643 lines | 403 code | 33 blank | 207 comment | 74 complexity | ec17bb1843b322d7129b8ff7f37f52ed MD5 | raw file
Possible License(s): LGPL-2.1
  1. <?php
  2. /**
  3. * @category zoop
  4. * @package forms
  5. */
  6. // Copyright (c) 2008 Supernerd LLC and Contributors.
  7. // All Rights Reserved.
  8. //
  9. // This software is subject to the provisions of the Zope Public License,
  10. // Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
  11. // THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
  12. // WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  13. // WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
  14. // FOR A PARTICULAR PURPOSE.
  15. /**
  16. * table
  17. *
  18. * @package
  19. * @version $id$
  20. * @copyright 1997-2008 Supernerd LLC
  21. * @author Steve Francia <steve.francia+zoop@gmail.com>
  22. * @license Zope Public License (ZPL) Version 2.1 {@link http://zoopframework.com/license}
  23. */
  24. class table
  25. {
  26. /**
  27. * idfield
  28. *
  29. * @var mixed
  30. * @access public
  31. */
  32. var $idfield;
  33. /**
  34. * name
  35. *
  36. * @var mixed
  37. * @access public
  38. */
  39. var $name;
  40. /**
  41. * dbconnname
  42. *
  43. * @var mixed
  44. * @access public
  45. */
  46. var $dbconnname;
  47. /**
  48. * sequence
  49. *
  50. * @var mixed
  51. * @access public
  52. */
  53. var $sequence;
  54. /**
  55. * listlink
  56. *
  57. * @var string
  58. * @access public
  59. */
  60. var $listlink = "edit";
  61. /**
  62. * zone
  63. *
  64. * @var string
  65. * @access public
  66. */
  67. var $zone = "default";
  68. /**
  69. * id_location
  70. *
  71. * @var string
  72. * @access public
  73. */
  74. var $id_location = "page"; // can be page or zone
  75. /**
  76. * fields
  77. *
  78. * @var mixed
  79. * @access public
  80. */
  81. var $fields;
  82. /**
  83. * records
  84. *
  85. * @var mixed
  86. * @access public
  87. */
  88. var $records;
  89. /**
  90. * limit
  91. *
  92. * @var float
  93. * @access public
  94. */
  95. var $limit = 25; # LIMIT OF -1 GIVES YOU ALL THE RECORDS
  96. /**
  97. * cur
  98. *
  99. * @var float
  100. * @access public
  101. */
  102. var $cur = 0;
  103. /**
  104. * total
  105. *
  106. * @var mixed
  107. * @access public
  108. */
  109. var $total;
  110. /**
  111. * pages
  112. *
  113. * @var mixed
  114. * @access public
  115. */
  116. var $pages;
  117. /**
  118. * sort
  119. *
  120. * @var mixed
  121. * @access public
  122. */
  123. var $sort;
  124. /**
  125. * direction
  126. *
  127. * @var string
  128. * @access public
  129. */
  130. var $direction = "ASC";
  131. /**
  132. * deleteColumn
  133. *
  134. * @var float
  135. * @access public
  136. */
  137. var $deleteColumn = 0;
  138. /**
  139. * deletelink
  140. *
  141. * @var string
  142. * @access public
  143. */
  144. var $deletelink = "delete";
  145. /**
  146. * deletefield
  147. *
  148. * @var string
  149. * @access public
  150. */
  151. var $deletefield = "deleted";
  152. /**
  153. * wherestr
  154. *
  155. * @var string
  156. * @access public
  157. */
  158. var $wherestr = "";
  159. /**
  160. * order
  161. *
  162. * @var array
  163. * @access public
  164. */
  165. var $order = array();
  166. /**
  167. * search
  168. *
  169. * @var string
  170. * @access public
  171. */
  172. var $search = array("type" => "all", "value" => null, "field" => null, "wherestr" => null);
  173. /**
  174. * sql
  175. *
  176. * @var string
  177. * @access public
  178. */
  179. var $sql = "";
  180. // type can be individual or all or advanced
  181. /**
  182. * table
  183. *
  184. * @param mixed $table
  185. * @param mixed $dbconnname
  186. * @access public
  187. * @return void
  188. */
  189. function table($table, $dbconnname)
  190. {
  191. $this->name = $table;
  192. $this->dbconnname = $dbconnname;
  193. global $$dbconnname;
  194. $dbname = $$dbconnname->dsn['database'];
  195. if (APP_STATUS == 'live' && $tablecache = zcache::getData($table, array('base'=> 'forms/processed_table_info/', 'group' => $dbname)))
  196. {
  197. $this->fields = $tablecache->fields;
  198. $this->idfield = $tablecache->idfield;
  199. $this->sequence = $tablecache->sequence;
  200. $this->order = $tablecache->order;
  201. }
  202. else
  203. {
  204. $result = $$dbconnname->get_table_info($table);
  205. foreach($result as $field)
  206. {
  207. $fieldname = $field["name"];
  208. $this->fields[$fieldname] = new field($field, $dbconnname);
  209. if (strstr($field["flags"], "primary_key"))
  210. {
  211. $this->idfield = $field["name"];
  212. $this->fields[$fieldname]->formshow = 0;
  213. $this->fields[$fieldname]->listshow = 1;
  214. $this->fields[$fieldname]->clickable = 1;
  215. }
  216. //the first is for more modern postgres. the second for older postgres...
  217. if (preg_match('/.*?default_nextval%28(.*?)%29\\s.*/i', $field["flags"], $regs) ||
  218. preg_match('/.*?default_nextval.*?public.(.*?)%29\\s.*/i', $field["flags"], $regs))
  219. {
  220. $this->sequence = $regs[1];
  221. }
  222. if (strstr($field["flags"], "not_null"))
  223. $this->fields[$fieldname]->required = true;
  224. $this->fields[$fieldname]->length = $field["len"];
  225. $this->fields[$fieldname]->label = ucwords(strtolower(strtr($this->fields[$fieldname]->name,"_", " ")));
  226. switch(true)
  227. {
  228. case strstr($field["type"], "int"):
  229. $this->fields[$fieldname]->datatype = "numeric";
  230. $this->fields[$fieldname]->html['type'] = "text";
  231. $this->fields[$fieldname]->validation['type'] = "numeric";
  232. $this->fields[$fieldname]->search["type"] = "exact";
  233. break;
  234. case strstr($field["type"], "string"):
  235. $this->fields[$fieldname]->datatype = "text";
  236. $this->fields[$fieldname]->html['type'] = "text";
  237. $this->fields[$fieldname]->search["type"] = "contains";
  238. break;
  239. case strstr($field["type"], "blob"):
  240. $this->fields[$fieldname]->datatype = "text";
  241. $this->fields[$fieldname]->html['type'] = "text";
  242. $this->fields[$fieldname]->search["type"] = "contains";
  243. break;
  244. case strstr($field["type"], "date"):
  245. $this->fields[$fieldname]->datatype = "date";
  246. $this->fields[$fieldname]->html['type'] = "date";
  247. $this->fields[$fieldname]->search["type"] = "range";
  248. break;
  249. }
  250. $this->order[] = $fieldname;
  251. }
  252. $tmpobj->fields = &$this->fields;
  253. $tmpobj->idfield = &$this->idfield;
  254. $tmpobj->sequence = &$this->sequence;
  255. $tmpobj->order = &$this->order;
  256. zcache::cacheData($table, $tmpobj, array('base'=> 'forms/processed_table_info/', 'group' => $dbname));
  257. }
  258. }
  259. /**
  260. * searchClear
  261. *
  262. * @access public
  263. * @return void
  264. */
  265. function searchClear()
  266. {
  267. unset($this->search["value"]);
  268. unset($this->search["field"]);
  269. unset($this->search["wherestr"]);
  270. $this->setAll("search['value']", null);
  271. $this->setAll("search['value_min']", null);
  272. $this->setAll("search['value_max']", null);
  273. }
  274. /**
  275. * setDbconnname
  276. *
  277. * @param mixed $dbconnname
  278. * @access public
  279. * @return void
  280. */
  281. function setDbconnname($dbconnname)
  282. {
  283. $this->dbconnname = $dbconnname;
  284. }
  285. /**
  286. * setAll
  287. *
  288. * @param mixed $param
  289. * @param mixed $val
  290. * @access public
  291. * @return void
  292. */
  293. function setAll($param, $val)
  294. {
  295. if (isset($this->fields))
  296. {
  297. foreach ($this->fields as $field)
  298. {
  299. if (isset($this->fields[$field->name]->$param))
  300. $this->fields[$field->name]->$param = $val;
  301. }
  302. }
  303. }
  304. /**
  305. * getTotal
  306. *
  307. * @access public
  308. * @return void
  309. */
  310. function getTotal()
  311. {
  312. $dbconnname = $this->dbconnname;
  313. global $$dbconnname;
  314. if (!$this->wherestr)
  315. $this->setupRequirements();
  316. $this->total = $$dbconnname->fetch_one_cell("SELECT COUNT(*) FROM $this->name $this->wherestr");
  317. if (is_numeric($this->limit))
  318. $this->pages = ceil($this->total / $this->limit);
  319. else
  320. $this->pages = 0;
  321. }
  322. /**
  323. * setupEnv
  324. *
  325. * @param mixed $get
  326. * @access public
  327. * @return void
  328. */
  329. function setupEnv($get)
  330. {
  331. if (isset($get["sort"]))
  332. {
  333. $this->sort = $get["sort"];
  334. if (!isset($this->fields[$this->sort]))
  335. $this->sort = $this->idfield;
  336. }
  337. else
  338. {
  339. if (!isset($this->fields[$this->sort]))
  340. $this->sort = $this->idfield;
  341. }
  342. if (isset($get["dir"]))
  343. {
  344. if ($get["dir"] == "ASC" || $get["dir"] == "DESC")
  345. $this->direction = $get["dir"];
  346. else
  347. $this->direction = "ASC";
  348. }
  349. if (isset($get["start"]))
  350. {
  351. if (!isset($this->total))
  352. $this->getTotal();
  353. if ($get["start"] > -1)
  354. {
  355. if ($this->total > $get["start"])
  356. $this->cur = $get["start"];
  357. }
  358. }
  359. }
  360. /**
  361. * setupRequirements
  362. *
  363. * @access public
  364. * @return void
  365. */
  366. function setupRequirements()
  367. {
  368. if (isset($_POST))
  369. $post = $_POST;
  370. $where = array();
  371. $wherestr = "where 1 = 1";
  372. $value = "";
  373. // SETUP INDIVIDUAL AND ALL SEARCH TYPES
  374. if (isset($post) && $post && ($this->search["type"] == "individual" || $this->search["type"] == "all"))
  375. {
  376. if (isset($post["search"]))
  377. {
  378. $value = $post["search"];
  379. $this->search["value"] = $post["search"];
  380. }
  381. if (isset($post["search['field']"]))
  382. $this->search["field"] = $post["searchfield"];
  383. }
  384. foreach ($this->fields as $field)
  385. {
  386. if (isset($field->name))
  387. {
  388. $fieldname = $field->name;
  389. // SETUP LIST REQUIREMENTS
  390. if (isset($field->listrequirement) && $field->listrequirement)
  391. {
  392. if (is_array($field->listrequirement))
  393. {
  394. $orwhere = array();
  395. foreach($field->listrequirement as $listrequirement)
  396. {
  397. $orwhere[] = "$field->name = '$listrequirement'";
  398. }
  399. $where[] = "(" . implode(" OR ", $orwhere) . ")";
  400. }
  401. else
  402. $where[] = "$field->name = '$field->listrequirement'";
  403. }
  404. if (isset($field->where) && $field->where)
  405. {
  406. if (is_array($field->where))
  407. {
  408. $fieldwhere = '';
  409. foreach($field->where as $thiswhere)
  410. {
  411. if(empty($fieldwhere))
  412. $fieldwhere .= "$field->name {$thiswhere['condition']}";
  413. else
  414. $fieldwhere .= " {$thiswhere['junction']} $field->name {$thiswhere['condition']}";
  415. }
  416. $where[] = "($fieldwhere)";
  417. }
  418. else
  419. $where[] = "$field->name $field->where";
  420. }
  421. // SETUP ADVANCED SEARCH
  422. if (isset($post) && $post) // PROCESS SEARCH QUERY AS WELL AS NORMAL QUERY
  423. {
  424. $this->cur = 0; // RESET TO PAGE 0 of RECORD SET
  425. if (isset($field->search["searchable"]) && $field->search["searchable"])
  426. {
  427. if ($this->search["type"] == "advanced")
  428. {
  429. if ($field->search["type"] != "range" && isset($post[$fieldname]))
  430. {
  431. $value = $post[$field->name];
  432. }
  433. else
  434. $value = true;
  435. $this->fields[$field->name]->search["value"] = $value;
  436. }
  437. else
  438. {
  439. if ($field->search["type"] == "range")
  440. $value = 0;
  441. }
  442. if ($field->search["type"] == "range")
  443. {
  444. $minval = $post[$field->name . "_min"];
  445. $maxval = $post[$field->name . "_max"];
  446. $this->fields[$field->name]->search["value_min"] = $minval;
  447. $this->fields[$field->name]->search["value_max"] = $maxval;
  448. }
  449. if (($value && ($this->search["type"] == "advanced" || $this->search["type"] == "all")) || ($this->search["type"] == "individual" && isset($post["searchfield"]) && $field->name == $post["searchfield"]));
  450. {
  451. switch ($field->search["type"])
  452. {
  453. case "exact":
  454. if (strlen($value) > 0)
  455. $swhere[] = "$field->name = '$value'";
  456. break;
  457. case "index":
  458. if ($value != "any" && (strlen($value) > 0))
  459. $swhere[] = "$field->name = '$value'";
  460. break;
  461. case "contains":
  462. if (strlen($value) > 0)
  463. $swhere[] = "$field->name LIKE '%$value%'";
  464. break;
  465. case "range":
  466. if (strlen($minval) > 0)
  467. $swhere[] = "$field->name >= '$minval'";
  468. if (strlen($maxval) > 0)
  469. $swhere[] = "$field->name <= '$maxval'";
  470. break;
  471. case "multiple":
  472. if ($value !== 1 && is_array($value))
  473. {
  474. foreach ($value as $val)
  475. {
  476. $mvalue[] = "$field->name = '$val'";
  477. }
  478. if (isset($mvalue))
  479. {
  480. $tmpstr = implode(" OR ", $mvalue);
  481. $swhere[] = " ($tmpstr) ";
  482. }
  483. }
  484. break;
  485. }
  486. }
  487. }
  488. }
  489. }
  490. else
  491. {
  492. echo("you have modified a field that doesn't exist. Here is an echo of that field");
  493. echo_r($field);
  494. echo_backtrace();
  495. }
  496. }
  497. if (isset($swhere[0]))
  498. {
  499. switch ($this->search["type"])
  500. {
  501. case "all":
  502. $search["wherestr"] = " AND (" . implode(" OR ", $swhere) . ")";
  503. break;
  504. case "individual":
  505. $search["wherestr"] = " AND (" . implode(" AND ", $swhere) . ")";
  506. break;
  507. case "advanced":
  508. $search["wherestr"] = " AND (" . implode(" AND ", $swhere) . ")";
  509. break;
  510. }
  511. $this->search["wherestr"] = $search["wherestr"];
  512. }
  513. if (isset($post) && $post && !isset($swhere)) // IF POSTING A SEARCH WITHOUT VALUES THEN CLEAR OUT THE SWHERE STRING
  514. {
  515. $this->search["wherestr"] = null;
  516. }
  517. if (isset($where[0]))
  518. $wherestr .= " AND " . implode(" AND ", $where);
  519. if (isset($this->search["wherestr"]))
  520. $wherestr .= $this->search["wherestr"];
  521. // echo_r($this->search["wherestr"]);
  522. // echo_r($wherestr);
  523. $this->wherestr = $wherestr;
  524. }
  525. function getRecords() # LIMIT OF -1 GIVES YOU ALL THE RECORDS
  526. {
  527. $dbconnname = $this->dbconnname;
  528. global $$dbconnname;
  529. $this->setupRequirements();
  530. $this->records = NULL; # FIRST UNSET ALL THE CURRENT RECORDS
  531. $this->getTotal();
  532. if ($this->cur < 1)
  533. $this->cur = 0;
  534. $query = "SELECT * FROM $this->name $this->wherestr";
  535. if (isset($this->sort))
  536. $query .=" ORDER BY $this->sort";
  537. if (isset($this->sort) && isset($this->direction) && ($this->direction == "ASC" || $this->direction == "DESC"))
  538. $query .= " $this->direction";
  539. if ($this->limit != -1 && is_numeric($this->limit))
  540. $query .= " LIMIT $this->limit OFFSET $this->cur";
  541. $this->sql = $query;
  542. $results = $$dbconnname->fetch_rows($query);
  543. foreach ($results as $array)
  544. {
  545. $idfield = $this->idfield;
  546. $id = $array[$idfield];
  547. $this->records[$id] = new record($this->name, $id, $idfield, $dbconnname, $array);
  548. }
  549. }
  550. /**
  551. * xmlExport
  552. *
  553. * @access public
  554. * @return void
  555. */
  556. function xmlExport()
  557. {
  558. $root = $this->name;
  559. $XML = "<$this->name>\r";
  560. if (count($this->records))
  561. {
  562. foreach ($this->records as $record)
  563. {
  564. $XML .= $record->xmlExport() . "\r";
  565. }
  566. }
  567. $XML .= "</$this->name>\r";
  568. return $XML;
  569. }
  570. /**
  571. * reorder
  572. *
  573. * @param mixed $array
  574. * @access public
  575. * @return void
  576. */
  577. function reorder($array = false)
  578. {
  579. if ($array)
  580. {
  581. if (is_array($array))
  582. $this->order = $array;
  583. }
  584. $array = $this->order;
  585. $a_diff = array_diff(array_keys($this->fields), $array);
  586. $this->order = array_merge($array, $a_diff);
  587. }
  588. }
  589. ?>