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

/htdocs/core/class/datatables/Datatables.php

https://bitbucket.org/speedealing/speedealing
PHP | 466 lines | 295 code | 91 blank | 80 comment | 46 complexity | 7d3a708d57ca79716c6a15b5eb7be1b7 MD5 | raw file
Possible License(s): LGPL-3.0, LGPL-2.1, GPL-3.0, MIT
  1. <?php
  2. /* Copyright (C) 2013 Regis Houssin <regis.houssin@capnetworks.com>
  3. * Copyright (C) 2013 Herve Prot <herve.prot@symeos.com>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. namespace datatables;
  19. class Datatables {
  20. const REQUEST_GET = 'GET';
  21. const REQUEST_POST = 'POST';
  22. protected $schema;
  23. protected $callbacks = array();
  24. protected $tabletools = array();
  25. protected $colvis = array();
  26. protected $plugins = array();
  27. protected $config = array();
  28. protected $chain = array();
  29. protected $method = array();
  30. protected $params = array(
  31. 'bProcessing' => true,
  32. 'bServerSide' => false,
  33. 'sAjaxSource' => null,
  34. 'bPaginate' => true,
  35. 'sPaginationType' => 'full_numbers',
  36. 'bLengthChange' => true,
  37. 'bFilter' => true,
  38. 'bSort' => true,
  39. 'bInfo' => false,
  40. 'bAutoWidth' => false,
  41. 'bStateSave' => false,
  42. 'bDeferRender' => true,
  43. 'aLengthMenu' => array(5, 10, 20, 50, 100, 500, 'All'),
  44. 'aaSorting' => array(array(2, 'asc')),
  45. //'sScrollY' => '400px',
  46. //'sScrollX' => '100%',
  47. //'sScrollXInner' => '100%',
  48. 'bScrollCollapse' => false,
  49. 'bScrollInfinite' => false,
  50. 'bJQueryUI' => true,
  51. 'iDisplayLength' => 20,
  52. 'oLanguage' => array(),
  53. 'sDom' => '<"dataTables_header"lfr>t<"dataTables_footer"p><"dataTables_actions">'
  54. );
  55. protected $htmlTemplate = "
  56. <table class=\"{:container_class}\" id=\"{:container_id}\">
  57. <thead>
  58. <tr>
  59. {:headers}
  60. </tr>
  61. </thead>
  62. <tbody>
  63. </tbody>
  64. <tfoot>
  65. <tr>
  66. {:footers}
  67. </tr>
  68. </tfoot>
  69. </table>
  70. ";
  71. protected $jsTemplate = "
  72. <script type=\"text/javascript\">
  73. $(document).ready(function() {
  74. <!-- // <![CDATA[
  75. var {:var_name} = jQuery('#{:container_id}').dataTable({:config}){:chain};
  76. {:method}
  77. // ]]> -->
  78. });
  79. </script>
  80. ";
  81. /* ______________________________________________________________________ */
  82. public function __construct(array $config = array()) {
  83. $defaults = array(
  84. 'request_method' => self::REQUEST_GET,
  85. 'object_class' => null,
  86. 'data_source' => null,
  87. 'var_name' => 'oTable',
  88. 'container_id' => 'datatableTable',
  89. 'container_class' => 'display dt_act'
  90. );
  91. $this->config = $config + $defaults;
  92. }
  93. /* ______________________________________________________________________ */
  94. public function __toString() {
  95. $table = '';
  96. try {
  97. $table = (string) $this->render();
  98. } catch(\Exception $e) {
  99. $table = 'Could not render table, possibly caused by wrong configuration';
  100. $table = $e->getMessage();
  101. }
  102. return $table;
  103. }
  104. /* ______________________________________________________________________ */
  105. public function setConfig($name, $value) {
  106. return $this->config[$name] = $value;
  107. }
  108. /* ______________________________________________________________________ */
  109. public function unsetConfig($name) {
  110. unset($this->config[$name]);
  111. }
  112. /* ______________________________________________________________________ */
  113. public function getConfig($name) {
  114. return (isset($this->config[$name])) ? $this->config[$name] : null;
  115. }
  116. /* ______________________________________________________________________ */
  117. public function setParam($name, $value = '') {
  118. if($name == 'fnDrawCallback') {
  119. $this->params['fnDrawCallback'] = '{:callback}';
  120. return $this->callbacks[] = $value;
  121. } else if($name == 'oTableTools') {
  122. $this->params['oTableTools'] = '{:tabletools}';
  123. return $this->tabletools[] = $value;
  124. } else if($name == 'oColVis') {
  125. $this->params['oColVis'] = '{:colvis}';
  126. return $this->colvis[] = $value;
  127. }
  128. return $this->params[$name] = $value;
  129. }
  130. /* ______________________________________________________________________ */
  131. public function unsetParam($name) {
  132. if($name == 'fnDrawCallback') {
  133. $this->callbacks = array();
  134. } else if($name == 'oTableTools') {
  135. $this->tabletools = array();
  136. } else if($name == 'oColVis') {
  137. $this->colvis = array();
  138. }
  139. unset($this->params[$name]);
  140. }
  141. /* ______________________________________________________________________ */
  142. public function getParam($name) {
  143. if($name == 'fnDrawCallback') {
  144. return $this->callbacks;
  145. } else if($name == 'oTableTools') {
  146. return $this->tabletools;
  147. } else if($name == 'oColVis') {
  148. return $this->colvis;
  149. }
  150. return (isset($this->params[$name])) ? $this->params[$name] : null;
  151. }
  152. /* ______________________________________________________________________ */
  153. public function translate($key, $str) {
  154. $this->params['oLanguage'][$key] = $str;
  155. }
  156. /* ______________________________________________________________________ */
  157. public function setTranslationArray(array $t) {
  158. $this->params['oLanguage'] = $t;
  159. }
  160. /* ______________________________________________________________________ */
  161. public function plug(PluginInterface $plugin) {
  162. $plugin->apply($this);
  163. }
  164. /* ______________________________________________________________________ */
  165. public function chain($chain) {
  166. $chain = rtrim($chain, ';'); // removes semicolon at the end
  167. $this->chain[] = "{$chain}";
  168. }
  169. /* ______________________________________________________________________ */
  170. public function method($method) {
  171. $this->method[] = $method;
  172. }
  173. /* ______________________________________________________________________ */
  174. public function callback($callback) {
  175. $this->callbacks[] = $callback;
  176. $this->params['fnDrawCallback'] = '{:callback}';
  177. }
  178. /* ______________________________________________________________________ */
  179. public function tabletools($tabletools) {
  180. $this->tabletools[] = $tabletools;
  181. $this->params['oTableTools'] = '{:tabletools}';
  182. }
  183. /* ______________________________________________________________________ */
  184. public function colvis($colvis) {
  185. $this->colvis[] = $colvis;
  186. $this->params['oColVis'] = '{:colvis}';
  187. }
  188. /* ______________________________________________________________________ */
  189. public function setSchema(Schema $schema) {
  190. $this->schema = $schema;
  191. }
  192. /* ______________________________________________________________________ */
  193. public function getSchema() {
  194. if( ! ($this->schema instanceof Schema)) {
  195. throw new \RuntimeException("Datatables schema is not set.");
  196. }
  197. return $this->schema;
  198. }
  199. /* ______________________________________________________________________ */
  200. public function getFieldType() {
  201. if( ! ($this->schema instanceof Schema)) {
  202. throw new \RuntimeException("Datatables schema is not set.");
  203. }
  204. return $this->schema->getType();
  205. }
  206. /* ______________________________________________________________________ */
  207. public function getFieldEditable() {
  208. if( ! ($this->schema instanceof Schema)) {
  209. throw new \RuntimeException("Datatables schema is not set.");
  210. }
  211. return $this->schema->getEditable();
  212. }
  213. /* ______________________________________________________________________ */
  214. public function formatJsonOutput(array $data, $totalRecords = null) {
  215. if(is_null($totalRecords)) {
  216. $totalRecords = count($data);
  217. }
  218. $data = array(
  219. 'iTotalRecords' => $totalRecords,
  220. 'iTotalDisplayRecords' => $totalRecords,
  221. 'aaData' => $data
  222. );
  223. return json_encode($data);
  224. }
  225. /* ______________________________________________________________________ */
  226. public function render() {
  227. if($this->getParam('bServerSide') == true) {
  228. if( ! $this->getParam('sAjaxSource')) {
  229. if( ! $this->getConfig('data_source')) {
  230. throw new \RuntimeException('Data source is not set.');
  231. }
  232. $this->setParam('sAjaxSource', $this->getConfig('data_source'));
  233. }
  234. } else {
  235. if( ! $this->getParam('aaData')) {
  236. $this->setParam('aaData', array());
  237. // throw new \RuntimeException('Datatables: `aaData` is not set.');
  238. }
  239. }
  240. $this->setParam('sAjaxSource', $this->getConfig('data_source'));
  241. if( ! ($this->schema instanceof Schema)) {
  242. throw new \RuntimeException("Datatables schema is not set.");
  243. }
  244. $var_name = $this->config['var_name'];
  245. $container_id = $this->config['container_id'];
  246. $container_class = $this->config['container_class'];
  247. $chain = empty($this->chain) ? null : '.' . implode('.', $this->chain);
  248. $method = empty($this->method) ? null : implode("\n", $this->method);
  249. $callback = "function(oSettings) {\n" . implode("\n", $this->callbacks) . "}\n";
  250. $tabletools = "{\n" . implode("\n", $this->tabletools) . "}\n";
  251. $colvis = "{\n" . implode("\n", $this->colvis) . "}\n";
  252. $i = 0;
  253. $cols = array();
  254. $def = array();
  255. $render = array();
  256. $headers = '';
  257. $editable = '';
  258. $footers = '';
  259. foreach($this->schema->data() as $key => $config) {
  260. /*
  261. $cols[] = $config['aoColumns'] + array(
  262. 'mData' => $key,
  263. 'mRender' => (!empty($config['render']) ? '{:render_'.$key.'}' : ''),
  264. 'sDefaultContent' => $config['default'] ? $config['default'] : '',
  265. 'sWidth' => $config['width'] ? intval($config['width']) . 'px' : '',
  266. 'sClass' => $config['class'] ? $config['class'] : '',
  267. 'bSortable' => (bool) $config['sortable'],
  268. 'bSearchable' => (bool) $config['searchable'],
  269. 'bVisible' => (bool) $config['visible']
  270. //'sType' => 'html'
  271. );*/
  272. $def['mData'][$key][] = $i;
  273. $def['sName'][$key][] = $i;
  274. $def['sDefaultContent'][$config['default']][] = $i;
  275. if (!empty($config['width']))
  276. $def['sWidth'][$config['width']][] = $i;
  277. if (!empty($config['editable']))
  278. $config['class'] = $config['class'] . ' editfield_' . $key;
  279. if (!empty($config['class']))
  280. $def['sClass'][$config['class']][] = $i;
  281. if ($config['sortable'] === false)
  282. $def['bSortable'][] = $i;
  283. if ($config['searchable'] === false)
  284. $def['bSearchable'][] = $i;
  285. if ($config['visible'] === false)
  286. $def['bVisible'][] = $i;
  287. if (!empty($config['render']))
  288. $def['mRender'][$i] = '{:render_'.$key.'}';
  289. // display header label
  290. $headers .= "<th>{$config['label']}</th>\n";
  291. // build editable
  292. /*
  293. if(!empty($config['visible']) && !empty($config['editable'])) {
  294. $editable .= self::insert($config['editable'], $config);
  295. } else if(!empty($config['visible'])) {
  296. $editable .= self::insert('null,', $config);
  297. }*/
  298. // display mRender
  299. if (!empty($config['render']))
  300. $render['render_'.$key] = self::insert($config['render'], $config);
  301. // display footer
  302. $footer = '';
  303. if(!empty($config['footer'])) {
  304. $footer = self::insert($config['footer'], $config);
  305. }
  306. $footers .= "<th id=\"{$i}\">{$footer}</th>\n";
  307. $i++;
  308. }
  309. //$this->params['aoColumns'] = $cols;
  310. // start
  311. foreach($def['mData'] as $key => $value) {
  312. $this->params['aoColumnDefs'][] = array('mData' => $key, 'aTargets' => $value);
  313. }
  314. unset($def['mData']);
  315. foreach($def['sName'] as $key => $value) {
  316. $this->params['aoColumnDefs'][] = array('sName' => $key, 'aTargets' => $value);
  317. }
  318. unset($def['sName']);
  319. foreach($def['sDefaultContent'] as $key => $value) {
  320. $this->params['aoColumnDefs'][] = array('sDefaultContent' => $key, 'aTargets' => $value);
  321. }
  322. unset($def['sDefaultContent']);
  323. foreach($def['sWidth'] as $key => $value) {
  324. $this->params['aoColumnDefs'][] = array('sWidth' => $key, 'aTargets' => $value);
  325. }
  326. unset($def['sWidth']);
  327. foreach($def['sClass'] as $key => $value) {
  328. $this->params['aoColumnDefs'][] = array('sClass' => $key, 'aTargets' => $value);
  329. }
  330. unset($def['sClass']);
  331. foreach($def['mRender'] as $key => $value) {
  332. $this->params['aoColumnDefs'][] = array('mRender' => $value, 'aTargets' => array($key));
  333. }
  334. unset($def['mRender']);
  335. foreach($def as $key => $value) {
  336. $this->params['aoColumnDefs'][] = array($key => false, 'aTargets' => $value);
  337. }
  338. /*echo json_encode($this->params['aoColumns']);
  339. echo '<br><br>';
  340. echo json_encode($this->params['aoColumnDefs']);*/
  341. // end
  342. // convert 'oLanguage' to object
  343. $this->params['oLanguage'] = (object) $this->params['oLanguage'];
  344. // display editable
  345. //$chain = preg_replace('/\{:editable\}/', $editable, $chain);
  346. // display editable options
  347. $chain = preg_replace('/\{:editable_options\}/', $editable_options, $chain);
  348. // params json encode
  349. $config = json_encode($this->params);
  350. // display callback
  351. $config = preg_replace('/"\{:callback\}"/', $callback, $config);
  352. // display tabletools
  353. $config = preg_replace('/"\{:tabletools\}"/', $tabletools, $config);
  354. // display colvis
  355. $config = preg_replace('/"\{:colvis\}"/', $colvis, $config);
  356. // display render
  357. if (!empty($render)) {
  358. foreach($render as $key => $value) {
  359. $config = preg_replace('/"\{:'.$key.'\}"/', $value, $config);
  360. }
  361. }
  362. $params = compact('var_name', 'container_id', 'container_class', 'chain', 'config', 'method', 'headers', 'footers');
  363. return self::insert($this->htmlTemplate . $this->jsTemplate, $params);
  364. }
  365. public static function insert($str, array $data) {
  366. if (empty($data)) {
  367. return $str;
  368. }
  369. $replace = array();
  370. foreach ($data as $key => $value) {
  371. $replace['{:' . $key . '}'] = $value;
  372. }
  373. return strtr($str, $replace);
  374. }
  375. }