BxCreditsModule.php 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093
  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_TRANSFER_TYPE_PURCHASE', 'purchase');
  12. define('BX_CREDITS_TRANSFER_TYPE_CHECKOUT', 'checkout');
  13. define('BX_CREDITS_TRANSFER_TYPE_CANCELLATION', 'cancellation');
  14. define('BX_CREDITS_TRANSFER_TYPE_GRANT', 'grant');
  15. define('BX_CREDITS_TRANSFER_TYPE_SEND', 'send');
  16. define('BX_CREDITS_TRANSFER_TYPE_WITHDRAW', 'withdraw');
  17. define('BX_CREDITS_TRANSFER_TYPE_SERVICE', 'service');
  18. define('BX_CREDITS_DIRECTION_IN', 'in');
  19. define('BX_CREDITS_DIRECTION_OUT', 'out');
  20. define('BX_CREDITS_ORDER_TYPE_SINGLE', 'single'); //--- one-time payment
  21. define('BX_CREDITS_ORDER_TYPE_RECURRING', 'recurring'); //--- recurring payment (subscription)
  22. class BxCreditsModule extends BxBaseModGeneralModule
  23. {
  24. function __construct(&$aModule)
  25. {
  26. parent::__construct($aModule);
  27. }
  28. public function actionGetProfiles()
  29. {
  30. $sTerm = bx_get('term');
  31. $a = BxDolService::call('system', 'profiles_search', array($sTerm), 'TemplServiceProfiles');
  32. echoJson($a);
  33. }
  34. public function actionCheckBundleName()
  35. {
  36. $CNF = &$this->_oConfig->CNF;
  37. $sName = bx_process_input(bx_get('name'));
  38. if(empty($sName))
  39. return echoJson(array());
  40. $sResult = '';
  41. $iId = (int)bx_get('id');
  42. if(!empty($iId)) {
  43. $aBundle = $this->_oDb->getBundle(array('type' => 'id', 'id' => $iId));
  44. if(strcmp($sName, $aBundle[$CNF['FIELD_NAME']]) == 0)
  45. $sResult = $sName;
  46. }
  47. echoJson(array(
  48. 'name' => !empty($sResult) ? $sResult : $this->_oConfig->getBundleName($sName)
  49. ));
  50. }
  51. public function actionCheckout()
  52. {
  53. $iBuyerId = bx_get_logged_profile_id();
  54. if(!$iBuyerId)
  55. return echoJson(array('code' => 1, 'msg' => _t('_bx_credits_err_unknown_buyer')));
  56. $aData = $this->_oConfig->getCheckoutData();
  57. if(empty($aData) || !is_array($aData))
  58. return echoJson(array('code' => 2, 'msg' => _t('_bx_credits_err_incorrect_data')));
  59. $iSellerId = (int)$aData['seller'];
  60. $fAmount = (float)$aData['amount'];
  61. $fBalance = (float)$this->_oDb->getProfile(array('type' => 'balance', 'id' => $iBuyerId));
  62. if($fAmount > $fBalance)
  63. return echoJson(array('code' => 3, 'msg' => _t('_bx_credits_err_low_balance')));
  64. $sOrder = $this->_oConfig->getOrder();
  65. $sInfo = '_bx_credits_txt_history_info_checkout';
  66. $sData = serialize(array(
  67. 'conversion' => $this->_oConfig->getConversionRateUse(),
  68. 'precision' => $this->_oConfig->getPrecision()
  69. ));
  70. $this->updateProfileBalance($iBuyerId, $iSellerId, -$fAmount, BX_CREDITS_TRANSFER_TYPE_CHECKOUT, $sOrder, $sInfo, $sData);
  71. $this->updateProfileBalance($iSellerId, $iBuyerId, $fAmount, BX_CREDITS_TRANSFER_TYPE_CHECKOUT, $sOrder, $sInfo, $sData);
  72. bx_alert($this->getName(), 'checkout', 0, false, array(
  73. 'seller' => $iSellerId,
  74. 'buyer' => $iBuyerId,
  75. 'amount' => $fAmount,
  76. 'order' => $sOrder
  77. ));
  78. return echoJson(array(
  79. 'code' => 0,
  80. 'redirect' => bx_append_url_params($aData['return_data_url'], array('o' => $sOrder, 'c' => $aData['custom']))
  81. ));
  82. }
  83. public function actionSubscribe()
  84. {
  85. $iBuyerId = bx_get_logged_profile_id();
  86. if(!$iBuyerId)
  87. return echoJson(array('code' => 1, 'msg' => _t('_bx_credits_err_unknown_buyer')));
  88. $aData = $this->_oConfig->getCheckoutData();
  89. if(empty($aData) || !is_array($aData))
  90. return echoJson(array('code' => 2, 'msg' => _t('_bx_credits_err_incorrect_data')));
  91. $iSellerId = (int)$aData['seller'];
  92. $fAmount = (float)$aData['amount'];
  93. $fBalance = (float)$this->_oDb->getProfile(array('type' => 'balance', 'id' => $iBuyerId));
  94. if($fAmount > $fBalance)
  95. return echoJson(array('code' => 3, 'msg' => _t('_bx_credits_err_low_balance')));
  96. $sUnique = $this->_oConfig->getOrder(9);
  97. $sCustomer = 'bx_cus_' . $sUnique;
  98. $sSubscription = 'bx_sub_' . $sUnique;
  99. bx_alert($this->getName(), 'subscribe', 0, false, array(
  100. 'seller' => $iSellerId,
  101. 'buyer' => $iBuyerId,
  102. 'amount' => $fAmount,
  103. 'trial' => $aData['trial'],
  104. 'customer' => $sCustomer,
  105. 'subscription' => $sSubscription
  106. ));
  107. return echoJson(array(
  108. 'code' => 0,
  109. 'redirect' => bx_append_url_params($aData['return_data_url'], array(
  110. 'cs' => $sCustomer,
  111. 'sb' => $sSubscription,
  112. 'tr' => $aData['trial'],
  113. 'c' => $aData['custom']
  114. ))
  115. ));
  116. }
  117. public function serviceGetSafeServices()
  118. {
  119. return array (
  120. 'GetBlockBundles' => '',
  121. 'GetBlockOrders' => '',
  122. 'GetBlockHistory' => '',
  123. );
  124. }
  125. public function serviceGetCheckoutUrl()
  126. {
  127. return $this->_oConfig->getCheckoutUrl();
  128. }
  129. public function serviceValidateCheckout($iSeller, $iBuyer, $fAmount, $sOrder)
  130. {
  131. $fAmount = (float)$fAmount;
  132. $aOut = $this->_oDb->getHistory(array('type' => 'row_by', 'by' => array('first_pid' => $iBuyer, 'direction' => BX_CREDITS_DIRECTION_OUT, 'order' => $sOrder)));
  133. if(empty($aOut) || !is_array($aOut) || (int)$aOut['second_pid'] != (int)$iSeller)
  134. return false;
  135. $aDataOut = unserialize($aOut['data']);
  136. if($this->_oConfig->convertM2C($fAmount, $aDataOut['conversion'], $aDataOut['precision']) != (float)$aOut['amount'])
  137. return false;
  138. $aIn = $this->_oDb->getHistory(array('type' => 'row_by', 'by' => array('first_pid' => $iSeller, 'direction' => BX_CREDITS_DIRECTION_IN, 'order' => $sOrder)));
  139. if(empty($aIn) || !is_array($aIn) || (int)$aIn['second_pid'] != (int)$iBuyer)
  140. return false;
  141. $aDataIn = unserialize($aIn['data']);
  142. if($this->_oConfig->convertM2C($fAmount, $aDataIn['conversion'], $aDataIn['precision']) != (float)$aIn['amount'])
  143. return false;
  144. return true;
  145. }
  146. public function serviceGetBlockCheckout()
  147. {
  148. $oBuyer = BxDolProfile::getInstance();
  149. if(!$oBuyer)
  150. return MsgBox(_t('_bx_credits_err_unknown_buyer'));
  151. $iSeller = (int)bx_get('seller');
  152. $oSeller = BxDolProfile::getInstance($iSeller);
  153. if(!$oSeller)
  154. return MsgBox(_t('_bx_credits_err_unknown_seller'));
  155. $fAmountM = (float)bx_get('amount');
  156. $fAmountC = $this->_oConfig->convertM2C($fAmountM);
  157. $aData = array(
  158. 'seller' => $iSeller,
  159. 'currency' => array(
  160. 'code' => bx_process_input(bx_get('currency_code')),
  161. 'sign' => bx_process_input(bx_get('currency_sign')),
  162. ),
  163. 'amountm' => $fAmountM,
  164. 'amountc' => $fAmountC
  165. );
  166. $iItemsCount = (int)bx_get('items_count');
  167. for($i = 0; $i < $iItemsCount; $i++) {
  168. $aData['items'][] = array(
  169. 'title' => bx_process_input(bx_get('item_title_' . $i)),
  170. 'quantity' => (int)bx_get('item_quantity_' . $i)
  171. );
  172. }
  173. $this->_oConfig->setCheckoutData(array(
  174. 'seller' => $iSeller,
  175. 'amount' => $fAmountC,
  176. 'custom' => bx_process_input(bx_get('custom')),
  177. 'return_data_url' => bx_process_input(bx_get('return_data_url')),
  178. ));
  179. return $this->_oTemplate->getBlockCheckout($oBuyer, $oSeller, $aData);
  180. }
  181. public function serviceGetPopupSubscribe($aData)
  182. {
  183. $oBuyer = BxDolProfile::getInstance();
  184. if(!$oBuyer)
  185. return array('msg' => _t('_bx_credits_err_unknown_buyer'));
  186. $iSeller = (int)$aData['seller'];
  187. $oSeller = BxDolProfile::getInstance($iSeller);
  188. if(!$oSeller)
  189. return array('msg' => _t('_bx_credits_err_unknown_seller'));
  190. $fAmountM = (float)$aData['amount'];
  191. $fAmountC = $this->_oConfig->convertM2C($fAmountM);
  192. $aData = array_merge($aData, array(
  193. 'amountm' => $fAmountM,
  194. 'amountc' => $fAmountC
  195. ));
  196. $this->_oConfig->setCheckoutData(array(
  197. 'seller' => $iSeller,
  198. 'amount' => $fAmountC,
  199. 'trial' => (int)$aData['trial'] > 0,
  200. 'custom' => bx_process_input($aData['custom']),
  201. 'return_data_url' => bx_process_input($aData['return_data_url']),
  202. ));
  203. return $this->_oTemplate->getPopupSubscribe($oBuyer, $oSeller, $aData);
  204. }
  205. public function serviceGetMenuItemAddonAmount()
  206. {
  207. $iProfileId = bx_get_logged_profile_id();
  208. if(!$iProfileId)
  209. return '';
  210. return array(
  211. 'unit' => $this->_oTemplate->getUnit(),
  212. 'value' => $this->convertC2S($this->_oDb->getProfile(array('type' => 'balance', 'id' => $iProfileId)), false)
  213. );
  214. }
  215. /**
  216. * @page service Service Calls
  217. * @section bx_credits Credits
  218. * @subsection bx_credits-page_blocks Page Blocks
  219. * @subsubsection bx_credits-get_block_bundles get_block_bundles
  220. *
  221. * @code bx_srv('bx_credits', 'get_block_bundles'); @endcode
  222. *
  223. * Get page block with bundles
  224. *
  225. * @see BxCreditsModule::serviceGetBlockBundles
  226. */
  227. /**
  228. * @ref bx_credits-get_block_bundles "get_block_bundles"
  229. */
  230. public function serviceGetBlockBundles()
  231. {
  232. return $this->_oTemplate->getBlockBundles();
  233. }
  234. /**
  235. * @page service Service Calls
  236. * @section bx_credits Credits
  237. * @subsection bx_credits-page_blocks Page Blocks
  238. * @subsubsection bx_credits-get_block_orders_note get_block_orders_note
  239. *
  240. * @code bx_srv('bx_credits', 'get_block_orders_note', [...]); @endcode
  241. *
  242. * Get page block with a notice for orders usage.
  243. *
  244. * @return HTML string with block content to display on the site.
  245. *
  246. * @see BxCreditsModule::serviceBlockLicensesNote
  247. */
  248. /**
  249. * @ref bx_credits-get_block_orders_note "get_block_orders_note"
  250. */
  251. public function serviceGetBlockOrdersNote()
  252. {
  253. return MsgBox(_t('_bx_credits_page_block_content_orders_common_note'));
  254. }
  255. /**
  256. * @page service Service Calls
  257. * @section bx_credits Credits
  258. * @subsection bx_credits-page_blocks Page Blocks
  259. * @subsubsection bx_credits-block_orders get_block_orders
  260. *
  261. * @code bx_srv('bx_credits', 'get_block_orders', [...]); @endcode
  262. *
  263. * Get page block with a list of orders purchased by currently logged member.
  264. *
  265. * @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.
  266. *
  267. * @see BxCreditsModule::serviceBlockLicenses
  268. */
  269. /**
  270. * @ref bx_credits-get_block_orders "get_block_orders"
  271. */
  272. public function serviceGetBlockOrders($sType = 'common')
  273. {
  274. return $this->_getBlockOrders($sType);
  275. }
  276. /**
  277. * @page service Service Calls
  278. * @section bx_credits Credits
  279. * @subsection bx_credits-page_blocks Page Blocks
  280. * @subsubsection bx_credits-get_block_history get_block_history
  281. *
  282. * @code bx_srv('bx_credits', 'get_block_history', [...]); @endcode
  283. *
  284. * Get page block with a list of all changes with credits.
  285. *
  286. * @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.
  287. *
  288. * @see BxCreditsModule::serviceGetBlockHistory
  289. */
  290. /**
  291. * @ref bx_credits-get_block_history "get_block_history"
  292. */
  293. public function serviceGetBlockHistory($sType = 'common')
  294. {
  295. return $this->_getBlockHistory($sType);
  296. }
  297. /**
  298. * @page service Service Calls
  299. * @section bx_credits Credits
  300. * @subsection bx_credits-payments Payments
  301. * @subsubsection bx_credits-get_payment_data get_payment_data
  302. *
  303. * @code bx_srv('bx_credits', 'get_payment_data', [...]); @endcode
  304. *
  305. * Get an array with module's description. Is needed for payments processing module.
  306. *
  307. * @return an array with module's description.
  308. *
  309. * @see BxCreditsModule::serviceGetPaymentData
  310. */
  311. /**
  312. * @ref bx_credits-get_payment_data "get_payment_data"
  313. */
  314. public function serviceGetPaymentData()
  315. {
  316. $CNF = &$this->_oConfig->CNF;
  317. $oPermalink = BxDolPermalinks::getInstance();
  318. $aResult = $this->_aModule;
  319. $aResult['url_browse_order_common'] = BX_DOL_URL_ROOT . $oPermalink->permalink($CNF['URL_ORDERS_COMMON'], array('filter' => '{order}'));
  320. $aResult['url_browse_order_administration'] = BX_DOL_URL_ROOT . $oPermalink->permalink($CNF['URL_ORDERS_ADMINISTRATION'], array('filter' => '{order}'));
  321. return $aResult;
  322. }
  323. /**
  324. * @page service Service Calls
  325. * @section bx_credits Credits
  326. * @subsection bx_credits-payments Payments
  327. * @subsubsection bx_credits-get_cart_item get_cart_item
  328. *
  329. * @code bx_srv('bx_credits', 'get_cart_item', [...]); @endcode
  330. *
  331. * Get an array with prodict's description. Is used in Shopping Cart in payments processing module.
  332. *
  333. * @param $iItemId product's ID.
  334. * @return an array with prodict's description. Empty array is returned if something is wrong.
  335. *
  336. * @see BxCreditsModule::serviceGetCartItem
  337. */
  338. /**
  339. * @ref bx_credits-get_cart_item "get_cart_item"
  340. */
  341. public function serviceGetCartItem($iItemId)
  342. {
  343. $CNF = &$this->_oConfig->CNF;
  344. if(!$iItemId)
  345. return array();
  346. $aItem = $this->_oDb->getBundle(array('type' => 'id', 'id' => $iItemId));
  347. if(empty($aItem) || !is_array($aItem))
  348. return array();
  349. return array (
  350. 'id' => $aItem[$CNF['FIELD_ID']],
  351. 'author_id' => $this->_oConfig->getAuthor(),
  352. 'name' => $aItem[$CNF['FIELD_NAME']],
  353. 'title' => _t($aItem[$CNF['FIELD_TITLE']]),
  354. 'description' => $this->_oConfig->getBundleDescription($aItem),
  355. 'url' => $this->_oConfig->getBundleUrl($aItem),
  356. 'price_single' => $aItem[$CNF['FIELD_PRICE']],
  357. 'price_recurring' => '',
  358. 'period_recurring' => 1,
  359. 'period_unit_recurring' => '',
  360. 'trial_recurring' => ''
  361. );
  362. }
  363. /**
  364. * @page service Service Calls
  365. * @section bx_credits Credits
  366. * @subsection bx_credits-payments Payments
  367. * @subsubsection bx_credits-get_cart_items get_cart_items
  368. *
  369. * @code bx_srv('bx_credits', 'get_cart_items', [...]); @endcode
  370. *
  371. * Get an array with prodicts' descriptions by seller. Is used in Manual Order Processing in payments processing module.
  372. *
  373. * @param $iSellerId seller ID.
  374. * @return an array with prodicts' descriptions. Empty array is returned if something is wrong or seller doesn't have any products.
  375. *
  376. * @see BxCreditsModule::serviceGetCartItems
  377. */
  378. /**
  379. * @ref bx_credits-get_cart_items "get_cart_items"
  380. */
  381. public function serviceGetCartItems($iAuthorId)
  382. {
  383. $CNF = &$this->_oConfig->CNF;
  384. $iAuthorId = $this->_oConfig->getAuthor();
  385. $aItems = $this->_oDb->getBundle(array('type' => 'all', 'active' => 1));
  386. $aResult = array();
  387. foreach($aItems as $aItem)
  388. $aResult[] = array(
  389. 'id' => $aItem[$CNF['FIELD_ID']],
  390. 'author_id' => $iAuthorId,
  391. 'name' => $aItem[$CNF['FIELD_NAME']],
  392. 'title' => _t($aItem[$CNF['FIELD_TITLE']]),
  393. 'description' => $this->_oConfig->getBundleDescription($aItem),
  394. 'url' => $this->_oConfig->getBundleUrl($aItem),
  395. 'price_single' => $aItem[$CNF['FIELD_PRICE']],
  396. 'price_recurring' => '',
  397. 'period_recurring' => 1,
  398. 'period_unit_recurring' => '',
  399. 'trial_recurring' => ''
  400. );
  401. return $aResult;
  402. }
  403. /**
  404. * @page service Service Calls
  405. * @section bx_credits Credits
  406. * @subsection bx_credits-payments Payments
  407. * @subsubsection bx_credits-register_cart_item register_cart_item
  408. *
  409. * @code bx_srv('bx_credits', 'register_cart_item', [...]); @endcode
  410. *
  411. * Register a processed single time payment inside the Credits module. Is called with payment processing module after the payment was registered there.
  412. *
  413. * @param $iClientId client ID.
  414. * @param $iSellerId seller ID
  415. * @param $iItemId item ID.
  416. * @param $iItemCount the number of purchased items.
  417. * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
  418. * @param $sLicense license number genereted with payment processing module for internal usage
  419. * @return an array with purchased prodict's description. Empty array is returned if something is wrong.
  420. *
  421. * @see BxCreditsModule::serviceRegisterCartItem
  422. */
  423. /**
  424. * @ref bx_credits-register_cart_item "register_cart_item"
  425. */
  426. public function serviceRegisterCartItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense)
  427. {
  428. return $this->_serviceRegisterItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense, BX_CREDITS_ORDER_TYPE_SINGLE);
  429. }
  430. /**
  431. * @page service Service Calls
  432. * @section bx_credits Credits
  433. * @subsection bx_credits-payments Payments
  434. * @subsubsection bx_credits-register_subscription_item register_subscription_item
  435. *
  436. * @code bx_srv('bx_credits', 'register_subscription_item', [...]); @endcode
  437. *
  438. * Register a processed subscription (recurring payment) inside the Credits module. Is called with payment processing module after the subscription was registered there.
  439. *
  440. * @param $iClientId client ID.
  441. * @param $iSellerId seller ID
  442. * @param $iItemId item ID.
  443. * @param $iItemCount the number of purchased items.
  444. * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
  445. * @param $sLicense license number genereted with payment processing module for internal usage
  446. * @return an array with subscribed prodict's description. Empty array is returned if something is wrong.
  447. *
  448. * @see BxCreditsModule::serviceRegisterSubscriptionItem
  449. */
  450. /**
  451. * @ref bx_credits-register_subscription_item "register_subscription_item"
  452. */
  453. public function serviceRegisterSubscriptionItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense)
  454. {
  455. return $this->_serviceRegisterItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense, BX_CREDITS_ORDER_TYPE_RECURRING);
  456. }
  457. /**
  458. * @page service Service Calls
  459. * @section bx_credits Credits
  460. * @subsection bx_credits-payments Payments
  461. * @subsubsection bx_credits-reregister_cart_item reregister_cart_item
  462. *
  463. * @code bx_srv('bx_credits', 'reregister_cart_item', [...]); @endcode
  464. *
  465. * Reregister a single time payment inside the Credits module. Is called with payment processing module after the payment was reregistered there.
  466. *
  467. * @param $iClientId client ID.
  468. * @param $iSellerId seller ID
  469. * @param $iItemIdOld old item ID.
  470. * @param $iItemIdNew new item ID.
  471. * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
  472. * @return an array with purchased prodict's description. Empty array is returned if something is wrong.
  473. *
  474. * @see BxCreditsModule::serviceReregisterCartItem
  475. */
  476. /**
  477. * @ref bx_credits-reregister_cart_item "reregister_cart_item"
  478. */
  479. public function serviceReregisterCartItem($iClientId, $iSellerId, $iItemIdOld, $iItemIdNew, $sOrder)
  480. {
  481. return array();
  482. }
  483. /**
  484. * @page service Service Calls
  485. * @section bx_credits Credits
  486. * @subsection bx_credits-payments Payments
  487. * @subsubsection bx_credits-reregister_subscription_item reregister_subscription_item
  488. *
  489. * @code bx_srv('bx_credits', 'reregister_subscription_item', [...]); @endcode
  490. *
  491. * Reregister a subscription (recurring payment) inside the Credits module. Is called with payment processing module after the subscription was reregistered there.
  492. *
  493. * @param $iClientId client ID.
  494. * @param $iSellerId seller ID
  495. * @param $iItemIdOld old item ID.
  496. * @param $iItemIdNew new item ID.
  497. * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
  498. * @return an array with subscribed prodict's description. Empty array is returned if something is wrong.
  499. *
  500. * @see BxCreditsModule::serviceReregisterSubscriptionItem
  501. */
  502. /**
  503. * @ref bx_credits-reregister_subscription_item "reregister_subscription_item"
  504. */
  505. public function serviceReregisterSubscriptionItem($iClientId, $iSellerId, $iItemIdOld, $iItemIdNew, $sOrder)
  506. {
  507. return array();
  508. }
  509. /**
  510. * @page service Service Calls
  511. * @section bx_credits Credits
  512. * @subsection bx_credits-payments Payments
  513. * @subsubsection bx_credits-unregister_cart_item unregister_cart_item
  514. *
  515. * @code bx_srv('bx_credits', 'unregister_cart_item', [...]); @endcode
  516. *
  517. * Unregister an earlier processed single time payment inside the Credits module. Is called with payment processing module after the payment was unregistered there.
  518. *
  519. * @param $iClientId client ID.
  520. * @param $iSellerId seller ID
  521. * @param $iItemId item ID.
  522. * @param $iItemCount the number of purchased items.
  523. * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
  524. * @param $sLicense license number genereted with payment processing module for internal usage
  525. * @return boolean value determining where the payment was unregistered or not.
  526. *
  527. * @see BxCreditsModule::serviceUnregisterCartItem
  528. */
  529. /**
  530. * @ref bx_credits-unregister_cart_item "unregister_cart_item"
  531. */
  532. public function serviceUnregisterCartItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense)
  533. {
  534. return $this->_serviceUnregisterItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense, BX_CREDITS_ORDER_TYPE_SINGLE);
  535. }
  536. /**
  537. * @page service Service Calls
  538. * @section bx_credits Credits
  539. * @subsection bx_credits-payments Payments
  540. * @subsubsection bx_credits-unregister_subscription_item unregister_subscription_item
  541. *
  542. * @code bx_srv('bx_credits', 'unregister_subscription_item', [...]); @endcode
  543. *
  544. * Unregister an earlier processed subscription (recurring payment) inside the Credits module. Is called with payment processing module after the subscription was unregistered there.
  545. *
  546. * @param $iClientId client ID.
  547. * @param $iSellerId seller ID
  548. * @param $iItemId item ID.
  549. * @param $iItemCount the number of purchased items.
  550. * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
  551. * @param $sLicense license number genereted with payment processing module for internal usage
  552. * @return boolean value determining where the subscription was unregistered or not.
  553. *
  554. * @see BxCreditsModule::serviceUnregisterSubscriptionItem
  555. */
  556. /**
  557. * @ref bx_credits-unregister_subscription_item "unregister_subscription_item"
  558. */
  559. public function serviceUnregisterSubscriptionItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense)
  560. {
  561. return $this->_serviceUnregisterItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense, BX_CREDITS_ORDER_TYPE_RECURRING);
  562. }
  563. /**
  564. * @page service Service Calls
  565. * @section bx_credits Credits
  566. * @subsection bx_credits-payments Payments
  567. * @subsubsection bx_credits-cancel_subscription_item cancel_subscription_item
  568. *
  569. * @code bx_srv('bx_credits', 'cancel_subscription_item', [...]); @endcode
  570. *
  571. * Cancel an earlier processed subscription (recurring payment) inside the Credits module. Is called with payment processing module after the subscription was canceled there.
  572. *
  573. * @param $iClientId client ID.
  574. * @param $iSellerId seller ID
  575. * @param $iItemId item ID.
  576. * @param $iItemCount the number of purchased items.
  577. * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
  578. * @return boolean value determining where the subscription was canceled or not.
  579. *
  580. * @see BxCreditsModule::serviceCancelSubscriptionItem
  581. */
  582. /**
  583. * @ref bx_credits-cancel_subscription_item "cancel_subscription_item"
  584. */
  585. public function serviceCancelSubscriptionItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder)
  586. {
  587. return true;
  588. }
  589. public function serviceGetProfileBalance($iProfileId = 0)
  590. {
  591. return $this->getProfileBalance($iProfileId);
  592. }
  593. public function serviceUpdateProfileBalance($iFirstPid, $fAmount, $iSecondPid = 0, $sOrder = '', $sInfo = '')
  594. {
  595. if(empty($sInfo))
  596. $sInfo = '_bx_credits_txt_history_info_service';
  597. return $this->updateProfileBalance($iFirstPid, $iSecondPid, $fAmount, BX_CREDITS_TRANSFER_TYPE_SERVICE, $sOrder, $sInfo);
  598. }
  599. public function serviceMakePayment($iBuyerPid, $fAmount, $iSellerPid, $sOrder = '')
  600. {
  601. $sInfo = '_bx_credits_txt_history_info_checkout';
  602. if(!$this->updateProfileBalance($iBuyerPid, $iSellerPid, -$fAmount, BX_CREDITS_TRANSFER_TYPE_CHECKOUT, $sOrder, $sInfo))
  603. return false;
  604. if(!$this->updateProfileBalance($iSellerPid, $iBuyerPid, $fAmount, $sOrder, BX_CREDITS_TRANSFER_TYPE_CHECKOUT, $sInfo)) {
  605. $this->updateProfileBalance($iBuyerPid, 0, $fAmount, BX_CREDITS_TRANSFER_TYPE_CANCELLATION, $sOrder, '_bx_credits_txt_history_info_cancellation');
  606. return false;
  607. }
  608. return true;
  609. }
  610. /**
  611. * Delete all content by profile
  612. * @param $iProfileId profile id
  613. * @return number of deleted items
  614. */
  615. public function serviceDeleteEntitiesByAuthor ($iProfileId)
  616. {
  617. $this->_oDb->deleteProfile(array('id' => $iProfileId));
  618. $this->_oDb->deleteHistory(array('first_pid' => $iProfileId));
  619. }
  620. /*
  621. * Common methods
  622. */
  623. public function convertC2S($fCredits, $bWithUnit = true)
  624. {
  625. $sResult = '';
  626. if($bWithUnit)
  627. $sResult .= $this->_oTemplate->getUnit();
  628. $iPrecision = $this->_oConfig->getPrecision();
  629. $sResult .= sprintf("%01." . $iPrecision . "f", round((float)$fCredits, $iPrecision));
  630. return $sResult;
  631. }
  632. public function getProfileBalance($iProfileId = 0)
  633. {
  634. if(empty($iProfileId))
  635. $iProfileId = bx_get_logged_profile_id();
  636. if(empty($iProfileId))
  637. return 0;
  638. return (float)$this->_oDb->getProfile(array('type' => 'balance', 'id' => $iProfileId));
  639. }
  640. public function getProfileBalanceCleared($iProfileId = 0)
  641. {
  642. if(empty($iProfileId))
  643. $iProfileId = bx_get_logged_profile_id();
  644. if(empty($iProfileId))
  645. return 0;
  646. $fCleared = (float)$this->_oDb->getHistory(['type' => 'cleared', 'profile' => $iProfileId]);
  647. $fSpent = (float)$this->_oDb->getHistory(['type' => 'spent', 'profile' => $iProfileId]);
  648. return $fCleared > $fSpent ? $fCleared - $fSpent : 0;
  649. }
  650. public function updateProfileBalance($iFirstPid, $iSecondPid, $fAmount, $sType, $sOrder = '', $sInfo = '', $sData = '')
  651. {
  652. $CNF = &$this->_oConfig->CNF;
  653. if(empty($sOrder))
  654. $sOrder = $this->_oConfig->getOrder();
  655. if(empty($sData))
  656. $sData = serialize(array(
  657. 'conversion' => $this->_oConfig->getConversionRateUse(),
  658. 'precision' => $this->_oConfig->getPrecision()
  659. ));
  660. if(!$this->_oDb->updateProfileBalance($iFirstPid, $fAmount))
  661. return false;
  662. $fAmountAbs = abs($fAmount);
  663. $sDirection = $fAmount > 0 ? BX_CREDITS_DIRECTION_IN : BX_CREDITS_DIRECTION_OUT;
  664. $iHistoryId = $this->_oDb->insertHistory([
  665. 'first_pid' => $iFirstPid,
  666. 'second_pid' => $iSecondPid,
  667. 'amount' => $fAmountAbs,
  668. 'type' => $sType,
  669. 'direction' => $sDirection,
  670. 'order' => $sOrder,
  671. 'data' => $sData,
  672. 'info' => $sInfo,
  673. 'date' => time()
  674. ]);
  675. if(!$iHistoryId)
  676. return false;
  677. bx_alert($this->getName(), 'update_balance', 0, false, array(
  678. 'first_pid' => $iFirstPid,
  679. 'second_pid' => $iSecondPid,
  680. 'amount' => $fAmountAbs,
  681. 'type' => $sType,
  682. 'direction' => $sDirection,
  683. 'order' => $sOrder,
  684. ));
  685. $oSecondProfile = BxDolProfile::getInstanceMagic($iSecondPid);
  686. sendMailTemplate($CNF['ETEMPLATE_' . strtoupper($sDirection)], 0, $iFirstPid, array(
  687. 'second_profile_name' => $oSecondProfile->getDisplayName(),
  688. 'amount' => $fAmountAbs,
  689. ));
  690. return $iHistoryId;
  691. }
  692. public function processGrant($iUserId, $iProfileId, $fAmount, $sMessage = '')
  693. {
  694. $CNF = &$this->_oConfig->CNF;
  695. $oProfile = BxDolProfile::getInstance($iProfileId);
  696. if(!$oProfile)
  697. return ['code' => 2, 'msg' => '_bx_credits_err_profile_not_found'];
  698. $sInfo = '_bx_credits_txt_history_info_grant';
  699. $iHistoryId = $this->updateProfileBalance($iProfileId, 0, $fAmount, BX_CREDITS_TRANSFER_TYPE_GRANT, '', $sInfo);
  700. if(!$iHistoryId)
  701. return ['code' => 3, 'msg' => '_bx_credits_err_cannot_update_balance'];
  702. sendMailTemplate($CNF['ETEMPLATE_GRANTED'], 0, $iProfileId, [
  703. 'amount' => $fAmount,
  704. 'message' => $sMessage
  705. ]);
  706. bx_alert($this->getName(), 'granted', 0, false, [
  707. 'profile' => $iProfileId,
  708. 'amount' => $fAmount,
  709. ]);
  710. return ['code' => 0, 'id' => $iHistoryId];
  711. }
  712. public function processSend($iUserId, $iProfileId, $fAmount, $sMessage = '')
  713. {
  714. $CNF = &$this->_oConfig->CNF;
  715. $fAmountAvail = $this->getProfileBalance($iUserId);
  716. if($fAmount > $fAmountAvail)
  717. return ['code' => 1, 'msg' => '_bx_credits_err_low_balance'];
  718. $oProfile = BxDolProfile::getInstance($iProfileId);
  719. if(!$oProfile)
  720. return ['code' => 2, 'msg' => '_bx_credits_err_profile_not_found'];
  721. $sOrder = $this->_oConfig->getOrder();
  722. $sInfo = !empty($sMessage) ? $sMessage : '_bx_credits_txt_history_info_send';
  723. $iHistoryId = $this->updateProfileBalance($iUserId, $iProfileId, -$fAmount, BX_CREDITS_TRANSFER_TYPE_SEND, $sOrder, $sInfo);
  724. if(!$iHistoryId)
  725. return ['code' => 3, 'msg' => '_bx_credits_err_cannot_update_balance'];
  726. if(!$this->updateProfileBalance($iProfileId, $iUserId, $fAmount, BX_CREDITS_TRANSFER_TYPE_SEND, $sOrder, $sInfo)) {
  727. $sInfo = '_bx_credits_txt_history_info_cancellation';
  728. $iHistoryId = $this->updateProfileBalance($iUserId, 0, $fAmount, BX_CREDITS_TRANSFER_TYPE_CANCELLATION, $sOrder, $sInfo);
  729. return ['code' => 3, 'id' => $iHistoryId, 'msg' => '_bx_credits_err_cannot_update_balance'];
  730. }
  731. $oUser = BxDolProfile::getInstance($iUserId);
  732. sendMailTemplate($CNF['ETEMPLATE_RECEIVED'], 0, $iProfileId, [
  733. 'performer_id' => $iUserId,
  734. 'performer_name' => $oUser->getDisplayName(),
  735. 'performer_link' => $oUser->getUrl(),
  736. 'amount' => $fAmount,
  737. 'order' => $sOrder,
  738. 'message' => $sMessage
  739. ]);
  740. bx_alert($this->getName(), 'sent', 0, $iUserId, [
  741. 'performer' => $iUserId,
  742. 'profile' => $iProfileId,
  743. 'amount' => $fAmount,
  744. 'order' => $sOrder,
  745. ]);
  746. return ['code' => 0, 'id' => $iHistoryId];
  747. }
  748. public function processWithdrawRequest($iUserId, $iProfileId, $fAmount, $sMessage = '')
  749. {
  750. $CNF = &$this->_oConfig->CNF;
  751. if(empty($iProfileId))
  752. $iProfileId = bx_get_logged_profile_id ();
  753. if(empty($iProfileId))
  754. return ['code' => 1, 'msg' => '_bx_credits_err_login_required'];
  755. $oProfile = BxDolProfile::getInstance($iProfileId);
  756. if(!$oProfile)
  757. return ['code' => 1, 'msg' => '_bx_credits_err_login_required'];
  758. $fBalanceCleared = $this->getProfileBalanceCleared($iProfileId);
  759. if($fAmount > $fBalanceCleared)
  760. return ['code' => 2, 'msg' => '_bx_credits_err_low_balance'];
  761. if($fAmount < ($iWithdrawMinimum = (int)getParam($CNF['PARAM_WITHDRAW_MINIMUM'])))
  762. return ['code' => 3, 'msg' => _t('_bx_credits_err_withdraw_minimum', $iWithdrawMinimum)];
  763. $fBalance = $this->getProfileBalance($iProfileId);
  764. if(($fBalance - $fAmount) < ($iWithdrawRemaining = (int)getParam($CNF['PARAM_WITHDRAW_REMAINING'])))
  765. return ['code' => 4, 'msg' => _t('_bx_credits_err_withdraw_remaining', $iWithdrawRemaining)];
  766. $aResult = ['code' => 5, 'msg' => '_bx_credits_err_cannot_send'];
  767. $fRate = $this->_oConfig->getConversionRateWithdraw();
  768. $aTemplateVars = [
  769. 'profile_link' => $oProfile->getUrl(),
  770. 'profile_name' => $oProfile->getDisplayName(),
  771. 'amount' => $fAmount,
  772. 'rate' => $fRate,
  773. 'message' => $sMessage,
  774. 'confirm_url' => BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink($CNF['URL_HISTORY_ADMINISTRATION'])
  775. ];
  776. $aTemplate = BxDolEmailTemplates::getInstance()->parseTemplate($CNF['ETEMPLATE_WITHDRAW_REQUESTED'], $aTemplateVars);
  777. if(!$aTemplate)
  778. return $aResult;
  779. $sEmail = $this->_oConfig->getWithdrawEmail();
  780. if(!sendMail($sEmail, $aTemplate['Subject'], $aTemplate['Body'], 0, [], BX_EMAIL_SYSTEM, 'html', false, [], true))
  781. return $aResult;
  782. bx_alert($this->getName(), 'withdraw_requested', 0, $iProfileId, [
  783. 'profile' => $iProfileId,
  784. 'amount' => $fAmount,
  785. 'rate' => $fRate
  786. ]);
  787. return ['code' => 0];
  788. }
  789. public function processWithdrawConfirm($iUserId, $iProfileId, $fAmount, $sMessage = '')
  790. {
  791. $CNF = &$this->_oConfig->CNF;
  792. $oProfile = BxDolProfile::getInstance($iProfileId);
  793. if(!$oProfile)
  794. return ['code' => 1, 'msg' => '_bx_credits_err_profile_not_found'];
  795. $fBalance = $this->getProfileBalance($iProfileId);
  796. if($fAmount > $fBalance)
  797. return ['code' => 2, 'msg' => '_bx_credits_err_low_balance'];
  798. $sInfo = '_bx_credits_txt_history_info_withdraw';
  799. $iHistoryId = $this->updateProfileBalance($iProfileId, 0, -$fAmount, BX_CREDITS_TRANSFER_TYPE_WITHDRAW, '', $sInfo);
  800. if(!$iHistoryId)
  801. return ['code' => 3, 'msg' => '_bx_credits_err_cannot_update_balance'];
  802. sendMailTemplate($CNF['ETEMPLATE_WITHDRAW_SENT'], 0, $iProfileId, [
  803. 'amount' => $fAmount,
  804. 'message' => $sMessage
  805. ]);
  806. bx_alert($this->getName(), 'withdraw_sent', 0, $iUserId, [
  807. 'performer' => $iUserId,
  808. 'profile' => $iProfileId,
  809. 'amount' => $fAmount,
  810. ]);
  811. return ['code' => 0, 'id' => $iHistoryId];
  812. }
  813. public function processClearing()
  814. {
  815. $CNF = &$this->_oConfig->CNF;
  816. $aItems = $this->_oDb->getHistory(['type' => 'clearing', 'clearing' => $this->_oConfig->getWithdrawClearing()]);
  817. if(empty($aItems) || !is_array($aItems))
  818. return;
  819. $iNow = time();
  820. foreach($aItems as $aItem) {
  821. $this->_oDb->updateHistory([$CNF['FIELD_H_CLEARED'] => $iNow], [$CNF['FIELD_H_ID'] => $aItem['id']]);
  822. //TODO: Some action(s) related to clearing can be performed here.
  823. }
  824. }
  825. /*
  826. * Internal methods
  827. */
  828. protected function _serviceRegisterItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense, $sType)
  829. {
  830. $CNF = &$this->_oConfig->CNF;
  831. $aItem = $this->serviceGetCartItem($iItemId);
  832. if(empty($aItem) || !is_array($aItem))
  833. return array();
  834. $aBundle = $this->_oDb->getBundle(array('type' => 'id', 'id' => $iItemId));
  835. if(empty($aBundle) || !is_array($aBundle))
  836. return array();
  837. $iTrial = 0;
  838. $sDuration = '';
  839. $sAction = 'register';
  840. if($sType == BX_CREDITS_ORDER_TYPE_RECURRING && isset($CNF['FIELD_DURATION_RECURRING'], $CNF['FIELD_TRIAL_RECURRING'])) {
  841. $iTrial = $aBundle[$CNF['FIELD_TRIAL_RECURRING']];
  842. $sDuration = $aBundle[$CNF['FIELD_DURATION_RECURRING']];
  843. if($this->_oDb->isOrderByPbo($iClientId, $iItemId, $sOrder))
  844. $sAction = 'prolong';
  845. }
  846. if(!$this->_oDb->{$sAction . 'Order'}($iClientId, $iItemId, $iItemCount, $sOrder, $sLicense, $sType, $sDuration, $iTrial))
  847. return array();
  848. $sInfo = '_bx_credits_txt_history_info_purchase';
  849. $fAmount = ((float)$aBundle[$CNF['FIELD_AMOUNT']] + (float)$aBundle[$CNF['FIELD_BONUS']]) * $iItemCount;
  850. if(!$this->updateProfileBalance($iClientId, 0, $fAmount, BX_CREDITS_TRANSFER_TYPE_PURCHASE, '', $sInfo))
  851. return array();
  852. bx_alert($this->getName(), 'order_' . $sAction, 0, false, array(
  853. 'profile_id' => $iClientId,
  854. 'bundle_id' => $iItemId,
  855. 'product_id' => $iItemId, //--- Alias for 'bundle_id'
  856. 'count' => $iItemCount,
  857. 'order' => $sOrder,
  858. 'license' => $sLicense,
  859. 'type' => $sType,
  860. 'duration' => $sDuration,
  861. 'trial' => $iTrial
  862. ));
  863. $oClient = BxDolProfile::getInstanceMagic($iClientId);
  864. $oSeller = BxDolProfile::getInstanceMagic($iSellerId);
  865. $sSellerUrl = $oSeller->getUrl();
  866. $sSellerName = $oSeller->getDisplayName();
  867. sendMailTemplate($CNF['ETEMPLATE_PURCHASED'], 0, $iClientId, array(
  868. 'client_name' => $oClient->getDisplayName(),
  869. 'bundle_name' => $aBundle[$CNF['FIELD_NAME']],
  870. 'bundle_title' => _t($aBundle[$CNF['FIELD_TITLE']]),
  871. 'bundle_url' => $this->_oConfig->getBundleUrl($aBundle),
  872. 'vendor_url' => $sSellerUrl,
  873. 'vendor_name' => $sSellerName,
  874. 'order' => $sOrder,
  875. 'license' => $sLicense,
  876. 'notes' => _t('_bx_credits_txt_purchased_note', $sSellerUrl, $sSellerName),
  877. ));
  878. return $aItem;
  879. }
  880. protected function _serviceUnregisterItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense, $sType)
  881. {
  882. $CNF = &$this->_oConfig->CNF;
  883. $aBundle = $this->_oDb->getBundle(array('type' => 'id', 'id' => $iItemId));
  884. if(empty($aBundle) || !is_array($aBundle))
  885. return false;
  886. if(!$this->_oDb->unregisterOrder($iClientId, $iItemId, $sOrder, $sLicense, $sType))
  887. return false;
  888. $fAmount = (float)$aBundle[$CNF['FIELD_AMOUNT']] + (float)$aBundle[$CNF['FIELD_BONUS']];
  889. $aProfile = $this->_oDb->getProfile(array('type' => 'id', 'id' => $iClientId));
  890. if(!empty($aProfile) && is_array($aProfile))
  891. $this->_oDb->updateProfile(array('balance' => (float)$aProfile['balance'] - $fAmount), array('id' => $aProfile['id']));
  892. bx_alert($this->getName(), 'order_unregister', 0, false, array(
  893. 'profile_id' => $iClientId,
  894. 'bundle_id' => $iItemId,
  895. 'product_id' => $iItemId, //--- Alias for 'bundle_id'
  896. 'count' => $iItemCount,
  897. 'order' => $sOrder,
  898. 'license' => $sLicense,
  899. 'type' => $sType,
  900. ));
  901. return true;
  902. }
  903. protected function _getBlockOrders($sType)
  904. {
  905. $CNF = &$this->_oConfig->CNF;
  906. $sGrid = $CNF['OBJECT_GRID_ORDERS_' . strtoupper($sType)];
  907. $oGrid = BxDolGrid::getObjectInstance($sGrid);
  908. if(!$oGrid)
  909. return '';
  910. return array(
  911. 'content' => $oGrid->getCode(),
  912. 'menu' => $CNF['OBJECT_MENU_MANAGE_SUBMENU']
  913. );
  914. }
  915. protected function _getBlockHistory($sType)
  916. {
  917. $CNF = &$this->_oConfig->CNF;
  918. $sGrid = $CNF['OBJECT_GRID_HISTORY_' . strtoupper($sType)];
  919. $oGrid = BxDolGrid::getObjectInstance($sGrid);
  920. if(!$oGrid)
  921. return '';
  922. return array(
  923. 'content' => $oGrid->getCode(),
  924. 'menu' => $CNF['OBJECT_MENU_MANAGE_SUBMENU']
  925. );
  926. }
  927. }
  928. /** @} */