BxCreditsModule.php 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854
  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 Credits Credits
  7. * @ingroup UnaModules
  8. *
  9. * @{
  10. */
  11. define('BX_CREDITS_DIRECTION_IN', 'in');
  12. define('BX_CREDITS_DIRECTION_OUT', 'out');
  13. define('BX_CREDITS_ORDER_TYPE_SINGLE', 'single'); //--- one-time payment
  14. define('BX_CREDITS_ORDER_TYPE_RECURRING', 'recurring'); //--- recurring payment (subscription)
  15. class BxCreditsModule extends BxBaseModGeneralModule
  16. {
  17. function __construct(&$aModule)
  18. {
  19. parent::__construct($aModule);
  20. }
  21. public function actionGetProfiles()
  22. {
  23. $sTerm = bx_get('term');
  24. $a = BxDolService::call('system', 'profiles_search', array($sTerm), 'TemplServiceProfiles');
  25. echoJson($a);
  26. }
  27. public function actionCheckout()
  28. {
  29. $iBuyerId = bx_get_logged_profile_id();
  30. if(!$iBuyerId)
  31. return echoJson(array('code' => 1, 'msg' => _t('_bx_credits_err_unknown_buyer')));
  32. $aData = $this->_oConfig->getCheckoutData();
  33. if(empty($aData) || !is_array($aData))
  34. return echoJson(array('code' => 2, 'msg' => _t('_bx_credits_err_incorrect_data')));
  35. $iSellerId = (int)$aData['seller'];
  36. $fAmount = (float)$aData['amount'];
  37. $fBalance = (float)$this->_oDb->getProfile(array('type' => 'balance', 'id' => $iBuyerId));
  38. if($fAmount > $fBalance)
  39. return echoJson(array('code' => 3, 'msg' => _t('_bx_credits_err_low_balance')));
  40. $sOrder = $this->_oConfig->getOrder();
  41. $sInfo = _t('_bx_credits_txt_history_info_checkout');
  42. $sData = serialize(array(
  43. 'conversion' => $this->_oConfig->getConversionRateUse(),
  44. 'precision' => $this->_oConfig->getPrecision()
  45. ));
  46. $this->updateProfileBalance($iBuyerId, $iSellerId, -$fAmount, $sOrder, $sInfo, $sData);
  47. $this->updateProfileBalance($iSellerId, $iBuyerId, $fAmount, $sOrder, $sInfo, $sData);
  48. bx_alert($this->getName(), 'checkout', 0, false, array(
  49. 'seller' => $iSellerId,
  50. 'buyer' => $iBuyerId,
  51. 'amount' => $fAmount,
  52. 'order' => $sOrder
  53. ));
  54. return echoJson(array(
  55. 'code' => 0,
  56. 'redirect' => bx_append_url_params($aData['return_data_url'], array('o' => $sOrder, 'c' => $aData['custom']))
  57. ));
  58. }
  59. public function serviceGetCheckoutUrl()
  60. {
  61. return $this->_oConfig->getCheckoutUrl();
  62. }
  63. public function serviceValidateCheckout($iSeller, $iBuyer, $fAmount, $sOrder)
  64. {
  65. $fAmount = (float)$fAmount;
  66. $aOut = $this->_oDb->getHistory(array('type' => 'row_by', 'by' => array('first_pid' => $iBuyer, 'direction' => BX_CREDITS_DIRECTION_OUT, 'order' => $sOrder)));
  67. if(empty($aOut) || !is_array($aOut) || (int)$aOut['second_pid'] != (int)$iSeller)
  68. return false;
  69. $aDataOut = unserialize($aOut['data']);
  70. if($this->_oConfig->convertM2C($fAmount, $aDataOut['conversion'], $aDataOut['precision']) != (float)$aOut['amount'])
  71. return false;
  72. $aIn = $this->_oDb->getHistory(array('type' => 'row_by', 'by' => array('first_pid' => $iSeller, 'direction' => BX_CREDITS_DIRECTION_IN, 'order' => $sOrder)));
  73. if(empty($aIn) || !is_array($aIn) || (int)$aIn['second_pid'] != (int)$iBuyer)
  74. return false;
  75. $aDataIn = unserialize($aIn['data']);
  76. if($this->_oConfig->convertM2C($fAmount, $aDataIn['conversion'], $aDataIn['precision']) != (float)$aIn['amount'])
  77. return false;
  78. return true;
  79. }
  80. public function serviceGetBlockCheckout()
  81. {
  82. $oBuyer = BxDolProfile::getInstance();
  83. if(!$oBuyer)
  84. return MsgBox(_t('_bx_credits_err_unknown_buyer'));
  85. $iSeller = (int)bx_get('seller');
  86. $oSeller = BxDolProfile::getInstance($iSeller);
  87. if(!$oSeller)
  88. return MsgBox(_t('_bx_credits_err_unknown_seller'));
  89. $fAmountM = (float)bx_get('amount');
  90. $fAmountC = $this->_oConfig->convertM2C($fAmountM);
  91. $aData = array(
  92. 'seller' => $iSeller,
  93. 'currency' => array(
  94. 'code' => bx_process_input(bx_get('currency_code')),
  95. 'sign' => bx_process_input(bx_get('currency_sign')),
  96. ),
  97. 'amountm' => $fAmountM,
  98. 'amountc' => $fAmountC
  99. );
  100. $iItemsCount = (int)bx_get('items_count');
  101. for($i = 0; $i < $iItemsCount; $i++) {
  102. $aData['items'][] = array(
  103. 'title' => bx_process_input(bx_get('item_title_' . $i)),
  104. 'quantity' => (int)bx_get('item_quantity_' . $i)
  105. );
  106. }
  107. $this->_oConfig->setCheckoutData(array(
  108. 'seller' => $iSeller,
  109. 'amount' => $fAmountC,
  110. 'custom' => bx_process_input(bx_get('custom')),
  111. 'return_data_url' => bx_process_input(bx_get('return_data_url')),
  112. ));
  113. return $this->_oTemplate->getBlockCheckout($oBuyer, $oSeller, $aData);
  114. }
  115. public function serviceGetMenuItemAddonAmount()
  116. {
  117. $iProfileId = bx_get_logged_profile_id();
  118. if(!$iProfileId)
  119. return '';
  120. return array(
  121. 'unit' => $this->_oConfig->getUnit(),
  122. 'value' => $this->_oConfig->convertC2S($this->_oDb->getProfile(array('type' => 'balance', 'id' => $iProfileId)), false)
  123. );
  124. }
  125. public function serviceGetBlockBundles()
  126. {
  127. return $this->_oTemplate->getBlockBundles();
  128. }
  129. /**
  130. * @page service Service Calls
  131. * @section bx_credits Credits
  132. * @subsection bx_credits-page_blocks Page Blocks
  133. * @subsubsection bx_credits-get_block_orders_note get_block_orders_note
  134. *
  135. * @code bx_srv('bx_credits', 'get_block_orders_note', [...]); @endcode
  136. *
  137. * Get page block with a notice for orders usage.
  138. *
  139. * @return HTML string with block content to display on the site.
  140. *
  141. * @see BxCreditsModule::serviceBlockLicensesNote
  142. */
  143. /**
  144. * @ref bx_credits-get_block_orders_note "get_block_orders_note"
  145. */
  146. public function serviceGetBlockOrdersNote()
  147. {
  148. return MsgBox(_t('_bx_credits_page_block_content_orders_common_note'));
  149. }
  150. /**
  151. * @page service Service Calls
  152. * @section bx_credits Credits
  153. * @subsection bx_credits-page_blocks Page Blocks
  154. * @subsubsection bx_credits-block_orders get_block_orders
  155. *
  156. * @code bx_srv('bx_credits', 'get_block_orders', [...]); @endcode
  157. *
  158. * Get page block with a list of orders purchased by currently logged member.
  159. *
  160. * @return an array describing a block to display on the site or false if there is no enough input data. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
  161. *
  162. * @see BxCreditsModule::serviceBlockLicenses
  163. */
  164. /**
  165. * @ref bx_credits-get_block_orders "get_block_orders"
  166. */
  167. public function serviceGetBlockOrders($sType = 'common')
  168. {
  169. return $this->_getBlockOrders($sType);
  170. }
  171. /**
  172. * @page service Service Calls
  173. * @section bx_credits Credits
  174. * @subsection bx_credits-page_blocks Page Blocks
  175. * @subsubsection bx_credits-get_block_history get_block_history
  176. *
  177. * @code bx_srv('bx_credits', 'get_block_history', [...]); @endcode
  178. *
  179. * Get page block with a list of all changes with credits.
  180. *
  181. * @return an array describing a block to display on the site or false if there is no enough input data. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
  182. *
  183. * @see BxCreditsModule::serviceGetBlockHistory
  184. */
  185. /**
  186. * @ref bx_credits-get_block_history "get_block_history"
  187. */
  188. public function serviceGetBlockHistory($sType = 'common')
  189. {
  190. return $this->_getBlockHistory($sType);
  191. }
  192. /**
  193. * @page service Service Calls
  194. * @section bx_credits Credits
  195. * @subsection bx_credits-payments Payments
  196. * @subsubsection bx_credits-get_payment_data get_payment_data
  197. *
  198. * @code bx_srv('bx_credits', 'get_payment_data', [...]); @endcode
  199. *
  200. * Get an array with module's description. Is needed for payments processing module.
  201. *
  202. * @return an array with module's description.
  203. *
  204. * @see BxCreditsModule::serviceGetPaymentData
  205. */
  206. /**
  207. * @ref bx_credits-get_payment_data "get_payment_data"
  208. */
  209. public function serviceGetPaymentData()
  210. {
  211. $CNF = &$this->_oConfig->CNF;
  212. $oPermalink = BxDolPermalinks::getInstance();
  213. $aResult = $this->_aModule;
  214. $aResult['url_browse_order_common'] = BX_DOL_URL_ROOT . $oPermalink->permalink($CNF['URL_ORDERS_COMMON'], array('filter' => '{order}'));
  215. $aResult['url_browse_order_administration'] = BX_DOL_URL_ROOT . $oPermalink->permalink($CNF['URL_ORDERS_ADMINISTRATION'], array('filter' => '{order}'));
  216. return $aResult;
  217. }
  218. /**
  219. * @page service Service Calls
  220. * @section bx_credits Credits
  221. * @subsection bx_credits-payments Payments
  222. * @subsubsection bx_credits-get_cart_item get_cart_item
  223. *
  224. * @code bx_srv('bx_credits', 'get_cart_item', [...]); @endcode
  225. *
  226. * Get an array with prodict's description. Is used in Shopping Cart in payments processing module.
  227. *
  228. * @param $iItemId product's ID.
  229. * @return an array with prodict's description. Empty array is returned if something is wrong.
  230. *
  231. * @see BxCreditsModule::serviceGetCartItem
  232. */
  233. /**
  234. * @ref bx_credits-get_cart_item "get_cart_item"
  235. */
  236. public function serviceGetCartItem($iItemId)
  237. {
  238. $CNF = &$this->_oConfig->CNF;
  239. if(!$iItemId)
  240. return array();
  241. $aItem = $this->_oDb->getBundle(array('type' => 'id', 'id' => $iItemId));
  242. if(empty($aItem) || !is_array($aItem))
  243. return array();
  244. return array (
  245. 'id' => $aItem[$CNF['FIELD_ID']],
  246. 'author_id' => $this->_oConfig->getAuthor(),
  247. 'name' => $aItem[$CNF['FIELD_NAME']],
  248. 'title' => _t($aItem[$CNF['FIELD_TITLE']]),
  249. 'description' => $this->_oConfig->getBundleDescription($aItem),
  250. 'url' => $this->_oConfig->getBundleUrl($aItem),
  251. 'price_single' => $aItem[$CNF['FIELD_PRICE']],
  252. 'price_recurring' => '',
  253. 'period_recurring' => 1,
  254. 'period_unit_recurring' => '',
  255. 'trial_recurring' => ''
  256. );
  257. }
  258. /**
  259. * @page service Service Calls
  260. * @section bx_credits Credits
  261. * @subsection bx_credits-payments Payments
  262. * @subsubsection bx_credits-get_cart_items get_cart_items
  263. *
  264. * @code bx_srv('bx_credits', 'get_cart_items', [...]); @endcode
  265. *
  266. * Get an array with prodicts' descriptions by seller. Is used in Manual Order Processing in payments processing module.
  267. *
  268. * @param $iSellerId seller ID.
  269. * @return an array with prodicts' descriptions. Empty array is returned if something is wrong or seller doesn't have any products.
  270. *
  271. * @see BxCreditsModule::serviceGetCartItems
  272. */
  273. /**
  274. * @ref bx_credits-get_cart_items "get_cart_items"
  275. */
  276. public function serviceGetCartItems($iAuthorId)
  277. {
  278. $CNF = &$this->_oConfig->CNF;
  279. $iAuthorId = $this->_oConfig->getAuthor();
  280. $aItems = $this->_oDb->getBundle(array('type' => 'all', 'active' => 1));
  281. $aResult = array();
  282. foreach($aItems as $aItem)
  283. $aResult[] = array(
  284. 'id' => $aItem[$CNF['FIELD_ID']],
  285. 'author_id' => $iAuthorId,
  286. 'name' => $aItem[$CNF['FIELD_NAME']],
  287. 'title' => _t($aItem[$CNF['FIELD_TITLE']]),
  288. 'description' => $this->_oConfig->getBundleDescription($aItem),
  289. 'url' => $this->_oConfig->getBundleUrl($aItem),
  290. 'price_single' => $aItem[$CNF['FIELD_PRICE']],
  291. 'price_recurring' => '',
  292. 'period_recurring' => 1,
  293. 'period_unit_recurring' => '',
  294. 'trial_recurring' => ''
  295. );
  296. return $aResult;
  297. }
  298. /**
  299. * @page service Service Calls
  300. * @section bx_credits Credits
  301. * @subsection bx_credits-payments Payments
  302. * @subsubsection bx_credits-register_cart_item register_cart_item
  303. *
  304. * @code bx_srv('bx_credits', 'register_cart_item', [...]); @endcode
  305. *
  306. * Register a processed single time payment inside the Credits module. Is called with payment processing module after the payment was registered there.
  307. *
  308. * @param $iClientId client ID.
  309. * @param $iSellerId seller ID
  310. * @param $iItemId item ID.
  311. * @param $iItemCount the number of purchased items.
  312. * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
  313. * @param $sLicense license number genereted with payment processing module for internal usage
  314. * @return an array with purchased prodict's description. Empty array is returned if something is wrong.
  315. *
  316. * @see BxCreditsModule::serviceRegisterCartItem
  317. */
  318. /**
  319. * @ref bx_credits-register_cart_item "register_cart_item"
  320. */
  321. public function serviceRegisterCartItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense)
  322. {
  323. return $this->_serviceRegisterItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense, BX_CREDITS_ORDER_TYPE_SINGLE);
  324. }
  325. /**
  326. * @page service Service Calls
  327. * @section bx_credits Credits
  328. * @subsection bx_credits-payments Payments
  329. * @subsubsection bx_credits-register_subscription_item register_subscription_item
  330. *
  331. * @code bx_srv('bx_credits', 'register_subscription_item', [...]); @endcode
  332. *
  333. * Register a processed subscription (recurring payment) inside the Credits module. Is called with payment processing module after the subscription was registered there.
  334. *
  335. * @param $iClientId client ID.
  336. * @param $iSellerId seller ID
  337. * @param $iItemId item ID.
  338. * @param $iItemCount the number of purchased items.
  339. * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
  340. * @param $sLicense license number genereted with payment processing module for internal usage
  341. * @return an array with subscribed prodict's description. Empty array is returned if something is wrong.
  342. *
  343. * @see BxCreditsModule::serviceRegisterSubscriptionItem
  344. */
  345. /**
  346. * @ref bx_credits-register_subscription_item "register_subscription_item"
  347. */
  348. public function serviceRegisterSubscriptionItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense)
  349. {
  350. return $this->_serviceRegisterItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense, BX_CREDITS_ORDER_TYPE_RECURRING);
  351. }
  352. /**
  353. * @page service Service Calls
  354. * @section bx_credits Credits
  355. * @subsection bx_credits-payments Payments
  356. * @subsubsection bx_credits-reregister_cart_item reregister_cart_item
  357. *
  358. * @code bx_srv('bx_credits', 'reregister_cart_item', [...]); @endcode
  359. *
  360. * Reregister a single time payment inside the Credits module. Is called with payment processing module after the payment was reregistered there.
  361. *
  362. * @param $iClientId client ID.
  363. * @param $iSellerId seller ID
  364. * @param $iItemIdOld old item ID.
  365. * @param $iItemIdNew new item ID.
  366. * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
  367. * @return an array with purchased prodict's description. Empty array is returned if something is wrong.
  368. *
  369. * @see BxCreditsModule::serviceReregisterCartItem
  370. */
  371. /**
  372. * @ref bx_credits-reregister_cart_item "reregister_cart_item"
  373. */
  374. public function serviceReregisterCartItem($iClientId, $iSellerId, $iItemIdOld, $iItemIdNew, $sOrder)
  375. {
  376. return array();
  377. }
  378. /**
  379. * @page service Service Calls
  380. * @section bx_credits Credits
  381. * @subsection bx_credits-payments Payments
  382. * @subsubsection bx_credits-reregister_subscription_item reregister_subscription_item
  383. *
  384. * @code bx_srv('bx_credits', 'reregister_subscription_item', [...]); @endcode
  385. *
  386. * Reregister a subscription (recurring payment) inside the Credits module. Is called with payment processing module after the subscription was reregistered there.
  387. *
  388. * @param $iClientId client ID.
  389. * @param $iSellerId seller ID
  390. * @param $iItemIdOld old item ID.
  391. * @param $iItemIdNew new item ID.
  392. * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
  393. * @return an array with subscribed prodict's description. Empty array is returned if something is wrong.
  394. *
  395. * @see BxCreditsModule::serviceReregisterSubscriptionItem
  396. */
  397. /**
  398. * @ref bx_credits-reregister_subscription_item "reregister_subscription_item"
  399. */
  400. public function serviceReregisterSubscriptionItem($iClientId, $iSellerId, $iItemIdOld, $iItemIdNew, $sOrder)
  401. {
  402. return array();
  403. }
  404. /**
  405. * @page service Service Calls
  406. * @section bx_credits Credits
  407. * @subsection bx_credits-payments Payments
  408. * @subsubsection bx_credits-unregister_cart_item unregister_cart_item
  409. *
  410. * @code bx_srv('bx_credits', 'unregister_cart_item', [...]); @endcode
  411. *
  412. * Unregister an earlier processed single time payment inside the Credits module. Is called with payment processing module after the payment was unregistered there.
  413. *
  414. * @param $iClientId client ID.
  415. * @param $iSellerId seller ID
  416. * @param $iItemId item ID.
  417. * @param $iItemCount the number of purchased items.
  418. * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
  419. * @param $sLicense license number genereted with payment processing module for internal usage
  420. * @return boolean value determining where the payment was unregistered or not.
  421. *
  422. * @see BxCreditsModule::serviceUnregisterCartItem
  423. */
  424. /**
  425. * @ref bx_credits-unregister_cart_item "unregister_cart_item"
  426. */
  427. public function serviceUnregisterCartItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense)
  428. {
  429. return $this->_serviceUnregisterItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense, BX_CREDITS_ORDER_TYPE_SINGLE);
  430. }
  431. /**
  432. * @page service Service Calls
  433. * @section bx_credits Credits
  434. * @subsection bx_credits-payments Payments
  435. * @subsubsection bx_credits-unregister_subscription_item unregister_subscription_item
  436. *
  437. * @code bx_srv('bx_credits', 'unregister_subscription_item', [...]); @endcode
  438. *
  439. * Unregister an earlier processed subscription (recurring payment) inside the Credits module. Is called with payment processing module after the subscription was unregistered there.
  440. *
  441. * @param $iClientId client ID.
  442. * @param $iSellerId seller ID
  443. * @param $iItemId item ID.
  444. * @param $iItemCount the number of purchased items.
  445. * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
  446. * @param $sLicense license number genereted with payment processing module for internal usage
  447. * @return boolean value determining where the subscription was unregistered or not.
  448. *
  449. * @see BxCreditsModule::serviceUnregisterSubscriptionItem
  450. */
  451. /**
  452. * @ref bx_credits-unregister_subscription_item "unregister_subscription_item"
  453. */
  454. public function serviceUnregisterSubscriptionItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense)
  455. {
  456. return $this->_serviceUnregisterItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense, BX_CREDITS_ORDER_TYPE_RECURRING);
  457. }
  458. /**
  459. * @page service Service Calls
  460. * @section bx_credits Credits
  461. * @subsection bx_credits-payments Payments
  462. * @subsubsection bx_credits-cancel_subscription_item cancel_subscription_item
  463. *
  464. * @code bx_srv('bx_credits', 'cancel_subscription_item', [...]); @endcode
  465. *
  466. * Cancel an earlier processed subscription (recurring payment) inside the Credits module. Is called with payment processing module after the subscription was canceled there.
  467. *
  468. * @param $iClientId client ID.
  469. * @param $iSellerId seller ID
  470. * @param $iItemId item ID.
  471. * @param $iItemCount the number of purchased items.
  472. * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
  473. * @return boolean value determining where the subscription was canceled or not.
  474. *
  475. * @see BxCreditsModule::serviceCancelSubscriptionItem
  476. */
  477. /**
  478. * @ref bx_credits-cancel_subscription_item "cancel_subscription_item"
  479. */
  480. public function serviceCancelSubscriptionItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder)
  481. {
  482. return true;
  483. }
  484. public function serviceGetProfileBalance($iProfileId = 0)
  485. {
  486. return $this->getProfileBalance($iProfileId);
  487. }
  488. public function serviceUpdateProfileBalance($iFirstPid, $fAmount, $iSecondPid = 0, $sOrder = '', $sInfo = '')
  489. {
  490. if(empty($sInfo))
  491. $sInfo = _t('_bx_credits_txt_history_info_service');
  492. return $this->updateProfileBalance($iFirstPid, $iSecondPid, $fAmount, $sOrder, $sInfo);
  493. }
  494. /**
  495. * Delete all content by profile
  496. * @param $iProfileId profile id
  497. * @return number of deleted items
  498. */
  499. public function serviceDeleteEntitiesByAuthor ($iProfileId)
  500. {
  501. $this->_oDb->deleteProfile(array('id' => $iProfileId));
  502. $this->_oDb->deleteHistory(array('first_pid' => $iProfileId));
  503. }
  504. /*
  505. * Common methods
  506. */
  507. public function getProfileBalance($iProfileId = 0)
  508. {
  509. if(empty($iProfileId))
  510. $iProfileId = bx_get_logged_profile_id();
  511. if(empty($iProfileId))
  512. return 0;
  513. return (float)$this->_oDb->getProfile(array('type' => 'balance', 'id' => $iProfileId));
  514. }
  515. public function updateProfileBalance($iFirstPid, $iSecondPid, $fAmount, $sOrder = '', $sInfo = '', $sData = '')
  516. {
  517. $CNF = &$this->_oConfig->CNF;
  518. if(empty($sOrder))
  519. $sOrder = $this->_oConfig->getOrder();
  520. if(empty($sData))
  521. $sData = serialize(array(
  522. 'conversion' => $this->_oConfig->getConversionRateUse(),
  523. 'precision' => $this->_oConfig->getPrecision()
  524. ));
  525. if(!$this->_oDb->updateProfileBalance($iFirstPid, $fAmount))
  526. return false;
  527. $fAmountAbs = abs($fAmount);
  528. $sDirection = $fAmount > 0 ? BX_CREDITS_DIRECTION_IN : BX_CREDITS_DIRECTION_OUT;
  529. $this->_oDb->insertHistory(array(
  530. 'first_pid' => $iFirstPid,
  531. 'second_pid' => $iSecondPid,
  532. 'amount' => $fAmountAbs,
  533. 'direction' => $sDirection,
  534. 'order' => $sOrder,
  535. 'data' => $sData,
  536. 'info' => $sInfo,
  537. 'date' => time()
  538. ));
  539. bx_alert($this->getName(), 'update_balance', 0, false, array(
  540. 'first_pid' => $iFirstPid,
  541. 'second_pid' => $iSecondPid,
  542. 'amount' => $fAmountAbs,
  543. 'direction' => $sDirection,
  544. 'order' => $sOrder,
  545. ));
  546. $oSecondProfile = BxDolProfile::getInstanceMagic($iSecondPid);
  547. sendMailTemplate($CNF['ETEMPLATE_' . strtoupper($sDirection)], 0, $iFirstPid, array(
  548. 'second_profile_name' => $oSecondProfile->getDisplayName(),
  549. 'amount' => $fAmountAbs,
  550. ));
  551. return true;
  552. }
  553. public function processGrant($iProfileId, $fAmount, $sMessage = '')
  554. {
  555. $CNF = &$this->_oConfig->CNF;
  556. $oProfile = BxDolProfile::getInstance($iProfileId);
  557. if(!$oProfile)
  558. return array('code' => 1, 'msg' => '_bx_credits_err_profile_not_found');
  559. $sInfo = _t('_bx_credits_txt_history_info_grant');
  560. if(!$this->updateProfileBalance($iProfileId, 0, $fAmount, '', $sInfo))
  561. return array('code' => 2, 'msg' => '_bx_credits_err_cannot_update_balance');
  562. sendMailTemplate($CNF['ETEMPLATE_GRANTED'], 0, $iProfileId, array(
  563. 'amount' => $fAmount,
  564. 'message' => $sMessage
  565. ));
  566. bx_alert($this->getName(), 'granted', 0, false, array(
  567. 'profile' => $iProfileId,
  568. 'amount' => $fAmount,
  569. ));
  570. return array('code' => 0);
  571. }
  572. public function processWithdrawRequest($iProfileId, $fAmount, $sMessage = '')
  573. {
  574. $CNF = &$this->_oConfig->CNF;
  575. if(empty($iProfileId))
  576. $iProfileId = bx_get_logged_profile_id ();
  577. if(empty($iProfileId))
  578. return array('code' => 1, 'msg' => '_bx_credits_err_login_required');
  579. $oProfile = BxDolProfile::getInstance($iProfileId);
  580. if(!$oProfile)
  581. return array('code' => 1, 'msg' => '_bx_credits_err_login_required');
  582. $fBalance = $this->getProfileBalance($iProfileId);
  583. if($fAmount > $fBalance)
  584. return array('code' => 2, 'msg' => '_bx_credits_err_low_balance');
  585. $aResult = array('code' => 3, 'msg' => '_bx_credits_err_cannot_send');
  586. $oEmailTemplates = BxDolEmailTemplates::getInstance();
  587. if(!$oEmailTemplates)
  588. return $aResult;
  589. $fRate = $this->_oConfig->getConversionRateWithdraw();
  590. $aTemplateVars = array(
  591. 'profile_link' => $oProfile->getUrl(),
  592. 'profile_name' => $oProfile->getDisplayName(),
  593. 'amount' => $fAmount,
  594. 'rate' => $fRate,
  595. 'message' => $sMessage,
  596. );
  597. $aTemplate = $oEmailTemplates->parseTemplate($CNF['ETEMPLATE_WITHDRAW_REQUESTED'], $aTemplateVars);
  598. if(!$aTemplate)
  599. return $aResult;
  600. $sEmail = $this->_oConfig->getWithdrawEmail();
  601. if(!sendMail($sEmail, $aTemplate['Subject'], $aTemplate['Body'], 0, array(), BX_EMAIL_SYSTEM, 'html', false, array(), false))
  602. return $aResult;
  603. bx_alert($this->getName(), 'withdraw_requested', 0, $iProfileId, array(
  604. 'profile' => $iProfileId,
  605. 'amount' => $fAmount,
  606. 'rate' => $fRate
  607. ));
  608. return array('code' => 0);
  609. }
  610. public function processWithdrawConfirm($iProfileId, $fAmount, $sMessage = '')
  611. {
  612. $CNF = &$this->_oConfig->CNF;
  613. $oProfile = BxDolProfile::getInstance($iProfileId);
  614. if(!$oProfile)
  615. return array('code' => 1, 'msg' => '_bx_credits_err_profile_not_found');
  616. $fBalance = $this->getProfileBalance($iProfileId);
  617. if($fAmount > $fBalance)
  618. return array('code' => 2, 'msg' => '_bx_credits_err_low_balance');
  619. $sInfo = _t('_bx_credits_txt_history_info_withdraw');
  620. if(!$this->updateProfileBalance($iProfileId, 0, -$fAmount, '', $sInfo))
  621. return array('code' => 3, 'msg' => '_bx_credits_err_cannot_update_balance');
  622. sendMailTemplate($CNF['ETEMPLATE_WITHDRAW_SENT'], 0, $iProfileId, array(
  623. 'amount' => $fAmount,
  624. 'message' => $sMessage
  625. ));
  626. bx_alert($this->getName(), 'withdraw_sent', 0, false, array(
  627. 'profile' => $iProfileId,
  628. 'amount' => $fAmount,
  629. ));
  630. return array('code' => 0);
  631. }
  632. /*
  633. * Internal methods
  634. */
  635. protected function _serviceRegisterItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense, $sType)
  636. {
  637. $CNF = &$this->_oConfig->CNF;
  638. $aItem = $this->serviceGetCartItem($iItemId);
  639. if(empty($aItem) || !is_array($aItem))
  640. return array();
  641. $aBundle = $this->_oDb->getBundle(array('type' => 'id', 'id' => $iItemId));
  642. if(empty($aBundle) || !is_array($aBundle))
  643. return array();
  644. $iTrial = 0;
  645. $sDuration = '';
  646. $sAction = 'register';
  647. if($sType == BX_CREDITS_ORDER_TYPE_RECURRING && isset($CNF['FIELD_DURATION_RECURRING'], $CNF['FIELD_TRIAL_RECURRING'])) {
  648. $iTrial = $aBundle[$CNF['FIELD_TRIAL_RECURRING']];
  649. $sDuration = $aBundle[$CNF['FIELD_DURATION_RECURRING']];
  650. if($this->_oDb->isOrderByPbo($iClientId, $iItemId, $sOrder))
  651. $sAction = 'prolong';
  652. }
  653. if(!$this->_oDb->{$sAction . 'Order'}($iClientId, $iItemId, $iItemCount, $sOrder, $sLicense, $sType, $sDuration, $iTrial))
  654. return array();
  655. $sInfo = _t('_bx_credits_txt_history_info_purchase');
  656. $fAmount = (float)$aBundle[$CNF['FIELD_AMOUNT']] + (float)$aBundle[$CNF['FIELD_BONUS']];
  657. if(!$this->updateProfileBalance($iClientId, 0, $fAmount, '', $sInfo))
  658. return array();
  659. bx_alert($this->getName(), 'order_' . $sAction, 0, false, array(
  660. 'profile_id' => $iClientId,
  661. 'bundle_id' => $iItemId,
  662. 'product_id' => $iItemId, //--- Alias for 'bundle_id'
  663. 'count' => $iItemCount,
  664. 'order' => $sOrder,
  665. 'license' => $sLicense,
  666. 'type' => $sType,
  667. 'duration' => $sDuration,
  668. 'trial' => $iTrial
  669. ));
  670. $oClient = BxDolProfile::getInstanceMagic($iClientId);
  671. $oSeller = BxDolProfile::getInstanceMagic($iSellerId);
  672. $sSellerUrl = $oSeller->getUrl();
  673. $sSellerName = $oSeller->getDisplayName();
  674. sendMailTemplate($CNF['ETEMPLATE_PURCHASED'], 0, $iClientId, array(
  675. 'client_name' => $oClient->getDisplayName(),
  676. 'bundle_name' => $aBundle[$CNF['FIELD_NAME']],
  677. 'bundle_title' => _t($aBundle[$CNF['FIELD_TITLE']]),
  678. 'bundle_url' => $this->_oConfig->getBundleUrl($aBundle),
  679. 'vendor_url' => $sSellerUrl,
  680. 'vendor_name' => $sSellerName,
  681. 'order' => $sOrder,
  682. 'license' => $sLicense,
  683. 'notes' => _t('_bx_credits_txt_purchased_note', $sSellerUrl, $sSellerName),
  684. ));
  685. return $aItem;
  686. }
  687. protected function _serviceUnregisterItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense, $sType)
  688. {
  689. $CNF = &$this->_oConfig->CNF;
  690. $aBundle = $this->_oDb->getBundle(array('type' => 'id', 'id' => $iItemId));
  691. if(empty($aBundle) || !is_array($aBundle))
  692. return false;
  693. if(!$this->_oDb->unregisterOrder($iClientId, $iItemId, $sOrder, $sLicense, $sType))
  694. return false;
  695. $fAmount = (float)$aBundle[$CNF['FIELD_AMOUNT']] + (float)$aBundle[$CNF['FIELD_BONUS']];
  696. $aProfile = $this->_oDb->getProfile(array('type' => 'id', 'id' => $iClientId));
  697. if(!empty($aProfile) && is_array($aProfile))
  698. $this->_oDb->updateProfile(array('balance' => (float)$aProfile['balance'] - $fAmount), array('id' => $aProfile['id']));
  699. bx_alert($this->getName(), 'order_unregister', 0, false, array(
  700. 'profile_id' => $iClientId,
  701. 'bundle_id' => $iItemId,
  702. 'product_id' => $iItemId, //--- Alias for 'bundle_id'
  703. 'count' => $iItemCount,
  704. 'order' => $sOrder,
  705. 'license' => $sLicense,
  706. 'type' => $sType,
  707. ));
  708. return true;
  709. }
  710. protected function _getBlockOrders($sType)
  711. {
  712. $CNF = &$this->_oConfig->CNF;
  713. $sGrid = $CNF['OBJECT_GRID_ORDERS_' . strtoupper($sType)];
  714. $oGrid = BxDolGrid::getObjectInstance($sGrid);
  715. if(!$oGrid)
  716. return '';
  717. return array(
  718. 'content' => $oGrid->getCode(),
  719. 'menu' => $CNF['OBJECT_MENU_MANAGE_SUBMENU']
  720. );
  721. }
  722. protected function _getBlockHistory($sType)
  723. {
  724. $CNF = &$this->_oConfig->CNF;
  725. $sGrid = $CNF['OBJECT_GRID_HISTORY_' . strtoupper($sType)];
  726. $oGrid = BxDolGrid::getObjectInstance($sGrid);
  727. if(!$oGrid)
  728. return '';
  729. return array(
  730. 'content' => $oGrid->getCode(),
  731. 'menu' => $CNF['OBJECT_MENU_MANAGE_SUBMENU']
  732. );
  733. }
  734. }
  735. /** @} */