PageRenderTime 40ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/Ip/Internal/Grid/Model/Config.php

https://gitlab.com/x33n/ImpressPages
PHP | 673 lines | 588 code | 52 blank | 33 comment | 52 complexity | 53d1e386fc79da44b091cf4fe8879cf8 MD5 | raw file
  1. <?php
  2. /**
  3. * @package ImpressPages
  4. */
  5. namespace Ip\Internal\Grid\Model;
  6. class Config
  7. {
  8. /**
  9. * @var Config
  10. */
  11. protected $config = null;
  12. protected $configChecked = false;
  13. protected $multilingual = null;
  14. /**
  15. * @var Field[]
  16. */
  17. protected $fieldObjects = null;
  18. public function __construct($config)
  19. {
  20. $this->config = $config;
  21. if (empty($this->config['table'])) {
  22. throw new \Ip\Exception('\'table\' configuration value missing.');
  23. }
  24. if (empty($this->config['pageSize'])) {
  25. $this->config['pageSize'] = 20;
  26. }
  27. if (empty($this->config['pagerSize'])) {
  28. $this->config['pagerSize'] = 10;
  29. }
  30. if (!isset($this->config['fields']) || !is_array($this->config['fields'])) {
  31. $this->config['fields'] = $this->getTableFields($this->tableName(), $this->languageTableName());
  32. }
  33. $this->checkConfig($this->config);
  34. }
  35. public function pageVariableName()
  36. {
  37. if (!empty($this->config['pageVariableName'])) {
  38. return $this->config['pageVariableName'];
  39. }
  40. return 'page';
  41. }
  42. /**
  43. * Get sql part to be used in where clause
  44. * @return string
  45. */
  46. public function filter()
  47. {
  48. if (!empty($this->config['filter'])) {
  49. return $this->config['filter'];
  50. }
  51. return '1';
  52. }
  53. /**
  54. * Get field name responsible for connection of subgrid to the parent grid.
  55. * You can think of it as a foreign key in SQL
  56. * @return string
  57. */
  58. public function connectionField()
  59. {
  60. if (!empty($this->config['connectionField'])) {
  61. return $this->config['connectionField'];
  62. }
  63. return false;
  64. }
  65. public function deleteWarning()
  66. {
  67. if (!empty($this->config['deleteWarning'])) {
  68. return $this->config['deleteWarning'];
  69. }
  70. return __('Are you sure you want to delete?', 'Ip-admin', false);
  71. }
  72. public function actions()
  73. {
  74. if (!empty($this->config['actions'])) {
  75. return $this->config['actions'];
  76. }
  77. return array();
  78. }
  79. /**
  80. * @return string
  81. */
  82. public function actionsFilter()
  83. {
  84. if (!empty($this->config['actionsFilter'])) {
  85. return $this->config['actionsFilter'];
  86. }
  87. return false;
  88. }
  89. public function beforeDelete()
  90. {
  91. if (empty($this->config['beforeDelete'])) {
  92. return false;
  93. }
  94. return $this->config['beforeDelete'];
  95. }
  96. public function afterDelete()
  97. {
  98. if (empty($this->config['afterDelete'])) {
  99. return false;
  100. }
  101. return $this->config['afterDelete'];
  102. }
  103. public function beforeUpdate()
  104. {
  105. if (empty($this->config['beforeUpdate'])) {
  106. return false;
  107. }
  108. return $this->config['beforeUpdate'];
  109. }
  110. public function afterUpdate()
  111. {
  112. if (empty($this->config['afterUpdate'])) {
  113. return false;
  114. }
  115. return $this->config['afterUpdate'];
  116. }
  117. public function beforeCreate()
  118. {
  119. if (empty($this->config['beforeCreate'])) {
  120. return false;
  121. }
  122. return $this->config['beforeCreate'];
  123. }
  124. public function afterCreate()
  125. {
  126. if (empty($this->config['afterCreate'])) {
  127. return false;
  128. }
  129. return $this->config['afterCreate'];
  130. }
  131. public function beforeMove()
  132. {
  133. if (empty($this->config['beforeMove'])) {
  134. return false;
  135. }
  136. return $this->config['beforeMove'];
  137. }
  138. public function afterMove()
  139. {
  140. if (empty($this->config['afterMove'])) {
  141. return false;
  142. }
  143. return $this->config['afterMove'];
  144. }
  145. public function preventAction()
  146. {
  147. if (empty($this->config['preventAction'])) {
  148. return false;
  149. }
  150. return $this->config['preventAction'];
  151. }
  152. /**
  153. * @param $field
  154. * @throws \Ip\Exception
  155. * @return \Ip\Internal\Grid\Model\Field
  156. */
  157. public function fieldObject($field)
  158. {
  159. if (empty($field['type'])) {
  160. $field['type'] = 'Text';
  161. }
  162. $class = '\\Ip\\Internal\\Grid\\Model\\Field\\' . $field['type'];
  163. if (!class_exists($class)) {
  164. if (class_exists($field['type'])) {
  165. $class = $field['type']; //type is full class name
  166. } else {
  167. throw new \Ip\Exception('Class doesn\'t exist "' . esc($field['type']) . '"');
  168. }
  169. }
  170. $fieldObject = new $class($field, $this->config);
  171. return $fieldObject;
  172. }
  173. public function fields()
  174. {
  175. if (!$this->configChecked) {
  176. $this->checkConfig($this->config);
  177. }
  178. return $this->config['fields'];
  179. }
  180. public function allowCreate()
  181. {
  182. return !array_key_exists('allowCreate', $this->config) || $this->config['allowCreate'];
  183. }
  184. public function allowSearch()
  185. {
  186. return !array_key_exists('allowSearch', $this->config) || $this->config['allowSearch'];
  187. }
  188. public function allowUpdate()
  189. {
  190. return !array_key_exists('allowUpdate', $this->config) || $this->config['allowUpdate'];
  191. }
  192. public function allowSort()
  193. {
  194. if (!empty($this->config['sortField'])) {
  195. if (isset($this->config['allowSort'])) {
  196. return $this->config['allowSort'];
  197. } else {
  198. return true;
  199. }
  200. } else {
  201. return false;
  202. }
  203. }
  204. public function allowDelete()
  205. {
  206. return !array_key_exists('allowDelete', $this->config) || $this->config['allowDelete'];
  207. }
  208. public function pageSize($statusVariables)
  209. {
  210. if (!empty($statusVariables['pageSize'])) {
  211. $pageSize = (int) $statusVariables['pageSize'];
  212. if ($pageSize < 1) {
  213. $pageSize = 1;
  214. }
  215. return $pageSize;
  216. }
  217. return $this->config['pageSize'];
  218. }
  219. public function pagerSize()
  220. {
  221. return $this->config['pagerSize'];
  222. }
  223. public function idField()
  224. {
  225. if (!empty($this->config['idField'])) {
  226. return $this->config['idField'];
  227. } else {
  228. return 'id';
  229. }
  230. }
  231. public function tableName()
  232. {
  233. return ipTable(str_replace("`", "", $this->config['table']));
  234. }
  235. public function languageTableName()
  236. {
  237. $tableName = $this->rawTableName() . '_language';
  238. if (!empty($this->config['languageTable'])) {
  239. $tableName = $this->config['languageTable'];
  240. }
  241. return ipTable(str_replace("`", "", $tableName));
  242. }
  243. public function languageForeignKeyField()
  244. {
  245. $field = 'itemId';
  246. if (!empty($this->config['languageForeignKeyField'])) {
  247. $field = $this->config['languageForeignKeyField'];
  248. }
  249. return $field;
  250. }
  251. public function languageCodeField()
  252. {
  253. $field = 'language';
  254. if (!empty($this->config['languageCodeField'])) {
  255. $field = $this->config['languageCodeField'];
  256. }
  257. return $field;
  258. }
  259. public function selectFields()
  260. {
  261. if (empty($this->config['selectFields'])) {
  262. return '*';
  263. }
  264. return $this->config['selectFields'];
  265. }
  266. public function rawTableName()
  267. {
  268. return $this->config['table'];
  269. }
  270. public function rawLanguageTableName()
  271. {
  272. if (!empty($this->config['languageTable'])) {
  273. return $this->config['languageTable'];
  274. } else {
  275. return $this->rawTableName() . '_language';
  276. }
  277. }
  278. public function sortField()
  279. {
  280. if (empty($this->config['sortField'])) {
  281. return false;
  282. }
  283. return trim($this->config['sortField'], '`');
  284. }
  285. public function sortDirection()
  286. {
  287. if (empty($this->config['sortDirection'])) {
  288. return 'asc';
  289. }
  290. if ($this->config['sortDirection'] == 'desc') {
  291. return 'desc';
  292. } else {
  293. return 'asc';
  294. }
  295. }
  296. public function orderBy($statusVariables)
  297. {
  298. if (!empty($this->config['orderBy'])) {
  299. return $this->config['orderBy'];
  300. } else {
  301. $orderFieldName = $this->orderField($statusVariables);
  302. $orderField = $this->getField($orderFieldName);
  303. if (!empty($orderField['multilingual'])) {
  304. $table = $this->languageTableName();
  305. } else {
  306. $table = $this->tableName();
  307. }
  308. return $table . ".`" . $orderFieldName . "` " . $this->orderDirection($statusVariables);
  309. }
  310. }
  311. public function getField($fieldName)
  312. {
  313. $fields = $this->fields();
  314. foreach($fields as $field) {
  315. if (!empty($field['field']) && $field['field'] == $fieldName) {
  316. return $field;
  317. }
  318. }
  319. }
  320. public function orderField($statusVariables)
  321. {
  322. $manualOrder = false;
  323. //check if order field is set manually and if it is allowed to order by that field
  324. if (!empty($statusVariables['order'])) {
  325. $orderField = $statusVariables['order'];
  326. foreach($this->config['fields'] as $field) {
  327. if (!empty($field['field']) && $field['field'] == $orderField && (!isset($field['allowOrder']) || $field['allowOrder'])) {
  328. $manualOrder = true;
  329. break;
  330. }
  331. }
  332. }
  333. if ($manualOrder) {
  334. return $statusVariables['order'];
  335. } else {
  336. if ($this->sortField()) {
  337. return $this->sortField();
  338. } else {
  339. return $this->idField();
  340. }
  341. }
  342. }
  343. public function orderDirection($statusVariables)
  344. {
  345. if (!empty($statusVariables['direction']) && $statusVariables['direction'] == 'desc') {
  346. $direction = 'desc';
  347. } else {
  348. $direction = $this->sortDirection();
  349. }
  350. return $direction;
  351. }
  352. public function createPosition()
  353. {
  354. if (!empty($this->config['createPosition']) && $this->config['createPosition'] == 'bottom') {
  355. return 'bottom';
  356. }
  357. return 'top';
  358. }
  359. public function getTitle()
  360. {
  361. if (empty($this->config['title'])) {
  362. return $this->config['table'];
  363. }
  364. return $this->config['title'];
  365. }
  366. protected function getTableFields($tableName, $languageTable)
  367. {
  368. $result = array();
  369. $sql = "SHOW COLUMNS FROM " . $tableName . " " . $this->joinQuery() . " ";
  370. $fields = ipDb()->fetchColumn($sql);
  371. foreach ($fields as $fieldName) {
  372. $result[] = array(
  373. 'label' => $fieldName,
  374. 'field' => $fieldName
  375. );
  376. }
  377. if ($this->isMultilingual()) {
  378. $sql = "SHOW COLUMNS FROM " . $languageTable . " ";
  379. $fields = ipDb()->fetchColumn($sql);
  380. foreach ($fields as $fieldName) {
  381. if (in_array($fieldName, array($this->languageCodeField(), $this->languageForeignKeyField()))) {
  382. continue;
  383. }
  384. $result[] = array(
  385. 'label' => $fieldName,
  386. 'field' => $fieldName,
  387. 'multilingual' => 1
  388. );
  389. }
  390. }
  391. return $result;
  392. }
  393. public function joinQuery()
  394. {
  395. if (!empty($this->config['joinQuery'])) {
  396. return $this->config['joinQuery'];
  397. }
  398. return false;
  399. }
  400. public function layout()
  401. {
  402. if (empty($this->config['layout'])) {
  403. return 'Ip/Internal/Grid/view/layout.php';
  404. }
  405. return $this->config['layout'];
  406. }
  407. public function updateFilter()
  408. {
  409. if (empty($this->config['updateFilter'])) {
  410. return false;
  411. }
  412. return $this->config['updateFilter'];
  413. }
  414. public function updateLanguageFilter()
  415. {
  416. if (empty($this->config['updateLanguageFilter'])) {
  417. return false;
  418. }
  419. return $this->config['updateLanguageFilter'];
  420. }
  421. public function updateFormFilter()
  422. {
  423. if (empty($this->config['updateFormFilter'])) {
  424. return false;
  425. }
  426. return $this->config['updateFormFilter'];
  427. }
  428. public function createFilter()
  429. {
  430. if (empty($this->config['createFilter'])) {
  431. return false;
  432. }
  433. return $this->config['createFilter'];
  434. }
  435. public function createLanguageFilter()
  436. {
  437. if (empty($this->config['createLanguageFilter'])) {
  438. return false;
  439. }
  440. return $this->config['createLanguageFilter'];
  441. }
  442. public function createFormFilter()
  443. {
  444. if (empty($this->config['createFormFilter'])) {
  445. return false;
  446. }
  447. return $this->config['createFormFilter'];
  448. }
  449. /**
  450. * @param int $depth
  451. * @param array $gridBreadcrumb //to detect loop
  452. * @throws \Ip\Exception
  453. */
  454. protected function checkConfig(&$config, $depth = 1, $gridBreadcrumb = array())
  455. {
  456. $fields = &$config['fields'];
  457. if (!is_array($fields)) {
  458. throw new \Ip\Exception('GRID configuration is missing \'fields\' attribute for table ' . $config['table']);
  459. }
  460. foreach($fields as &$field) {
  461. if (empty($field['type'])) {
  462. $field['type'] = 'Text';
  463. }
  464. }
  465. //if at least one of the fields is of type 'Tab', then make sure the first field is also 'Tab'. Otherwise tabs don't work.
  466. if ($fields[0]['type'] != 'Tab') {
  467. $tabExist = false;
  468. foreach ($fields as $key => $fieldData) {
  469. if (!empty($fieldData['type']) && $fieldData['type'] == 'Tab') {
  470. $tabExist = true;
  471. break;
  472. }
  473. }
  474. if ($tabExist) {
  475. array_unshift($fields, array('label' => __('General', 'Ip-admin', false), 'type' => 'Tab'));
  476. }
  477. }
  478. //automatically add gridId to grid fields
  479. $gridIndex = 0;
  480. foreach ($fields as $key => &$fieldData) {
  481. if (!empty($fieldData['type']) && $fieldData['type'] == 'Grid') {
  482. $gridIndex++;
  483. if (empty($fieldData['gridId'])) {
  484. $fieldData['gridId'] = 'grid' . $gridIndex;
  485. }
  486. $subConfig = $fieldData['config'];
  487. $loop = false;
  488. foreach($gridBreadcrumb as $crumb) {
  489. if ($subConfig == $crumb) {
  490. $loop = true;
  491. }
  492. }
  493. if (!$loop) {
  494. $newBreadcrumb = array_merge($gridBreadcrumb, array($config));
  495. $this->checkConfig($fieldData['config'], $depth + 1, $newBreadcrumb);
  496. }
  497. }
  498. }
  499. if($depth == 1) {
  500. $this->configChecked = true;
  501. }
  502. }
  503. /**
  504. * Return nested grid config object
  505. * @param $statusVariables
  506. * @return Config
  507. * @throws \Ip\Exception
  508. */
  509. public function subgridConfig($statusVariables, $depthLimit = null)
  510. {
  511. $depth = Status::depth($statusVariables);
  512. if ($depthLimit !== null && $depthLimit < $depth) {
  513. $depth = $depthLimit;
  514. }
  515. $config = $this->config;
  516. for ($i = 1; $i < $depth; $i++) {
  517. $found = false;
  518. foreach ($config['fields'] as $field) {
  519. if (!empty($field['type']) && $field['type'] == 'Grid' && $field['gridId'] == $statusVariables['gridId' . $i]) {
  520. $config = $field['config'];
  521. $found = true;
  522. break;
  523. }
  524. }
  525. if (!$found) {
  526. throw new \Ip\Exception('Unknown subgrid');
  527. }
  528. }
  529. return new self($config);
  530. }
  531. public function getBreadcrumbField()
  532. {
  533. if (empty($this->config['breadcrumbField'])) {
  534. return '';
  535. }
  536. return $this->config['breadcrumbField'];
  537. }
  538. public function isMultilingual()
  539. {
  540. if ($this->multilingual !== null) {
  541. return $this->multilingual;
  542. }
  543. if (!empty($this->config['languageTable'])) {
  544. $this->multilingual = true;
  545. return true;
  546. }
  547. if (empty($this->config['fields'])) { //without this, isMultilingual check in getFields function will result in error.
  548. return false;
  549. }
  550. $fields = $this->fields();
  551. if (!$fields) {
  552. $this->multilingual = false;
  553. return false;
  554. }
  555. $multilingual = false;
  556. foreach($fields as $field) {
  557. if (!empty($field['multilingual'])) {
  558. $multilingual = true;
  559. break;
  560. }
  561. }
  562. $this->multilingual = $multilingual;
  563. return $multilingual;
  564. }
  565. }