FeatureAttrContextSelected.php 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. <?php
  2. // TODO: cron task - clear not used tables
  3. class FeatureAttrContextSelected {
  4. static function getIdContext($context) {
  5. try {
  6. $idContext = self::_fetchIdContext($context);
  7. } catch (Exception $e) {
  8. DBG::log($e);
  9. if ('42S02' == $e->getCode()) { // SQLSTATE[42S02]: Base table or view not found: 1146 Table 'SES_USERS2.CRM_@SELECTED_CONTEXT' doesn't exist
  10. self::_createContextTable();
  11. try {
  12. $idContext = self::_fetchIdContext($context);
  13. } catch (Exception $e) {
  14. DBG::log($e);
  15. if ('42S02' == $e->getCode()) { // SQLSTATE[42S02]: Base table or view not found: 1146 Table 'SES_USERS2.CRM_@SELECTED_CONTEXT' doesn't exist
  16. throw new Exception("Cannot create config table for @selected with context");
  17. }
  18. }
  19. DBG::log("DBG: Created config table for @selected with context");
  20. }
  21. }
  22. if (!$idContext) {
  23. try {
  24. $idContext = DB::getPDO()->insert('CRM__@SELECTED_CONTEXT', [ 'name' => $context, 'A_CREATE_TIME' => "NOW()", 'A_LAST_ACCESS_TIME' => "NOW()", 'A_LAST_UPDATE_TIME' => "NOW()" ]);
  25. DBG::log("DBG: created context ID:{$idContext} for: '{$context}'");
  26. } catch (Exception $e) {
  27. // TODO: if (cannot add new row - table full)
  28. throw $e;
  29. }
  30. } else {
  31. DBG::log("DBG: found context ID:{$idContext} for: '{$context}'");
  32. self::_updateLastAccessTime($idContext);
  33. }
  34. return $idContext;
  35. }
  36. static function _fetchIdContext($context) {
  37. return (int)DB::getPDO()->fetchValue("
  38. select ctx.id
  39. from `CRM__@SELECTED_CONTEXT` ctx
  40. where ctx.name = :name
  41. ", [ ':name' => $context ]);
  42. }
  43. static function _createContextTable() {
  44. DB::getPDO()->execSql("
  45. CREATE TABLE IF NOT EXISTS `CRM__@SELECTED_CONTEXT` (
  46. `ID` int(11) unsigned NOT NULL AUTO_INCREMENT,
  47. `name` varchar(32) NOT NULL,
  48. `A_CREATE_TIME` datetime,
  49. `A_LAST_ACCESS_TIME` datetime,
  50. `A_LAST_UPDATE_TIME` datetime,
  51. PRIMARY KEY (`ID`),
  52. UNIQUE KEY `name` (`name`)
  53. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  54. ");
  55. }
  56. static function _updateLastAccessTime($idContext) {
  57. DB::getPDO()->update('CRM__@SELECTED_CONTEXT', 'ID', $idContext, [ 'A_LAST_ACCESS_TIME' => "NOW()" ]);
  58. }
  59. static function _updateLastUpdateTime($idContext) {
  60. DB::getPDO()->update('CRM__@SELECTED_CONTEXT', 'ID', $idContext, [ 'A_LAST_UPDATE_TIME' => "NOW()" ]);
  61. }
  62. static function getTotalSelected($idContext, $typeName) {
  63. $idUser = User::getID();
  64. self::prepareUserTable($idContext, $typeName, $idUser);
  65. self::_updateLastAccessTime($idContext);
  66. $tableName = self::getAttributeTableName($idContext, $typeName, $idUser);
  67. return (int)DB::getPDO()->fetchValue("
  68. select count(*) as total
  69. from `{$tableName}`
  70. ");
  71. }
  72. static function getSelectState($idContext, $typeName, array $listPrimaryKeys) {
  73. $idUser = User::getID();
  74. self::prepareUserTable($idContext, $typeName, $idUser);
  75. self::_updateLastAccessTime($idContext);
  76. $tableName = self::getAttributeTableName($idContext, $typeName, $idUser);
  77. if (empty($listPrimaryKeys)) return [];
  78. $dbQuote = [ DB::getPDO(), 'quote' ];
  79. $sqlPks = implode(", ", array_map(function ($pk) use ($dbQuote) {
  80. return $dbQuote($pk);
  81. }, $listPrimaryKeys));
  82. $selected = DB::getPDO()->fetchValuesListByKey("
  83. select primaryKey
  84. from `{$tableName}`
  85. where primaryKey in ( {$sqlPks} )
  86. ", $key = 'primaryKey');
  87. return array_combine($listPrimaryKeys, array_map(function ($pk) use ($selected) {
  88. return in_array($pk, $selected);
  89. }, $listPrimaryKeys));
  90. }
  91. static function selectAllByFilter($idContext, $typeName, array $filterQuery) {
  92. $idUser = User::getID();
  93. self::prepareUserTable($idContext, $typeName, $idUser);
  94. $tableName = self::getAttributeTableName($idContext, $typeName, $idUser);
  95. $acl = ACL::getAclByTypeName($typeName);
  96. $args = [];
  97. parse_str($filterQuery[0], $args);
  98. DBG::log(['$filterQuery' => $filterQuery, '$args' => $args], 'array', "DBG: selectAllByFilter");
  99. $params = [];
  100. $params['limit'] = 0;
  101. $params['cols'] = [ $acl->getPrimaryKeyField() ];
  102. foreach ($args as $k => $v) {
  103. if (strlen($k) > 3 && substr($k, 0, 2) == 'f_' && strlen($v) > 0) {// filter prefix
  104. $params[$k] = $v;
  105. }
  106. else if (strlen($k) > 4 && substr($k, 0, 3) == 'sf_' && strlen($v) > 0) {// special filter prefix
  107. $params[$k] = $v;
  108. }
  109. }
  110. $queryFeatures = $acl->buildQuery($params);
  111. DBG::log($queryFeatures, 'array', '$queryFeatures');
  112. try {
  113. $sql = $queryFeatures->getRawQueryPrimaryKeys();
  114. DBG::log($sql, 'string', 'sql getRawQueryPrimaryKeys');
  115. Lib::loadClass('FeatureAttrSelected');
  116. $userSelectedTableName = FeatureAttrSelected::getAttributeTableName($idContext, $typeName = $acl->getNamespace(), $idUser = User::getID());
  117. DB::getPDO()->execSql("
  118. insert ignore into `{$userSelectedTableName}` (`primaryKey`)
  119. select `selectedTable`.`@primaryKey`
  120. from ( {$sql} ) as `selectedTable`
  121. ");
  122. } catch (Exception $e) {
  123. DBG::log($e);
  124. DBG::log('legacyMode - execute query for all primary keys');
  125. $listItems = $queryFeatures->getItems();
  126. $listPrimaryKeys = array_map(function ($item) {
  127. return $item['ID'];
  128. }, $listItems);
  129. foreach ($listPrimaryKeys as $pk) {
  130. DB::getPDO()->execSql(" insert ignore `{$tableName}` (`primaryKey`) values ( :pk ) ", [ ':pk' => $pk ]);
  131. }
  132. }
  133. self::_updateLastUpdateTime($idContext);
  134. }
  135. static function select($idContext, $typeName, array $listPrimaryKeys) {
  136. $idUser = User::getID();
  137. self::prepareUserTable($idContext, $typeName, $idUser);
  138. $tableName = self::getAttributeTableName($idContext, $typeName, $idUser);
  139. foreach ($listPrimaryKeys as $pk) {
  140. DB::getPDO()->execSql(" insert ignore `{$tableName}` (`primaryKey`) values ( :pk ) ", [ ':pk' => $pk ]);
  141. }
  142. self::_updateLastUpdateTime($idContext);
  143. }
  144. static function unselect($idContext, $typeName, array $listPrimaryKeys) {
  145. $idUser = User::getID();
  146. self::prepareUserTable($idContext, $typeName, $idUser);
  147. $tableName = self::getAttributeTableName($idContext, $typeName, $idUser);
  148. foreach ($listPrimaryKeys as $pk) {
  149. DB::getPDO()->execSql(" delete from `{$tableName}` where `primaryKey` = :pk ", [ ':pk' => $pk ]);
  150. }
  151. self::_updateLastUpdateTime($idContext);
  152. }
  153. static function unselectAll($idContext, $typeName) {
  154. $idUser = User::getID();
  155. self::prepareUserTable($idContext, $typeName, $idUser);
  156. $tableName = self::getAttributeTableName($idContext, $typeName, $idUser);
  157. DB::getPDO()->execSql(" truncate table `{$tableName}` ");
  158. self::_updateLastUpdateTime($idContext);
  159. }
  160. static function prepareUserTable($idContext, $typeName, $idUser) {
  161. static $_created = [];
  162. $key = "{$typeName}-{$idContext}-{$idUser}";
  163. if (!array_key_exists($key, $_created)) {
  164. self::_prepareUserTable($idContext, $typeName, $idUser);
  165. $_created[$key] = true;
  166. }
  167. }
  168. static function _prepareUserTable($idContext, $typeName, $idUser) {
  169. $tableName = self::getAttributeTableName($idContext, $typeName, $idUser);
  170. // TODO: primaryKey type from $acl
  171. DB::getPDO()->execSql("
  172. CREATE TABLE IF NOT EXISTS `{$tableName}` (
  173. `primaryKey` int(11) NOT NULL,
  174. UNIQUE KEY `primaryKey` (`primaryKey`)
  175. ) ENGINE=MyISAM DEFAULT CHARSET=latin2;
  176. ");
  177. }
  178. // @example FeatureAttrSelected::getAttributeTableName($typeName, $idUser);
  179. static function getAttributeTableName($idContext, $typeName, $idUser) {
  180. static $_created = [];
  181. $key = "{$typeName}-{$idUser}";
  182. if (!array_key_exists($key, $_created)) {
  183. $_created[$key] = self::_getAttributeTableName($idContext, $typeName, $idUser);
  184. }
  185. return $_created[$key];
  186. }
  187. static function _getAttributeTableName($idContext, $typeName, $idUser) {
  188. $acl = ACL::getAclByTypeName($typeName);
  189. $rootTableName = $acl->getRootTableName();
  190. return "{$rootTableName}__@sel_{$idContext}_{$idUser}";
  191. }
  192. }