BxPaymentCart.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  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 Payment Payment
  7. * @ingroup UnaModules
  8. *
  9. * @{
  10. */
  11. class BxPaymentCart extends BxBaseModPaymentCart
  12. {
  13. function __construct()
  14. {
  15. $this->MODULE = 'bx_payment';
  16. parent::__construct();
  17. }
  18. /*
  19. * Service methods
  20. */
  21. /**
  22. * @page service Service Calls
  23. * @section bx_payment Payment
  24. * @subsection bx_payment-page_blocks Page Blocks
  25. * @subsubsection bx_payment-get_block_carts get_block_carts
  26. *
  27. * @code bx_srv('bx_payment', 'get_block_carts', [...], 'Cart'); @endcode
  28. *
  29. * Get page block with shopping carts by vendors.
  30. *
  31. * @return an array describing a block to display on the site or an empty string if something is wrong. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
  32. *
  33. * @see BxPaymentCart::serviceGetBlockCarts
  34. */
  35. /**
  36. * @ref bx_payment-get_block_carts "get_block_carts"
  37. */
  38. public function serviceGetBlockCarts()
  39. {
  40. $CNF = &$this->_oModule->_oConfig->CNF;
  41. $iUserId = $this->_oModule->getProfileId();
  42. if(empty($iUserId))
  43. return MsgBox(_t($CNF['T']['ERR_REQUIRED_LOGIN']));
  44. if($this->_oModule->_oConfig->isSingleSeller())
  45. return MsgBox(_t($CNF['T']['MSG_SINGLE_SELLER_MODE'], $this->serviceGetCartUrl()));
  46. if(bx_get('seller_id') !== false)
  47. return '';
  48. $mixedContent = $this->_oModule->_oTemplate->displayBlockCarts($iUserId);
  49. if($this->_bIsApi)
  50. return [
  51. bx_api_get_block('grid', $mixedContent)
  52. ];
  53. return [
  54. 'content' => $mixedContent
  55. ];
  56. }
  57. /**
  58. * @page service Service Calls
  59. * @section bx_payment Payment
  60. * @subsection bx_payment-page_blocks Page Blocks
  61. * @subsubsection bx_payment-get_block_cart get_block_cart
  62. *
  63. * @code bx_srv('bx_payment', 'get_block_cart', [...], 'Cart'); @endcode
  64. *
  65. * Get page block with content of selected shopping cart.
  66. *
  67. * @return an array describing a block to display on the site or an empty string if something is wrong. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
  68. *
  69. * @see BxPaymentCart::serviceGetBlockCart
  70. */
  71. /**
  72. * @ref bx_payment-get_block_cart "get_block_cart"
  73. */
  74. public function serviceGetBlockCart()
  75. {
  76. $CNF = &$this->_oModule->_oConfig->CNF;
  77. if(!$this->_bSingleSeller && bx_get('seller_id') === false)
  78. return $this->_bIsApi ? [bx_api_get_msg('')] : '';
  79. $iUserId = $this->_oModule->getProfileId();
  80. if(empty($iUserId))
  81. return $this->_bIsApi ? [bx_api_get_msg(_t($CNF['T']['ERR_REQUIRED_LOGIN']))] : [
  82. 'content' => MsgBox(_t($CNF['T']['ERR_REQUIRED_LOGIN']))
  83. ];
  84. $iSellerId = !$this->_bSingleSeller ? bx_process_input(bx_get('seller_id'), BX_DATA_INT) : $this->_oModule->_oConfig->getSiteAdmin();
  85. if(empty($iSellerId))
  86. return $this->_bIsApi ? [bx_api_get_msg(_t($CNF['T']['ERR_UNKNOWN_VENDOR']))] : [
  87. 'content' => MsgBox(_t($CNF['T']['ERR_UNKNOWN_VENDOR']))
  88. ];
  89. $aSeller = $this->_oModule->getProfileInfo($iSellerId);
  90. $sTitle = _t($CNF['T']['BLOCK_TITLE_CART'], $aSeller['name']);
  91. $mixedContent = $this->_oModule->_oTemplate->displayBlockCart($iUserId, $iSellerId);
  92. if($this->_bIsApi)
  93. return [
  94. 'title' => $sTitle,
  95. 'content' => [bx_api_get_block('grid', $mixedContent)]
  96. ];
  97. return [
  98. 'title' => $sTitle,
  99. 'content' => $mixedContent
  100. ];
  101. }
  102. /**
  103. * @page service Service Calls
  104. * @section bx_payment Payment
  105. * @subsection bx_payment-page_blocks Page Blocks
  106. * @subsubsection bx_payment-get_block_cart_history get_block_cart_history
  107. *
  108. * @code bx_srv('bx_payment', 'get_block_cart_history', [...], 'Cart'); @endcode
  109. *
  110. * Get page block with shopping cart history.
  111. *
  112. * @return an array describing a block to display on the site or an empty string if something is wrong. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
  113. *
  114. * @see BxPaymentCart::serviceGetBlockCartHistory
  115. */
  116. /**
  117. * @ref bx_payment-get_block_cart_history "get_block_cart_history"
  118. */
  119. public function serviceGetBlockCartHistory()
  120. {
  121. $CNF = &$this->_oModule->_oConfig->CNF;
  122. $iSellerId = bx_get('vendor') !== false ? (int)bx_get('vendor') : 0;
  123. $iUserId = $this->_oModule->getProfileId();
  124. if(empty($iUserId))
  125. return $this->_bIsApi ? [] : [
  126. 'content' => MsgBox(_t($CNF['T']['ERR_REQUIRED_LOGIN']))
  127. ];
  128. $mixedBlockContent = $this->_oModule->_oTemplate->displayBlockHistory($iUserId, $iSellerId);
  129. if($this->_bIsApi)
  130. return !$mixedBlockContent ? [] : [
  131. bx_api_get_block('grid', $mixedBlockContent)
  132. ];
  133. return [
  134. 'content' => $mixedBlockContent,
  135. ];
  136. }
  137. /**
  138. * @page service Service Calls
  139. * @section bx_payment Payment
  140. * @subsection bx_payment-purchase_processing Purchase Processing
  141. * @subsubsection bx_payment-add_to_cart add_to_cart
  142. *
  143. * @code bx_srv('bx_payment', 'add_to_cart', [...], 'Cart'); @endcode
  144. *
  145. * Add an item described with method's params to shopping cart.
  146. *
  147. * @param $iSellerId integer value with seller ID.
  148. * @param $mixedModuleId mixed value (ID, Name or URI) determining a module from which the action was initiated.
  149. * @param $iItemId integer value with item ID.
  150. * @param $iItemCount integer value with a number of items for purchasing.
  151. * @param $aCustom array with custom data.
  152. * @return an array with special format which describes the result of operation.
  153. *
  154. * @see BxPaymentCart::serviceAddToCart
  155. */
  156. /**
  157. * @ref bx_payment-add_to_cart "add_to_cart"
  158. */
  159. public function serviceAddToCart($iSellerId, $mixedModuleId, $iItemId, $iItemCount, $aCustom = array())
  160. {
  161. $CNF = &$this->_oModule->_oConfig->CNF;
  162. $iModuleId = $this->_oModule->_oConfig->getModuleId($mixedModuleId);
  163. $iClientId = $this->_oModule->getProfileId();
  164. $mixedResult = $this->_oModule->checkData($iClientId, $iSellerId, $iModuleId, $iItemId, $iItemCount, $aCustom);
  165. if($mixedResult !== true)
  166. return $mixedResult;
  167. $aSellerProviders = $this->_oModule->_oDb->getVendorInfoProvidersSingle($iSellerId);
  168. if(empty($aSellerProviders))
  169. return array('code' => 5, 'message' => _t($CNF['T']['ERR_NOT_ACCEPT_PAYMENTS']));
  170. $aCart = $this->_oModule->_oDb->getCartContent($iClientId);
  171. $sCartItems = !empty($aCart['items']) ? $aCart['items'] : '';
  172. $sCartItemsResult = false;
  173. $this->_oModule->alert('before_add_to_cart', 0, $iClientId, [
  174. 'client_id' => $iClientId,
  175. 'seller_id' => $iSellerId,
  176. 'module_id' => $iModuleId,
  177. 'item_id' => $iItemId,
  178. 'item_count' => $iItemCount,
  179. 'cart' => &$aCart,
  180. 'cart_items' => &$sCartItems,
  181. 'cart_ref' => &$aCart,
  182. 'cart_items_ref' => &$sCartItems,
  183. 'override_result' => &$sCartItemsResult,
  184. ]);
  185. $sCiDsc = $this->_oModule->_oConfig->descriptorA2S(array($iSellerId, $iModuleId, $iItemId));
  186. if($sCartItemsResult === false) {
  187. if(strpos($sCartItems, $sCiDsc) !== false)
  188. $sCartItemsResult = preg_replace_callback(
  189. "/" . $this->_oModule->_oConfig->descriptorA2S(array(preg_quote($iSellerId, '/'), preg_quote($iModuleId, '/'), preg_quote($iItemId, '/'), '([0-9]+)')) . "/", function($aMatches) use($iSellerId, $iModuleId, $iItemId, $iItemCount) {
  190. return $this->_oModule->_oConfig->descriptorA2S(array($iSellerId, $iModuleId, $iItemId, $aMatches[1] + $iItemCount));
  191. },
  192. $sCartItems
  193. );
  194. else {
  195. $sCartItem = $this->_oModule->_oConfig->descriptorA2S(array($iSellerId, $iModuleId, $iItemId, $iItemCount));
  196. $sCartItemsResult = empty($sCartItems) ? $sCartItem : $sCartItems . $this->_oModule->_oConfig->getDivider('DIVIDER_DESCRIPTORS') . $sCartItem;
  197. }
  198. }
  199. $aCartCustom = $aCart['customs'];
  200. if(!empty($aCustom) && is_array($aCustom))
  201. $aCartCustom[$sCiDsc] = !empty($aCartCustom[$sCiDsc]) && is_array($aCartCustom[$sCiDsc]) ? array_merge($aCartCustom[$sCiDsc], $aCustom) : $aCustom;
  202. $this->_oModule->_oDb->setCartItems($iClientId, $sCartItemsResult, $aCartCustom);
  203. $aInfo = $this->getInfo(BX_PAYMENT_TYPE_SINGLE, $iClientId);
  204. $iTotalQuantity = 0;
  205. foreach($aInfo as $aCart)
  206. $iTotalQuantity += $aCart['items_count'];
  207. return array(
  208. 'code' => 0,
  209. 'message' => _t($CNF['T']['MSG_ITEM_ADDED']),
  210. 'total_quantity' => $iTotalQuantity,
  211. //TODO: Update account submenu if it's needed.
  212. 'content' => '' //$this->_oModule->_oTemplate->displayToolbarSubmenu($aInfo)
  213. );
  214. }
  215. /**
  216. * @page service Service Calls
  217. * @section bx_payment Payment
  218. * @subsection bx_payment-purchase_processing Purchase Processing
  219. * @subsubsection bx_payment-delete_from_cart delete_from_cart
  220. *
  221. * @code bx_srv('bx_payment', 'delete_from_cart', [...], 'Cart'); @endcode
  222. *
  223. * Delete an item(s) from shopping cart.
  224. *
  225. * @param $iSellerId integer value with seller ID. The items owned by this seller will be removed only.
  226. * @param $iModuleId (optional) integer value with module ID. If specified, the items related to this module will be removed only.
  227. * @param $iItemId (optional) integer value with item ID. If specified, the item with this ID will be removed only.
  228. * @return an array with special format which describes the result of operation.
  229. *
  230. * @see BxPaymentCart::serviceDeleteFromCart
  231. */
  232. /**
  233. * @ref bx_payment-delete_from_cart "delete_from_cart"
  234. */
  235. public function serviceDeleteFromCart($iSellerId, $iModuleId = 0, $iItemId = 0)
  236. {
  237. $CNF = &$this->_oModule->_oConfig->CNF;
  238. if($iSellerId == BX_PAYMENT_EMPTY_ID)
  239. return array('code' => 1, 'message' => _t($CNF['T']['ERR_WRONG_DATA']));
  240. $iClientId = $this->_oModule->getProfileId();
  241. if(empty($iClientId))
  242. return array('code' => 2, 'message' => _t($CNF['T']['ERR_REQUIRED_LOGIN']));
  243. $aCart = $this->_oModule->_oDb->getCartContent($iClientId);
  244. $aCartCustom = $aCart['customs'];
  245. if(!empty($iModuleId) && !empty($iItemId)) {
  246. $sCiDsc = $this->_oModule->_oConfig->descriptorA2S(array($iSellerId, $iModuleId, $iItemId));
  247. if(!empty($aCartCustom[$sCiDsc]))
  248. unset($aCartCustom[$sCiDsc]);
  249. }
  250. else {
  251. $aCiDscs = array_keys($aCartCustom);
  252. foreach($aCiDscs as $sCiDsc)
  253. if(strpos($sCiDsc, $iSellerId . '_') === 0)
  254. unset($aCartCustom[$sCiDsc]);
  255. $iModuleId = $iItemId = '[0-9\-]+';
  256. }
  257. $aCart['items'] = trim(preg_replace("'" . $this->_oModule->_oConfig->descriptorA2S(array(preg_quote($iSellerId, "'"), preg_quote($iModuleId, "'"), preg_quote($iItemId, "'"), '[0-9]+:?')) . "'", "", $aCart['items']), ":");
  258. $this->_oModule->_oDb->setCartItems($iClientId, $aCart['items'], $aCartCustom);
  259. $this->_oModule->alert('delete_from_cart', 0, 0, array(
  260. 'seller_id' => $iSellerId,
  261. 'module_id' => $iModuleId,
  262. 'item_id' => $iItemId,
  263. ));
  264. return array('code' => 0, 'message' => _t($CNF['T']['MSG_ITEM_DELETED']));
  265. }
  266. public function getInfo($sType, $iUserId, $iSellerId = BX_PAYMENT_EMPTY_ID, $aItems = array())
  267. {
  268. if($iSellerId != BX_PAYMENT_EMPTY_ID && !empty($aItems))
  269. return $this->_getInfo($sType, $iUserId, $iSellerId, $this->_oModule->_oConfig->descriptorsM2A($aItems));
  270. $aContent = $this->_parseByVendor($iUserId);
  271. if($iSellerId != BX_PAYMENT_EMPTY_ID)
  272. return $this->_getInfo($sType, $iUserId, $iSellerId, (isset($aContent[$iSellerId]) ? $aContent[$iSellerId] : []));
  273. $aResult = array();
  274. foreach($aContent as $iSellerId => $aSellerItems)
  275. $aResult[$iSellerId] = $this->_getInfo($sType, $iUserId, $iSellerId, $aSellerItems);
  276. return $aResult;
  277. }
  278. /**
  279. * Enter description here...
  280. *
  281. * @param integer $iClientId client's ID
  282. * @param integer $iSellerId vendor's ID
  283. * @param array $aItems item descriptors(quaternions) from shopping cart.
  284. * @return array with full info about vendor and items.
  285. */
  286. protected function _getInfo($sType, $iClientId, $iSellerId, $aItems)
  287. {
  288. $bTypeSingle = $sType == BX_PAYMENT_TYPE_SINGLE;
  289. $iItemsCount = 0;
  290. $fItemsPrice = 0;
  291. $aItemsInfo = array();
  292. foreach($aItems as $aItem) {
  293. $aCustom = isset($aItem['custom']) ? $aItem['custom'] : [];
  294. //--- Get item main info
  295. $aItemInfo = $this->_oModule->callGetCartItem((int)$aItem['module_id'], array($aItem['item_id'], $iClientId, $aCustom));
  296. if(empty($aItemInfo) || !is_array($aItemInfo)) {
  297. if($bTypeSingle) {
  298. $sCartItems = $this->_oModule->_oDb->getCartItems($iClientId);
  299. $sCartItems = trim(preg_replace("'" . preg_quote($this->_oModule->_oConfig->descriptorA2S($aItem), "'") . ":?'", "", $sCartItems), ":");
  300. $this->_oModule->_oDb->setCartItems($iClientId, $sCartItems);
  301. }
  302. continue;
  303. }
  304. $aItemInfo['module_id'] = (int)$aItem['module_id'];
  305. $aItemInfo['quantity'] = (int)$aItem['item_count'];
  306. //--- Get item addons' info
  307. $aItemAddons = array();
  308. if(!empty($aItem['item_addons'])) {
  309. $aAddons = $this->_oModule->_oConfig->s2a($aItem['item_addons']);
  310. foreach($aAddons as $sAddon) {
  311. if(isset($aItemAddons[$sAddon])) {
  312. $aItemAddons[$sAddon]['quantity'] += 1;
  313. continue;
  314. }
  315. $aAddonInfo = $this->_oModule->callGetCartItem((int)$aItem['module_id'], array($sAddon, $iClientId, $aCustom));
  316. if(empty($aAddonInfo) || !is_array($aAddonInfo))
  317. continue;
  318. $aAddonInfo['module_id'] = (int)$aItem['module_id'];
  319. $aAddonInfo['quantity'] = 1;
  320. $aItemAddons[$sAddon] = $aAddonInfo;
  321. }
  322. }
  323. $aItemInfo['addons'] = $aItemAddons;
  324. $aItemsInfo[] = $aItemInfo;
  325. //--- Update items' summary
  326. $fAddonsPrice = 0;
  327. foreach($aItemInfo['addons'] as $aAddonInfo)
  328. $fAddonsPrice += $aAddonInfo['quantity'] * $this->_oModule->_oConfig->getPrice($sType, $aAddonInfo);
  329. $iItemsCount += $aItemInfo['quantity'];
  330. $fItemsPrice += $aItemInfo['quantity'] * ($this->_oModule->_oConfig->getPrice($sType, $aItemInfo) + $fAddonsPrice);
  331. }
  332. $aSeller = $this->_oModule->getVendorInfo((int)$iSellerId);
  333. $aResult = array(
  334. 'client_id' => $iClientId,
  335. 'vendor_id' => $aSeller['id'],
  336. 'vendor_name' => $aSeller['name'],
  337. 'vendor_link' => $aSeller['link'],
  338. 'vendor_icon' => $aSeller['icon'],
  339. 'vendor_thumb' => $aSeller['thumb'],
  340. 'vendor_avatar' => $aSeller['avatar'],
  341. 'vendor_currency_code' => $aSeller['currency_code'],
  342. 'vendor_currency_sign' => $aSeller['currency_sign'],
  343. 'items_count' => $iItemsCount,
  344. 'items_price' => $fItemsPrice,
  345. 'items' => $aItemsInfo
  346. );
  347. $this->_oModule->alert('get_cart_info', 0, 0, array(
  348. 'type' => $sType,
  349. 'client_id' => $iClientId,
  350. 'seller_id' => $iSellerId,
  351. 'items' => $aItems,
  352. 'override_result' => &$aResult
  353. ));
  354. return $aResult;
  355. }
  356. }
  357. /** @} */