BxMarketDb.php 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763
  1. <?php defined('BX_DOL') or die('hack attempt');
  2. /**
  3. * Copyright (c) UNA, Inc - https://una.io
  4. * MIT License - https://opensource.org/licenses/MIT
  5. *
  6. * @defgroup Market Market
  7. * @ingroup UnaModules
  8. *
  9. * @{
  10. */
  11. /*
  12. * Module database queries
  13. */
  14. class BxMarketDb extends BxBaseModTextDb
  15. {
  16. protected $_aRecurringDurations;
  17. function __construct(&$oConfig)
  18. {
  19. parent::__construct($oConfig);
  20. $this->_aRecurringDurations = array(
  21. 'day' => 'INTERVAL 1 DAY',
  22. 'week' => 'INTERVAL 7 DAY',
  23. 'month' => 'INTERVAL 1 MONTH',
  24. 'year' => 'INTERVAL 1 YEAR',
  25. );
  26. }
  27. public function getProductsNames ($iVendor = 0, $iLimit = 1000)
  28. {
  29. $CNF = &$this->_oConfig->CNF;
  30. $sWhere = '';
  31. $aBindings = array('limit' => $iLimit);
  32. if ($iVendor) {
  33. $aBindings['author'] = $iVendor;
  34. $sWhere .= "AND `{$CNF['FIELD_AUTHOR']} = :author`";
  35. }
  36. return $this->getColumn("SELECT `{$CNF['FIELD_NAME']}` FROM `{$CNF['TABLE_ENTRIES']}` WHERE (`{$CNF['FIELD_PRICE_SINGLE']}` != '0' OR `{$CNF['FIELD_PRICE_RECURRING']}` != '0') $sWhere LIMIT :limit", $aBindings);
  37. }
  38. public function getContentInfoBy ($aParams)
  39. {
  40. $CNF = &$this->_oConfig->CNF;
  41. $aMethod = array('name' => 'getAll', 'params' => array(0 => 'query'));
  42. $aOrderWay = array('up' => 'ASC', 'down' => 'DESC');
  43. $sFieldsClause = $sJoinClause = $sWhereClause = $sGroupClause = $sOrderClause = $sLimitClause = '';
  44. //--- Add file info.
  45. $sFieldsClause .= " `te`.`" . $CNF['FIELD_PACKAGE'] . "` AS `file_id`, `tf`.`file_name` AS `file_name`, `tfe`.`version` AS `file_version`, ";
  46. $sJoinClause .= " LEFT JOIN `" . $CNF['TABLE_FILES2ENTRIES'] . "` AS `tfe` ON `te`.`" . $CNF['FIELD_ID'] . "`=`tfe`.`content_id` AND `te`.`" . $CNF['FIELD_PACKAGE'] . "`=`tfe`.`file_id` LEFT JOIN `" . $CNF['TABLE_FILES'] . "` AS `tf` ON `te`.`" . $CNF['FIELD_PACKAGE'] . "`=`tf`.`id` ";
  47. //--- Add license checking for Public listings if Client is specified.
  48. if(in_array($aParams['type'], array('latest', 'popular', 'featured', 'category', 'tag', 'vendor', 'keyword')) && isset($aParams['client']) && (int)$aParams['client'] != 0) {
  49. //--- Direct license purchase for a product
  50. $sLicDir = $this->prepareAsString("SELECT `tl`.`added` FROM `" . $CNF['TABLE_LICENSES'] . "` AS `tl` WHERE `tl`.`product_id`=`te`.`" . $CNF['FIELD_ID'] . "` AND `tl`.`profile_id`=? AND (`tl`.`domain`=?" . (empty($aParams['key_assigned']) ? " OR `tl`.`domain`=''" : "") . ") LIMIT 1", (int)$aParams['client'], $aParams['key']);
  51. //--- License got with package purchase
  52. $oConnnection = BxDolConnection::getObjectInstance($CNF['OBJECT_CONNECTION_SUBENTRIES']);
  53. $aConnectionSql = $oConnnection->getConnectedInitiatorsAsSQLPartsMultiple('tl', 'product_id', 'te', $CNF['FIELD_ID']);
  54. $sLicPack = $this->prepareAsString("SELECT `tl`.`added` FROM `" . $CNF['TABLE_LICENSES'] . "` AS `tl` " . $aConnectionSql['join'] . " WHERE 1 " . $aConnectionSql['where'] . " AND `tl`.`profile_id`=? AND (`tl`.`domain`=?" . (empty($aParams['key_assigned']) ? " OR `tl`.`domain`=''" : "") . ") LIMIT 1", (int)$aParams['client'], $aParams['key']);
  55. $sFieldsClause .= " ((" . $sLicDir . ") OR (" . $sLicPack . ")) AS `purchased_on`, ";
  56. }
  57. //--- Include content by ids or names
  58. if(!empty($aParams['include_by']) && in_array($aParams['include_by'], array('id', 'name')) && !empty($aParams['include_values']))
  59. $sWhereClause .= " AND `te`.`" . $aParams['include_by'] . "` IN (" . $this->implode_escape($aParams['include_values']) . ") ";
  60. //--- Exclude content by ids or names
  61. if(!empty($aParams['exclude_by']) && in_array($aParams['exclude_by'], array('id', 'name')) && !empty($aParams['exclude_values']))
  62. $sWhereClause .= " AND `te`.`" . $aParams['exclude_by'] . "` NOT IN (" . $this->implode_escape($aParams['exclude_values']) . ") ";
  63. //--- Attach custom queries described with field - value pairs.
  64. if(!empty($aParams['custom_and']) && is_array($aParams['custom_and']))
  65. $sWhereClause .= " AND (" . $this->arrayToSQL($aParams['custom_and'], ' AND ') . ") ";
  66. if(!empty($aParams['custom_or']) && is_array($aParams['custom_or']))
  67. $sWhereClause .= " AND (" . $this->arrayToSQL($aParams['custom_or'], ' OR ') . ") ";
  68. //--- Exclude inactive authors
  69. if(!empty($aParams['exclude_inactive_authors']))
  70. $sJoinClause .= " INNER JOIN `sys_profiles` AS `tp` ON `te`.`author`=`tp`.`id` AND `tp`.`status`='active'";
  71. if(isset($aParams['start']) && !empty($aParams['per_page']))
  72. $sLimitClause = $aParams['start'] . ", " . $aParams['per_page'];
  73. switch($aParams['type']) {
  74. case 'id':
  75. $aMethod['name'] = 'getRow';
  76. $sFieldsClause .= "";
  77. $sJoinClause .= "";
  78. $sWhereClause .= $this->prepareAsString(" AND `te`.`" . $CNF['FIELD_ID'] . "`=? ", $aParams['value']);
  79. $sOrderClause .= "";
  80. break;
  81. case 'name':
  82. $aMethod['name'] = 'getRow';
  83. $sFieldsClause .= "";
  84. $sJoinClause .= "";
  85. $sWhereClause .= $this->prepareAsString(" AND `te`.`" . $CNF['FIELD_NAME'] . "`=? ", $aParams['value']);
  86. $sOrderClause .= "";
  87. break;
  88. case 'file_id':
  89. $aMethod['name'] = 'getRow';
  90. $sFieldsClause .= "";
  91. $sJoinClause .= "";
  92. $sWhereClause .= $this->prepareAsString(" AND `te`.`" . $CNF['FIELD_PACKAGE'] . "`=? ", $aParams['value']);
  93. $sOrderClause .= "";
  94. break;
  95. case 'latest':
  96. $sFieldsClause .= "";
  97. $sJoinClause .= "";
  98. $sWhereClause .= "";
  99. $sOrderClause = "`te`.`added` " . (isset($aParams['order_way']) ? $aOrderWay[$aParams['order_way']] : "DESC");
  100. break;
  101. case 'featured':
  102. $sFieldsClause .= "";
  103. $sJoinClause .= "";
  104. $sWhereClause .= " AND `te`.`" . $CNF['FIELD_FEATURED'] . "`<>0";
  105. $sOrderClause = "`te`.`" . $CNF['FIELD_FEATURED'] . "` " . (isset($aParams['order_way']) ? $aOrderWay[$aParams['order_way']] : "DESC");
  106. break;
  107. case 'popular':
  108. $sFieldsClause .= "";
  109. $sJoinClause .= "";
  110. $sWhereClause .= "";
  111. $sOrderClause = "`te`.`views` " . (isset($aParams['order_way']) ? $aOrderWay[$aParams['order_way']] : "DESC");
  112. break;
  113. case 'selected':
  114. $sFieldsClause .= "";
  115. $sJoinClause .= "";
  116. $sWhereClause .= " AND `te`.`id` IN (" . $this->implode_escape($aParams['selected']) . ") ";
  117. $sOrderClause = "`te`.`added` " . (isset($aParams['order_way']) ? $aOrderWay[$aParams['order_way']] : "DESC");
  118. break;
  119. case 'category':
  120. if(!is_array($aParams['value']))
  121. $aParams['value'] = array($aParams['value']);
  122. $sFieldsClause .= "";
  123. $sJoinClause .= "";
  124. $sWhereClause .= " AND `te`.`" . $CNF['FIELD_CATEGORY'] . "` IN (" . $this->implode_escape($aParams['value']) . ")";
  125. $sOrderClause = "`te`.`added` " . (isset($aParams['order_way']) ? $aOrderWay[$aParams['order_way']] : "DESC");
  126. break;
  127. case 'tag':
  128. $sFieldsClause .= "";
  129. $aSql = BxDolMetatags::getObjectInstance($CNF['OBJECT_METATAGS'])->keywordsGetAsSQLPart('te', $CNF['FIELD_ID'], $aParams['value']);
  130. if(!empty($aSql['where'])) {
  131. $sWhereClause .= $aSql['where'];
  132. if(!empty($aSql['join']))
  133. $sJoinClause .= $aSql['join'];
  134. }
  135. $sOrderClause = "`te`.`added` " . (isset($aParams['order_way']) ? $aOrderWay[$aParams['order_way']] : "DESC");
  136. break;
  137. case 'vendor':
  138. $sFieldsClause .= "";
  139. $sJoinClause .= "";
  140. $sWhereClause .= $this->prepareAsString(" AND `te`.`" . $CNF['FIELD_AUTHOR'] . "`=? ", (int)$aParams['value']);
  141. if(isset($aParams['paid']) && (int)$aParams['paid'] == 1)
  142. $sWhereClause .= " AND `te`.`" . $CNF['FIELD_PRICE_SINGLE'] . "`<>'0' AND `te`.`" . $CNF['FIELD_PRICE_RECURRING'] . "`<>'0'";
  143. $sOrderClause = "`te`.`" . (isset($aParams['order_by']) ? $aParams['order_by'] : "added") . "` " . (isset($aParams['order_way']) ? $aOrderWay[$aParams['order_way']] : "DESC");
  144. break;
  145. case 'keyword':
  146. if(getParam('useLikeOperator') == 'on') {
  147. $sKeyword = $this->escape('%' . preg_replace('/\s+/', '%', $aParams['value']) . '%');
  148. $aWhereSubclause = [];
  149. foreach ([$CNF['FIELD_TITLE'], $CNF['FIELD_TEXT']] as $sField)
  150. $aWhereSubclause []= "`" . $sField . "` LIKE " . $sKeyword;
  151. $sWhereClause .= ' AND (' . implode(' OR ', $aWhereSubclause) . ')';
  152. }
  153. else {
  154. $sFieldsClause .= $this->prepareAsString(" MATCH(`" . $CNF['FIELD_TITLE'] . "`, `" . $CNF['FIELD_TEXT'] . "`) AGAINST (?) AS `search_condition`, ", $aParams['value']);
  155. $sWhereClause .= $this->prepareAsString(" AND MATCH(`" . $CNF['FIELD_TITLE'] . "`, `" . $CNF['FIELD_TEXT'] . "`) AGAINST (?) ", $aParams['value']);
  156. $sOrderClause = "`search_condition` " . (isset($aParams['order_way']) ? $aOrderWay[$aParams['order_way']] : "DESC");
  157. }
  158. break;
  159. case 'granted':
  160. $sFieldsClause .= " '" . $aParams['license']['license'] . "' AS `license`, '" . $aParams['license']['profile_id'] . "' AS `purchased_by`, '' AS `purchased_for`, '" . $aParams['license']['added'] . "' AS `purchased_on`, ";
  161. $sWhereClause .= $this->prepareAsString(" AND `te`.`" . $CNF['FIELD_AUTHOR'] . "`=? AND (`te`.`" . $CNF['FIELD_PRICE_SINGLE'] . "`<>'0' OR `te`.`" . $CNF['FIELD_PRICE_RECURRING'] . "`<>'0') ", (int)$aParams['value']);
  162. $sOrderClause = "`te`.`added` " . (isset($aParams['order_way']) ? $aOrderWay[$aParams['order_way']] : "DESC");
  163. break;
  164. case 'purchased':
  165. $sFieldsClause .= " `tl`.`license` AS `license`, `tl`.`profile_id` AS `purchased_by`, `tl`.`domain` AS `purchased_for`, `tl`.`added` AS `purchased_on`, ";
  166. if(isset($aParams['package']) && (int)$aParams['package'] == 1) {
  167. $oConnnection = BxDolConnection::getObjectInstance($CNF['OBJECT_CONNECTION_SUBENTRIES']);
  168. $aConnectionSql = $oConnnection->getConnectedContentAsSQLPartsMultiple('te', $CNF['FIELD_ID'], 'tl', 'product_id');
  169. $sJoinClause .= " " . $aConnectionSql['join'] . " LEFT JOIN `" . $CNF['TABLE_LICENSES'] . "` AS `tl` ON " . trim($aConnectionSql['where'], " AND ") . " ";
  170. }
  171. else
  172. $sJoinClause .= " LEFT JOIN `" . $CNF['TABLE_LICENSES'] . "` AS `tl` ON `te`.`" . $CNF['FIELD_ID'] . "`=`tl`.`product_id` ";
  173. $sWhereClause .= $this->prepareAsString(" AND `tl`.`profile_id`=? AND (`tl`.`domain`=?" . (empty($aParams['key_assigned']) ? " OR `tl`.`domain`=''" : "") . ") ", (int)$aParams['client'], $aParams['key']);
  174. $sGroupClause .= "`te`.`" . $CNF['FIELD_ID'] . "`";
  175. $sOrderClause = "`tl`.`added` " . (isset($aParams['order_way']) ? $aOrderWay[$aParams['order_way']] : "DESC");
  176. break;
  177. }
  178. $sGroupClause = $sGroupClause ? "GROUP BY " . $sGroupClause : "";
  179. $sOrderClause = $sOrderClause ? "ORDER BY " . $sOrderClause : "";
  180. $sLimitClause = $sLimitClause ? "LIMIT " . $sLimitClause : "";
  181. $aMethod['params'][0] = "SELECT " . $sFieldsClause . "`te`.*
  182. FROM `" . $CNF['TABLE_ENTRIES'] . "` AS `te`" . $sJoinClause . "
  183. WHERE 1" . $sWhereClause . " " . $sGroupClause . " " . $sOrderClause . " " . $sLimitClause;
  184. return call_user_func_array(array($this, $aMethod['name']), $aMethod['params']);
  185. }
  186. public function getContentInfoByName ($sContentName)
  187. {
  188. $sQuery = $this->prepare ("SELECT * FROM `" . $this->_oConfig->CNF['TABLE_ENTRIES'] . "` WHERE `" . $this->_oConfig->CNF['FIELD_NAME'] . "` = ?", $sContentName);
  189. return $this->getRow($sQuery);
  190. }
  191. public function updateContentInfoBy ($aSet, $aWhere)
  192. {
  193. $sQuery = "UPDATE `" . $this->_oConfig->CNF['TABLE_ENTRIES'] . "` SET " . $this->arrayToSQL($aSet) . " WHERE " . (!empty($aWhere) ? $this->arrayToSQL($aWhere, ' AND ') : "1");
  194. return (int)$this->query($sQuery) > 0;
  195. }
  196. public function getPhoto($aParams = array())
  197. {
  198. return $this->_getAttachment($this->_oConfig->CNF['TABLE_PHOTOS2ENTRIES'], $aParams);
  199. }
  200. public function updatePhoto($aSet, $aWhere)
  201. {
  202. return $this->_updateAttachment($this->_oConfig->CNF['TABLE_PHOTOS2ENTRIES'], $aSet, $aWhere);
  203. }
  204. public function getFile($aParams = array())
  205. {
  206. return $this->_getAttachment($this->_oConfig->CNF['TABLE_FILES2ENTRIES'], $aParams);
  207. }
  208. public function updateFile($aSet, $aWhere)
  209. {
  210. return $this->_updateAttachment($this->_oConfig->CNF['TABLE_FILES2ENTRIES'], $aSet, $aWhere);
  211. }
  212. public function associatePhotoWithContent($iContentId, $iFileId, $sTitle)
  213. {
  214. $sQuery = $this->prepare ("SELECT MAX(`order`) FROM `" . $this->_oConfig->CNF['TABLE_PHOTOS2ENTRIES'] . "` WHERE `content_id` = ?", $iContentId);
  215. $iOrder = 1 + (int)$this->getOne($sQuery);
  216. $sQuery = $this->prepare ("INSERT INTO `" . $this->_oConfig->CNF['TABLE_PHOTOS2ENTRIES'] . "` SET `content_id` = ?, `file_id` = ?, `title` = ?, `order` = ? ON DUPLICATE KEY UPDATE `title` = ?", $iContentId, $iFileId, $sTitle, $iOrder, $sTitle);
  217. return $this->res($sQuery);
  218. }
  219. public function deassociatePhotoWithContent($iContentId, $iFileId)
  220. {
  221. return $this->_deassociateAttachmentWithContent($this->_oConfig->CNF['TABLE_PHOTOS2ENTRIES'], $iContentId, $iFileId);
  222. }
  223. public function associateFileWithContent($iContentId, $iFileId, $aParams)
  224. {
  225. $sQuery = $this->prepare ("SELECT MAX(`order`) FROM `" . $this->_oConfig->CNF['TABLE_FILES2ENTRIES'] . "` WHERE `content_id` = ?", $iContentId);
  226. $iOrder = 1 + (int)$this->getOne($sQuery);
  227. $aBindings = array_merge(array(
  228. 'content_id' => $iContentId,
  229. 'file_id' => $iFileId,
  230. 'order' => $iOrder,
  231. ), $aParams);
  232. $sDiv = ", ";
  233. $sParams = "";
  234. foreach($aParams as $sKey => $mixedValue)
  235. $sParams .= "`" . $sKey . "` = :" . $sKey . $sDiv;
  236. $sParams = trim($sParams, $sDiv);
  237. $sQuery = $this->prepare("INSERT INTO `" . $this->_oConfig->CNF['TABLE_FILES2ENTRIES'] . "` SET `content_id` = :content_id, `file_id` = :file_id, " . $sParams . ", `order` = :order ON DUPLICATE KEY UPDATE " . $sParams);
  238. return $this->res($sQuery, $aBindings);
  239. }
  240. public function deassociateFileWithContent($iContentId, $iFileId)
  241. {
  242. return $this->_deassociateAttachmentWithContent($this->_oConfig->CNF['TABLE_FILES2ENTRIES'], $iContentId, $iFileId);
  243. }
  244. public function insertDownload($iFileId, $iProfileId, $iProfileNip)
  245. {
  246. $sQuery = $this->prepare("INSERT IGNORE INTO `" . $this->_oConfig->CNF['TABLE_DOWNLOADS'] . "` SET `file_id` = ?, `profile_id` = ?, `profile_nip` = ?, `date` = UNIX_TIMESTAMP()", $iFileId, $iProfileId, $iProfileNip);
  247. return (int)$this->query($sQuery) > 0;
  248. }
  249. /**
  250. * Integration with Payment based modules.
  251. */
  252. public function getLicense($aParams = array())
  253. {
  254. $CNF = &$this->_oConfig->CNF;
  255. $aMethod = array('name' => 'getAll', 'params' => array(0 => 'query'));
  256. $sSelectClause = "`tl`.*";
  257. $sJoinClause = $sWhereClause = $sLimitClause = "";
  258. switch($aParams['type']) {
  259. case 'id':
  260. $aMethod['name'] = 'getRow';
  261. $aMethod['params'][1] = array(
  262. 'id' => $aParams['id']
  263. );
  264. $sWhereClause = " AND `tl`.`id`=:id";
  265. break;
  266. case 'license':
  267. $aMethod['name'] = 'getRow';
  268. $aMethod['params'][1] = array(
  269. 'license' => $aParams['license']
  270. );
  271. $sWhereClause = " AND `tl`.`license`=:license";
  272. break;
  273. case 'new':
  274. $aMethod['params'][1] = array(
  275. 'profile_id' => $aParams['profile_id']
  276. );
  277. $sWhereClause = " AND `tl`.`profile_id`=:profile_id AND `tl`.`new`='1'";
  278. break;
  279. case 'order':
  280. $aMethod['params'][1] = array(
  281. 'order' => $aParams['order']
  282. );
  283. $sWhereClause = " AND `tl`.`order`=:order";
  284. if(isset($aParams['used']) && $aParams['used'] == true)
  285. $sWhereClause .= " AND `tl`.`domain` <> ''";
  286. if(isset($aParams['unused']) && $aParams['unused'] == true)
  287. $sWhereClause .= " AND `tl`.`domain` = ''";
  288. break;
  289. case 'unused':
  290. $aMethod['params'][1] = array(
  291. 'profile_id' => $aParams['profile_id']
  292. );
  293. $sWhereClause = " AND `tl`.`profile_id`=:profile_id AND `tl`.`domain`=''";
  294. break;
  295. case 'expired':
  296. $aMethod['params'][1] = array(
  297. 'type' => BX_MARKET_LICENSE_TYPE_RECURRING
  298. );
  299. $sWhereClause = " AND `type` = :type AND `added` < UNIX_TIMESTAMP() AND `expired` <> 0 AND `expired` < UNIX_TIMESTAMP()";
  300. break;
  301. case 'product_id':
  302. $aMethod['params'][1] = array(
  303. 'product_id' => $aParams['product_id']
  304. );
  305. $sWhereClause = " AND `tl`.`product_id`=:product_id";
  306. if(!empty($aParams['profile_id'])) {
  307. $aMethod['params'][1]['profile_id'] = $aParams['profile_id'];
  308. $sWhereClause .= " AND `tl`.`profile_id`=:profile_id";
  309. }
  310. break;
  311. case 'profile_id':
  312. $aMethod['params'][1] = array(
  313. 'profile_id' => $aParams['profile_id']
  314. );
  315. $sWhereClause = " AND `tl`.`profile_id`=:profile_id";
  316. if(!empty($aParams['product_id'])) {
  317. $aMethod['params'][1]['product_id'] = $aParams['product_id'];
  318. $sWhereClause .= " AND `tl`.`product_id`=:product_id";
  319. }
  320. break;
  321. case 'profile_id_file_id_key':
  322. $aMethod['name'] = "getRow";
  323. $aMethod['params'][1] = array(
  324. 'profile_id' => $aParams['profile_id'],
  325. 'key' => $aParams['key']
  326. );
  327. $iProductId = $this->getOne("SELECT `te`.`" . $CNF['FIELD_ID'] . "` FROM `" . $CNF['TABLE_ENTRIES'] . "` AS `te` LEFT JOIN `" . $CNF['TABLE_FILES2ENTRIES'] . "` AS `tfe` ON `te`.`id`=`tfe`.`content_id` WHERE `tfe`.`file_id`=:file_id LIMIT 1", array(
  328. 'file_id' => $aParams['file_id']
  329. ));
  330. if(isset($aParams['package']) && (int)$aParams['package'] == 1) {
  331. $oConnnection = BxDolConnection::getObjectInstance($CNF['OBJECT_CONNECTION_SUBENTRIES']);
  332. $aConnectionSql = $oConnnection->getConnectedInitiatorsAsSQLParts('tl', 'product_id', $iProductId);
  333. $sJoinClause .= $aConnectionSql['join'];
  334. }
  335. else {
  336. $aMethod['params'][1]['product_id'] = $iProductId;
  337. $sWhereClause .= " AND `tl`.`product_id`=:product_id";
  338. }
  339. $sWhereClause .= " AND `tl`.`profile_id`=:profile_id AND (`tl`.`domain`='' OR `tl`.`domain`=:key)";
  340. $sLimitClause = "1";
  341. break;
  342. case 'has_by':
  343. $aMethod['name'] = "getOne";
  344. $aMethod['params'][1] = array(
  345. 'profile_id' => $aParams['profile_id']
  346. );
  347. $sSelectClause = "`tl`.`id`";
  348. $sWhereClause = " AND `tl`.`profile_id`=:profile_id";
  349. if(isset($aParams['package']) && (int)$aParams['package'] == 1) {
  350. $oConnnection = BxDolConnection::getObjectInstance($CNF['OBJECT_CONNECTION_SUBENTRIES']);
  351. $aConnectionSql = $oConnnection->getConnectedInitiatorsAsSQLParts('tl', 'product_id', $aParams['product_id']);
  352. $sJoinClause .= $aConnectionSql['join'];
  353. }
  354. else {
  355. $aMethod['params'][1]['product_id'] = $aParams['product_id'];
  356. $sWhereClause .= " AND `tl`.`product_id`=:product_id";
  357. }
  358. if(!empty($aParams['domain'])) {
  359. $aMethod['params'][1]['domain'] = $aParams['domain'];
  360. $sWhereClause .= " AND `tl`.`domain`=:domain";
  361. }
  362. if(!empty($aParams['order'])) {
  363. $aMethod['params'][1]['order'] = $aParams['order'];
  364. $sWhereClause .= " AND `tl`.`order`=:order";
  365. }
  366. $sLimitClause = "1";
  367. break;
  368. }
  369. $sLimitClause = !empty($sLimitClause) ? "LIMIT " . $sLimitClause : $sLimitClause;
  370. $aMethod['params'][0] = "SELECT
  371. " . $sSelectClause . "
  372. FROM `" . $this->_oConfig->CNF['TABLE_LICENSES'] . "` AS `tl`" . $sJoinClause . "
  373. WHERE 1" . $sWhereClause . " " . $sLimitClause;
  374. return call_user_func_array(array($this, $aMethod['name']), $aMethod['params']);
  375. }
  376. public function updateLicense($aSet, $aWhere)
  377. {
  378. $CNF = &$this->_oConfig->CNF;
  379. return $this->query("UPDATE `" . $CNF['TABLE_LICENSES'] . "` SET " . $this->arrayToSQL($aSet) . " WHERE " . (!empty($aWhere) ? $this->arrayToSQL($aWhere, ' AND ') : "1"));
  380. }
  381. public function deleteLicense($aWhere)
  382. {
  383. if(empty($aWhere))
  384. return false;
  385. $sQuery = "DELETE FROM `" . $this->_oConfig->CNF['TABLE_LICENSES'] . "` WHERE " . $this->arrayToSQL($aWhere, ' AND ');
  386. return (int)$this->query($sQuery) > 0;
  387. }
  388. public function hasLicense ($iProfileId, $iProductId, $sDomain = '')
  389. {
  390. $aParams = array(
  391. 'type' => 'has_by',
  392. 'profile_id' => $iProfileId,
  393. 'product_id' => $iProductId,
  394. 'domain' => !empty($sDomain) ? $sDomain : ''
  395. );
  396. $iLicenseId = (int)$this->getLicense($aParams);
  397. if($iLicenseId > 0)
  398. return true;
  399. $aParams['package'] = 1;
  400. $iLicenseId = (int)$this->getLicense($aParams);
  401. if($iLicenseId > 0)
  402. return true;
  403. return false;
  404. }
  405. public function hasLicenseByOrder ($iProfileId, $iProductId, $sOrder = '')
  406. {
  407. $aParams = array(
  408. 'type' => 'has_by',
  409. 'profile_id' => $iProfileId,
  410. 'product_id' => $iProductId,
  411. 'order' => !empty($sOrder) ? $sOrder : ''
  412. );
  413. $iLicenseId = (int)$this->getLicense($aParams);
  414. if($iLicenseId > 0)
  415. return true;
  416. $aParams['package'] = 1;
  417. $iLicenseId = (int)$this->getLicense($aParams);
  418. if($iLicenseId > 0)
  419. return true;
  420. return false;
  421. }
  422. public function registerLicense($iProfileId, $iProductId, $iCount, $sOrder, $sLicense, $sType, $sDuration = '', $iTrial = 0)
  423. {
  424. $CNF = &$this->_oConfig->CNF;
  425. $oPayments = BxDolPayments::getInstance();
  426. $iProcessed = 0;
  427. for($i = 0; $i < $iCount; $i++) {
  428. $aQueryParams = array(
  429. 'profile_id' => $iProfileId,
  430. 'product_id' => $iProductId,
  431. 'count' => 1,
  432. 'order' => $sOrder,
  433. 'license' => $sLicense,
  434. 'type' => $sType
  435. );
  436. $sExpireParam = '';
  437. if(!empty($iTrial))
  438. $sExpireParam = ', `expired`=UNIX_TIMESTAMP(DATE_ADD(DATE_ADD(NOW(), INTERVAL ' . (int)$iTrial . ' DAY), INTERVAL ' . (int)$this->getParam($CNF['OPTION_RECURRING_RESERVE']) . ' DAY))';
  439. else if(!empty($sDuration) && isset($this->_aRecurringDurations[$sDuration]))
  440. $sExpireParam = ', `expired`=UNIX_TIMESTAMP(DATE_ADD(DATE_ADD(NOW(), ' . $this->_aRecurringDurations[$sDuration] . '), INTERVAL ' . (int)$this->getParam($CNF['OPTION_RECURRING_RESERVE']) . ' DAY))';
  441. if((int)$this->query("INSERT INTO `" . $CNF['TABLE_LICENSES'] . "` SET " . $this->arrayToSQL($aQueryParams) . ", `added`=UNIX_TIMESTAMP()" . $sExpireParam) == 0)
  442. continue;
  443. $sLicense = $oPayments->generateLicense();
  444. $iProcessed += 1;
  445. }
  446. return $iCount == $iProcessed;
  447. }
  448. public function prolongLicense($iProfileId, $iProductId, $iCount, $sOrder, $sLicense, $sType, $sDuration = '', $iTrial = 0)
  449. {
  450. $CNF = &$this->_oConfig->CNF;
  451. if($sType == BX_MARKET_LICENSE_TYPE_SINGLE)
  452. return true;
  453. if(empty($sDuration) || empty($this->_aRecurringDurations[$sDuration]))
  454. return false;
  455. $sQuery = $this->prepare("UPDATE
  456. `" . $CNF['TABLE_LICENSES'] . "`
  457. SET
  458. `expired`=UNIX_TIMESTAMP(DATE_ADD(FROM_UNIXTIME(`expired`), " . $this->_aRecurringDurations[$sDuration] . "))
  459. WHERE
  460. `profile_id` = ? AND
  461. `product_id` = ? AND
  462. `order` = ?
  463. LIMIT ?", $iProfileId, $iProductId, $sOrder, (int)$iCount);
  464. return (int)$this->query($sQuery) > 0;
  465. }
  466. public function unregisterLicense($iProfileId, $iProductId, $sOrder, $sLicense, $sType)
  467. {
  468. $sWhereClause = "`profile_id` = :profile_id AND `product_id` = :product_id AND `order` = :order AND `license` = :license";
  469. $aWhereBindings = array(
  470. 'profile_id' => $iProfileId,
  471. 'product_id' => $iProductId,
  472. 'order' => $sOrder,
  473. 'license' => $sLicense
  474. );
  475. //--- Move to deleted licenses table with 'refund' as reason.
  476. $sQuery = "INSERT IGNORE INTO `" . $this->_oConfig->CNF['TABLE_LICENSES_DELETED'] . "` SELECT *, 'refund' AS `reason`, UNIX_TIMESTAMP() AS `deleted` FROM `" . $this->_oConfig->CNF['TABLE_LICENSES'] . "` WHERE " . $sWhereClause;
  477. $this->query($sQuery, $aWhereBindings);
  478. $sQuery = "DELETE FROM `" . $this->_oConfig->CNF['TABLE_LICENSES'] . "` WHERE " . $sWhereClause;
  479. return $this->query($sQuery, $aWhereBindings) !== false;
  480. }
  481. public function unregisterLicenseById($iId, $sReason = 'refund')
  482. {
  483. $CNF = &$this->_oConfig->CNF;
  484. //--- Move to deleted licenses table with provided reason.
  485. $this->query("INSERT IGNORE INTO `" . $CNF['TABLE_LICENSES_DELETED'] . "` SELECT *, :reason AS `reason`, UNIX_TIMESTAMP() AS `deleted` FROM `" . $CNF['TABLE_LICENSES'] . "` WHERE `id` = :id", [
  486. 'id' => $iId,
  487. 'reason' => $sReason
  488. ]);
  489. return $this->query("DELETE FROM `" . $CNF['TABLE_LICENSES'] . "` WHERE `id` = :id", [
  490. 'id' => $iId,
  491. ]) !== false;
  492. }
  493. function processExpiredLicense($aLicense)
  494. {
  495. //--- Move to deleted licenses table with 'expire' as reason.
  496. $this->query("INSERT IGNORE INTO `" . $this->_oConfig->CNF['TABLE_LICENSES_DELETED'] . "` SET " . $this->arrayToSQL($aLicense));
  497. return $this->query("DELETE FROM `" . $this->_oConfig->CNF['TABLE_LICENSES'] . "` WHERE `id`=:id LIMIT 1", array('id' => $aLicense['id'])) !== false;
  498. }
  499. function processExpiredLicenses()
  500. {
  501. $sWhereClause = "`type` = :type AND `added` < UNIX_TIMESTAMP() AND `expired` <> 0 AND `expired` < UNIX_TIMESTAMP()";
  502. $aWhereBindings = array(
  503. 'type' => BX_MARKET_LICENSE_TYPE_RECURRING
  504. );
  505. //--- Move to deleted licenses table with 'expire' as reason.
  506. $sQuery = "INSERT IGNORE INTO `" . $this->_oConfig->CNF['TABLE_LICENSES_DELETED'] . "` SELECT *, 'expire' AS `reason`, UNIX_TIMESTAMP() AS `deleted` FROM `" . $this->_oConfig->CNF['TABLE_LICENSES'] . "` WHERE " . $sWhereClause;
  507. $this->query($sQuery, $aWhereBindings);
  508. $sQuery = "DELETE FROM `" . $this->_oConfig->CNF['TABLE_LICENSES'] . "` WHERE " . $sWhereClause;
  509. return $this->query($sQuery, $aWhereBindings) !== false;
  510. }
  511. protected function _deassociateAttachmentWithContent($sTable, $iContentId, $iFileId)
  512. {
  513. $sWhere = '';
  514. $aBindings = array();
  515. if ($iContentId) {
  516. $sWhere .= " AND `content_id` = :content_id ";
  517. $aBindings['content_id'] = $iContentId;
  518. }
  519. if ($iFileId) {
  520. $sWhere .= " AND `file_id` = :file_id ";
  521. $aBindings['file_id'] = $iFileId;
  522. }
  523. $sQuery = "DELETE FROM `" . $sTable . "` WHERE 1 " . $sWhere;
  524. return $this->query($sQuery, $aBindings) !== false;
  525. }
  526. protected function _getAttachment($sTable, $aParams = array())
  527. {
  528. $aMethod = array('name' => 'getRow', 'params' => array(0 => 'query'));
  529. $sFieldsClause = "`tfe`.*";
  530. $sJoinClause = $sWhereClause = $sOrderClause = $sLimitClause = "";
  531. switch($aParams['type']) {
  532. case 'id':
  533. $aMethod['params'][1] = array(
  534. 'id' => $aParams['id']
  535. );
  536. $sWhereClause = " AND `tfe`.`id`=:id";
  537. break;
  538. case 'file_id':
  539. $aMethod['params'][1] = array(
  540. 'file_id' => $aParams['file_id']
  541. );
  542. $sWhereClause = " AND `tfe`.`file_id`=:file_id";
  543. break;
  544. case 'file_id_ext':
  545. $aMethod['params'][1] = array(
  546. 'file_id' => $aParams['file_id']
  547. );
  548. $sFieldsClause .= ", `tf`.`file_name`, `tf`.`size` AS `file_size`";
  549. $sJoinClause = " LEFT JOIN `" . $this->_oConfig->CNF['TABLE_FILES'] . "` AS `tf` ON `tfe`.`file_id`=`tf`.`id` ";
  550. $sWhereClause = " AND `tfe`.`file_id`=:file_id";
  551. break;
  552. case 'content_id':
  553. $aMethod['name'] = 'getAll';
  554. $aMethod['params'][1] = array(
  555. 'content_id' => $aParams['content_id']
  556. );
  557. $sWhereClause = " AND `tfe`.`content_id`=:content_id";
  558. if(!empty($aParams['except']))
  559. $sWhereClause .= " AND `tfe`.`file_id` NOT IN (" . $this->implode_escape($aParams['except']) . ")";
  560. break;
  561. case 'content_id_key_file_id':
  562. $aMethod['name'] = 'getAllWithKey';
  563. $aMethod['params'][1] = 'file_id';
  564. $aMethod['params'][2] = array(
  565. 'content_id' => $aParams['content_id']
  566. );
  567. $sWhereClause = " AND `tfe`.`content_id`=:content_id";
  568. $sOrderClause = "`tfe`.`type` ASC, `tfe`.`order` DESC";
  569. break;
  570. case 'content_id_and_type':
  571. $aMethod['name'] = 'getAll';
  572. $aMethod['params'][1] = array(
  573. 'content_id' => $aParams['content_id'],
  574. 'type' => $aParams['file_type']
  575. );
  576. $sFieldsClause .= ", `tf`.`file_name`, `tf`.`size` AS `file_size`";
  577. $sJoinClause = " LEFT JOIN `" . $this->_oConfig->CNF['TABLE_FILES'] . "` AS `tf` ON `tfe`.`file_id`=`tf`.`id` ";
  578. $sWhereClause = " AND `tfe`.`content_id`=:content_id AND `tfe`.`type`=:type";
  579. if(!empty($aParams['version'])) {
  580. $aMethod['name'] = 'getRow';
  581. $aMethod['params'][1]['version'] = $aParams['version'];
  582. $sWhereClause .= " AND `tfe`.`version`=:version";
  583. }
  584. if(isset($aParams['ordered']) && $aParams['ordered'] === true)
  585. $sOrderClause = "`tfe`.`version` ASC";
  586. break;
  587. }
  588. if(!empty($sOrderClause))
  589. $sOrderClause = " ORDER BY " . $sOrderClause;
  590. if(!empty($sLimitClause))
  591. $sLimitClause = " LIMIT " . $sLimitClause;
  592. $aMethod['params'][0] = "SELECT
  593. " . $sFieldsClause . "
  594. FROM `" . $sTable . "` AS `tfe`" . $sJoinClause . "
  595. WHERE 1" . $sWhereClause . $sOrderClause . $sLimitClause;
  596. return call_user_func_array(array($this, $aMethod['name']), $aMethod['params']);
  597. }
  598. protected function _updateAttachment($sTable, $aSet, $aWhere)
  599. {
  600. $sQuery = "UPDATE `" . $sTable . "` SET " . $this->arrayToSQL($aSet) . " WHERE " . (!empty($aWhere) ? $this->arrayToSQL($aWhere, ' AND ') : "1");
  601. return (int)$this->query($sQuery) > 0;
  602. }
  603. }
  604. /** @} */