Filter.php 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. <?php
  2. class Filter {
  3. var $args;
  4. var $args_default;
  5. var $filters;
  6. var $labels;
  7. var $callbacks;
  8. var $_key;
  9. var $_storage;// enum('session', 'cookie')
  10. var $_trash_filtr;// Tree trash
  11. /**
  12. * @param $args - args table: $_GET, $_POST, $_REQUEST, etc
  13. * @param $key - kay to store values in @storage, if not set then args not saved
  14. * @param $storage - where to store state - cookie or session, default is cookie
  15. */
  16. function __construct($args, $key = null, $storage = 'cookie') {
  17. $this->args = $args;
  18. $this->args_default = array();
  19. $this->filters = array();
  20. $this->labels = array();
  21. $this->callbacks = array();
  22. $this->_key = 'filter-'.$key;
  23. $this->_storage = $storage;
  24. $this->_init_args();
  25. $this->_trash_filtr = null;
  26. }
  27. public function get_arg($name) {
  28. // TODO: allow only keys from $this->filters
  29. // try load from @storage and save
  30. if (array_key_exists($name, $this->args)) {
  31. return $this->args[$name];
  32. } else if (array_key_exists($name, $this->args_default)) {
  33. return $this->args_default[$name];
  34. }
  35. return null;
  36. }
  37. public function setArgs($args) {
  38. foreach ($args as $k => $v) {
  39. if (!array_key_exists($k, $this->filters)) continue;
  40. $this->args[$k] = $v;
  41. }
  42. }
  43. private function _init_args() {
  44. if (array_key_exists('filtr_clear', $this->args) && $this->args['filtr_clear'] == 1) {
  45. $this->args = array();
  46. } else {
  47. $this->_read_args();
  48. }
  49. }
  50. function add_filter($name, $values, $default, $label = '', $callback = null) {
  51. $this->filters[$name] = $values;
  52. $this->labels[$name] = ($label)? $label : $name;
  53. $this->args_default[$name] = $default;
  54. if ($callback) $this->callbacks[$name] = $callback;
  55. }
  56. public function _save_args() {
  57. if (!$this->_key) { return; }
  58. if ($this->_storage == 'cookie') {
  59. $this->_save_args_in_cookie();
  60. } else {
  61. $this->_save_args_in_session();
  62. }
  63. }
  64. private function _save_args_in_session() {
  65. if (!$this->_key) { return; }
  66. $save_args = array();
  67. foreach ($this->filters as $name => $options) {
  68. $arg = (isset($this->args[$name]))? $this->args[$name] : '';
  69. if (count($options) == 1 && reset($options) == 'search') {
  70. if ($arg != $this->args_default[$name]) {
  71. $option = $arg;
  72. $save_args[] = ''.urlencode($name).'='.urlencode($option);
  73. }
  74. } else {
  75. foreach($options as $option => $field_name) {
  76. if (isset($this->args[$name]) && $this->args[$name] == $option) {
  77. $save_args[] = ''.urlencode($name).'='.urlencode($option);
  78. }
  79. }
  80. }
  81. }
  82. $save_args = implode(',', $save_args);
  83. $_SESSION[$this->_key] = $save_args;
  84. }
  85. private function _save_args_in_cookie() {
  86. if (!$this->_key) { return; }
  87. $save_args = array();
  88. foreach ($this->filters as $name => $options) {
  89. $arg = (isset($this->args[$name]))? $this->args[$name] : '';
  90. if (count($options) == 1 && reset($options) == 'search') {
  91. if ($arg != $this->args_default[$name]) {
  92. $option = $arg;
  93. $save_args[] = ''.urlencode($name).'='.urlencode($option);
  94. }
  95. } else {
  96. foreach($options as $option => $field_name) {
  97. if (isset($this->args[$name]) && $this->args[$name] == $option) {
  98. $save_args[] = ''.urlencode($name).'='.urlencode($option);
  99. }
  100. }
  101. }
  102. }
  103. // if ($save_args) {
  104. $save_args = implode(',', $save_args);
  105. echo'<script type="text/javascript">';echo"
  106. (function(){
  107. var exdate=new Date()
  108. , exdays = 14
  109. , c_name='".$this->_key."'
  110. , value='".$save_args."'
  111. ;
  112. exdate.setDate(exdate.getDate() + exdays);
  113. var c_value=escape(value) + ((exdays==null) ? '' : '; expires='+exdate.toUTCString());
  114. document.cookie=c_name + '=' + c_value;
  115. })();
  116. ";echo'</script>';
  117. // }
  118. }
  119. public function _read_args($force = false) {
  120. if (!$this->_key) { return; }
  121. if ($this->_storage == 'cookie') {
  122. $this->_read_args_from_cookie($force);
  123. } else {
  124. $this->_read_args_from_session($force);
  125. }
  126. }
  127. private function _read_args_from_session($force = false) {
  128. if (!$this->_key) { return; }
  129. if (!array_key_exists($this->_key, $_SESSION)) { return; }
  130. $c_args = explode(',', $_SESSION[$this->_key]);
  131. //echo'<p>read from session c_args: '.$_SESSION[$this->_key].'</p>';
  132. foreach ($c_args as $c_val) {
  133. $c_val = explode('=', $c_val);
  134. if (count($c_val) != 2) continue;
  135. $name = urldecode($c_val[0]);
  136. $option = urldecode($c_val[1]);
  137. if ($force || !array_key_exists($name, $this->args)) {
  138. //echo'<p>read from session: '.$name.' / '.$this->args[$name].' / set '.$option.'</p>';
  139. $this->args[$name] = $option;
  140. }
  141. }
  142. }
  143. /**
  144. * Read args from cookie.
  145. */
  146. private function _read_args_from_cookie($force = false) {
  147. if (!$this->_key) { return; }
  148. if (!array_key_exists($this->_key, $_COOKIE)) { return; }
  149. $c_args = explode(',', $_COOKIE[$this->_key]);
  150. foreach ($c_args as $c_val) {
  151. $c_val = explode('=', $c_val);
  152. if (count($c_val) != 2) continue;
  153. $name = urldecode($c_val[0]);
  154. $option = urldecode($c_val[1]);
  155. if ($force || !array_key_exists($name, $this->args)) {
  156. $this->args[$name] = $option;
  157. }
  158. }
  159. }
  160. /**
  161. * Print form fields. Must be inside <form> tag.
  162. */
  163. public function show_filters() {
  164. // read args from cookie if exists
  165. $selected_defaults = true;
  166. // bug fix in browser, run onclick action on first submit/image/button element in html code
  167. echo'<nobr style="float:right;margin:-9999px 0 0 -9999px;">';
  168. echo'<input type="submit" value="'."submit".'" />';
  169. echo'</nobr>';
  170. // show trash if exists
  171. echo $this->show_trash();
  172. // show filters
  173. foreach ($this->filters as $name => $options) {
  174. $out = new stdClass();
  175. $out->cls = '';// class
  176. $out->cnt = '';// content
  177. $selected_option = (isset($this->args[$name]))? $this->args[$name] : $this->args_default[$name];
  178. if (count($options) == 1 && reset($options) == 'search') {
  179. $size = strlen($selected_option); $size = ($size < 4)? 4 : $size + 2;// size min 4
  180. $out->cnt .= '<input type="text" name="'.$name.'" value="'.$selected_option.'" class="i" size="'.$size.'" />';
  181. if ($selected_option != $this->args_default[$name]) {
  182. $selected_defaults = false;
  183. $out->cls = 'active';
  184. //echo' <input type="submit" value="'."x".'" onclick="'."this.form.".$name.".value='';".'" title="'."Usuń".'" />';
  185. // po kliknięciu ENTER w polu wymuszało usuwanie zawartości pola - 1st submit btn in form
  186. $out->cnt .= '<input type="button" value="'."x".'" onclick="'."this.form.".$name.".value='';this.form.submit();".'" title="'."Usuń".'" />';
  187. }
  188. //$out->cnt .= '<input type="submit" value="'."Szukaj".'" />';
  189. $out->cnt .= '<input type="image" src="' . "icon/search.png" . '" ale="'."Szukaj".'" title="'."Szukaj".'" />';
  190. }
  191. else if (count($options) == 2) {// 2 opcje do wyboru to button
  192. $selected_button = $selected_option;
  193. if (!array_key_exists($selected_button, $options)) {
  194. $selected_button = $this->args_default[$name];
  195. }
  196. if ($selected_button != $this->args_default[$name]) {
  197. $selected_defaults = false;
  198. $out->cls = 'active';
  199. }
  200. foreach ($options as $option => $val) {
  201. if ($selected_button != $option) {
  202. $out->cnt .= '<input type="submit" name="'.$name.'" value="'.$option.'" />';
  203. }
  204. }
  205. }
  206. else {// ponad 2 opcje to select
  207. $out->cnt .= '<select name="'.$name.'" onchange="this.form.submit();">';
  208. if ($selected_option != $this->args_default[$name]) {
  209. $selected_defaults = false;
  210. $out->cls = 'active';
  211. }
  212. foreach ($options as $option => $field_name) {
  213. $sel = ($selected_option == $option)? 'selected' : '';
  214. $out->cnt .= '<option value="'.$option.'" '.$sel.'>'.$option.'</option>';
  215. }
  216. $out->cnt .= '</select>';
  217. }
  218. echo' <nobr'.(($out->cls)? ' class="'.$out->cls.'"' : '').'>';
  219. echo $this->labels[$name];
  220. echo $out->cnt;
  221. echo'</nobr>';
  222. echo $this->separator();
  223. unset($out);
  224. }
  225. if (!$selected_defaults) {
  226. echo'<nobr>';
  227. echo'<input type="hidden" name="filtr_clear" value="0" />';
  228. echo' <input type="button" value="'."Wyczyść filtr".'" onclick="this.form.filtr_clear.value=1;this.form.submit()" /> ';
  229. echo'</nobr>';
  230. }
  231. $this->_save_args();
  232. }
  233. public function set_trash($filtr_key = '', $value = 0) {
  234. $this->_trash_filtr = array('filtr_key'=>$filtr_key, 'value'=>$value);
  235. }
  236. public function is_trash() {
  237. if ($this->_trash_filtr === null) {
  238. return false;
  239. }
  240. $trash_filtr_key = $this->_trash_filtr['filtr_key'];
  241. $trash_filtr_value = $this->_trash_filtr['value'];
  242. $filtr_value = $this->get_arg($trash_filtr_key);
  243. if ($filtr_value === null) {
  244. return false;
  245. }
  246. if ($filtr_value == $trash_filtr_value) {
  247. return true;
  248. }
  249. return false;
  250. }
  251. public function show_trash() {
  252. $out = '';
  253. if ($this->_trash_filtr === null) {
  254. return $out;
  255. }
  256. $trash_filtr_key = $this->_trash_filtr['filtr_key'];
  257. $trash_filtr_value = $this->_trash_filtr['value'];
  258. $filtr_value = $this->get_arg($trash_filtr_key);
  259. if ($filtr_value === null) {// filtr not exists, TODO: throw error?
  260. return $out;
  261. }
  262. $out .= '<nobr>';
  263. if ($this->is_trash()) {
  264. //echo App::link("Drzewo", array('task'=>App::get_task()), array('ico'=>'trash_out.gif', 'title'=>'Wroc do drzewa'));
  265. $trash_ico = 'icon/trash_out.gif';
  266. $onclick = ' onclick="'."this.form.".$trash_filtr_key.".value='';this.form.submit();".'"';
  267. $out .= '<input type="image" src="'.$trash_ico.'" value="'."Drzewo".'" class="i"'.$onclick.' title="'."Wroc do drzewa".'" />';
  268. } else {
  269. //echo App::link("Kosz", array('task'=>App::get_task(), 'filtr_id'=>"-1"), array('ico'=>'trash.gif', 'title'=>'Kosz'));
  270. $trash_ico = 'icon/trash.gif';
  271. $onclick = ' onclick="'."this.form.".$trash_filtr_key.".value='".$trash_filtr_value."';this.form.submit();".'"';
  272. $out .= '<input type="image" src="'.$trash_ico.'" value="'."Kosz".'" class="i"'.$onclick.' title="'."Kosz".'" />';
  273. }
  274. $out .= '</nobr>';
  275. $out .= $this->separator();
  276. return $out;
  277. }
  278. function separator() {
  279. return '<div class="btnseparator"></div>';// separator
  280. }
  281. }