DataProvider.php 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. <?php
  2. namespace ModulesGarden\Servers\ProxmoxCloudVps\Core\UI\Widget\DataTable\DataProviders;
  3. use ModulesGarden\Servers\ProxmoxCloudVps\Core\Http\Request;
  4. /**
  5. *
  6. */
  7. abstract class DataProvider
  8. {
  9. const FILTR_BY_DATE = '\ModulesGarden\Servers\ProxmoxCloudVps\Core\UI\Widget\DataTable\Filters\Date';
  10. const FILTR_BY_RAGE = '\ModulesGarden\Servers\ProxmoxCloudVps\Core\UI\Widget\DataTable\Filters\Rage';
  11. const FILTR_BY_RAGE_DATE = '\ModulesGarden\Servers\ProxmoxCloudVps\Core\UI\Widget\DataTable\Filters\RageDate';
  12. const FILTR_BY_SELECT = '\ModulesGarden\Servers\ProxmoxCloudVps\Core\UI\Widget\DataTable\Filters\Select';
  13. const FILTR_BY_TEXT = '\ModulesGarden\Servers\ProxmoxCloudVps\Core\UI\Widget\DataTable\Filters\Text';
  14. const FILTR_BY_YESNO = '\ModulesGarden\Servers\ProxmoxCloudVps\Core\UI\Widget\DataTable\Filters\YesNo';
  15. const SORT_ASC = 'ASC';
  16. const SORT_DESC = 'DESC';
  17. protected $limit = 10;
  18. protected $offset = 0;
  19. protected $data = null;
  20. protected $orderColumn = null;
  21. protected $orderDir = null;
  22. protected $request = null;
  23. protected $avalibleCols = null;
  24. protected $filter = [];
  25. protected $records = [];
  26. protected $filterFields = [];
  27. protected $toSearch = null;
  28. private $response;
  29. protected $customSearch = false;
  30. protected $defaultOrderColumn = null;
  31. protected $defaultOrderDir = null;
  32. public function __construct()
  33. {
  34. $this->request = Request::build();
  35. $this->response = new DataSet();
  36. $this->loadLimits();
  37. $this->loadSortings();
  38. $this->loadFilter();
  39. $this->loadSearch();
  40. }
  41. protected function loadLimits()
  42. {
  43. if ($this->request->query->get('iDisplayLength'))
  44. {
  45. $this->setLimit((int) $this->request->query->get('iDisplayLength'));
  46. }
  47. if ($this->request->query->get('iDisplayStart'))
  48. {
  49. $this->setOfset((int) $this->request->query->get('iDisplayStart'));
  50. }
  51. }
  52. protected function loadSortings()
  53. {
  54. if ($this->request->query->get('iSortCol_0') && $this->request->query->get('sSortDir_0'))
  55. {
  56. $this->setSortBy($this->request->query->get('iSortCol_0'));
  57. $this->setSortDir($this->request->query->get('sSortDir_0'));
  58. }
  59. }
  60. protected function loadSearch()
  61. {
  62. if ($this->request->query->get('sSearch'))
  63. {
  64. $this->setSearch(html_entity_decode($this->request->query->get('sSearch'), ENT_QUOTES));
  65. }
  66. }
  67. protected function loadFilter()
  68. {
  69. $filters = $this->request->query->get('filter', []);
  70. foreach ($filters as $filter)
  71. {
  72. $this->addFilter($filter['name'], $filter['data']);
  73. }
  74. return $this;
  75. }
  76. protected function addFilter($key, $data = null)
  77. {
  78. if (isset($data))
  79. {
  80. array_set($this->filter, $key, $data);
  81. }
  82. return $this;
  83. }
  84. public function setLimit($limit)
  85. {
  86. $this->limit = (int) $limit;
  87. }
  88. public function setSearch($toSearch)
  89. {
  90. $this->toSearch = $toSearch;
  91. }
  92. protected function useSearch($data = [])
  93. {
  94. if ($this->toSearch && str_replace(" ", "", $this->toSearch) != '' && $this->customSearch === false)
  95. {
  96. $searchable = [];
  97. foreach ($this->avalibleCols as $column)
  98. {
  99. if ($column->searchable === true)
  100. {
  101. $searchable[] = $column->name;
  102. }
  103. }
  104. $removeIds = [];
  105. foreach ($data as $id => $record)
  106. {
  107. $isFind = false;
  108. foreach ($record as $fieldKey => $fieldData)
  109. {
  110. if (strpos(strtolower(str_replace(" ", "", $fieldData)),
  111. strtolower(str_replace(" ", "", $this->toSearch))) !== false
  112. && in_array($fieldKey, $searchable))
  113. {
  114. $isFind = true;
  115. break;
  116. }
  117. }
  118. if ($isFind === false)
  119. {
  120. $removeIds[] = $id;
  121. }
  122. }
  123. if (is_object($data))
  124. {
  125. foreach ($removeIds as $id)
  126. {
  127. unset($data->$id);
  128. }
  129. }
  130. else
  131. {
  132. foreach ($removeIds as $id)
  133. {
  134. unset($data[$id]);
  135. }
  136. }
  137. }
  138. return $data;
  139. }
  140. public function setOfset($offset)
  141. {
  142. $this->offset = (int) $offset;
  143. }
  144. public function setData(array $data = [])
  145. {
  146. $this->data = $data;
  147. return $this;
  148. }
  149. public function setSortBy($colName)
  150. {
  151. $this->orderColumn = $colName;
  152. }
  153. public function setSortDir($sortDir)
  154. {
  155. $this->orderDir = $sortDir;
  156. }
  157. public function getData(array $avalibleCols = [])
  158. {
  159. $this->avalibleCols = $avalibleCols;
  160. $this->data = $this->useSearch($this->data);
  161. $this->records = $this->data;
  162. $this->response->fullDataLenght = count($this->records);
  163. //$this->useFilter(); //<- todo
  164. $this->sortData();
  165. $this->addLimit($this->records);
  166. $this->response->offset = $this->offset;
  167. $this->response->records = $this->records;
  168. return $this->response;
  169. }
  170. protected function sortData()
  171. {
  172. if ($this->orderColumn && $this->orderDir && $this->avalibleCols[$this->orderColumn])
  173. {
  174. $column = $this->avalibleCols[$this->orderColumn];
  175. $this->sortNow($this->orderColumn, $column->type, strtolower($this->orderDir) === strtolower(DataProvider::SORT_ASC));
  176. }
  177. }
  178. protected function addLimit(&$data)
  179. {
  180. $data = array_slice($data, $this->offset, $this->limit);
  181. }
  182. protected function useSort()
  183. {
  184. foreach ($this->sort as $field => $sort)
  185. {
  186. $this->sortNow($field, $this->getType($field), strtolower($sort) === strtolower(DataProvider::SORT_ASC));
  187. }
  188. return $this;
  189. }
  190. protected function sortNow($fieldName, $type, $asc)
  191. {
  192. if ($type == 'string')
  193. {
  194. usort($this->records, function (array $a, array $b) use ($fieldName, $asc)
  195. {
  196. if ($asc)
  197. {
  198. return strnatcmp(strtolower($a[$fieldName]), strtolower($b[$fieldName]));
  199. }
  200. return strnatcmp(strtolower($b[$fieldName]), strtolower($a[$fieldName]));
  201. });
  202. }
  203. elseif ($type == 'int')
  204. {
  205. usort($this->records, function (array $a, array $b) use (&$fieldName, &$asc)
  206. {
  207. if ($a[$fieldName] == $b[$fieldName])
  208. {
  209. $return = 0;
  210. }
  211. elseif ($a[$fieldName] != $b[$fieldName] && $asc)
  212. {
  213. $return = ($a[$fieldName] < $b[$fieldName]) ? -1 : 1;
  214. }
  215. else
  216. {
  217. $return = ($a[$fieldName] > $b[$fieldName]) ? -1 : 1;
  218. }
  219. return $return;
  220. });
  221. }
  222. elseif ($type == 'date')
  223. {
  224. usort($this->records, function (array $a, array $b) use (&$fieldName, &$asc)
  225. {
  226. $a = $a[$fieldName];
  227. if (!is_numeric($a))
  228. $a = strtotime($a);
  229. $b = $b[$fieldName];
  230. if (!is_numeric($b))
  231. $b = strtotime($b);
  232. $return = $asc ? 1 : -1;
  233. if ($a == $b) {
  234. return 0;
  235. }
  236. return $a > $b ? $return : -$return;
  237. });
  238. }
  239. else
  240. {
  241. foreach ($this->sortFunction as $typeCallBack => $callback)
  242. {
  243. if ($typeCallBack == $type)
  244. {
  245. usort($this->records, $callback);
  246. }
  247. }
  248. }
  249. }
  250. protected function addSortFunction($type, $callback)
  251. {
  252. array_set($this->sortFunction, $type, $callback);
  253. return $this;
  254. }
  255. private function setType($field, $type = self::TYPE_STRING)
  256. {
  257. array_set($this->type, $field, $type);
  258. return $this;
  259. }
  260. protected function getType($field)
  261. {
  262. if (array_key_exists($field, $this->type))
  263. {
  264. return $this->type[$field];
  265. }
  266. return 'string';
  267. }
  268. private function addFilterField($field, $class = self::FILTR_BY_TEXT)
  269. {
  270. array_set($this->filterFields, $field, $class);
  271. return $this;
  272. }
  273. protected function useFilter()
  274. {
  275. foreach ($this->filter as $field => $value)
  276. {
  277. if (isset($this->filterFields[$field]))
  278. {
  279. $class = $this->filterFields[$field];
  280. $this->setData($class::create($this->getRecords(), $field, $value));
  281. }
  282. else
  283. {
  284. $this->setData(Filters\Text::create($this->getRecords(), $field, $value));
  285. }
  286. }
  287. return $this;
  288. }
  289. public function setDefaultSorting($column, $direction)
  290. {
  291. if (!$this->request->query->get('iSortCol_0') && !$this->request->query->get('sSortDir_0'))
  292. {
  293. $this->setSortBy($column);
  294. $this->setSortDir($direction);
  295. }
  296. return $this;
  297. }
  298. public function enableCustomSearch()
  299. {
  300. $this->customSearch = true;
  301. }
  302. }