BxMarketModule.php 57 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540
  1. <?php defined('BX_DOL') or die('hack attempt');
  2. /**
  3. * Copyright (c) UNA, Inc - https://una.io
  4. * MIT License - https://opensource.org/licenses/MIT
  5. *
  6. * @defgroup Market Market
  7. * @ingroup UnaModules
  8. *
  9. * @{
  10. */
  11. define('BX_MARKET_LICENSE_TYPE_SINGLE', 'single'); //--- one-time payment license
  12. define('BX_MARKET_LICENSE_TYPE_RECURRING', 'recurring'); //--- recurring payment license
  13. define('BX_MARKET_FILE_TYPE_VERSION', 'version');
  14. define('BX_MARKET_FILE_TYPE_UPDATE', 'update');
  15. /**
  16. * Market module
  17. */
  18. class BxMarketModule extends BxBaseModTextModule
  19. {
  20. function __construct(&$aModule)
  21. {
  22. parent::__construct($aModule);
  23. $CNF = &$this->_oConfig->CNF;
  24. $this->_aSearchableNamesExcept = array_merge($this->_aSearchableNamesExcept, array(
  25. $CNF['FIELD_NAME'],
  26. $CNF['FIELD_DURATION_RECURRING'],
  27. $CNF['FIELD_TRIAL_RECURRING'],
  28. $CNF['FIELD_ALLOW_PURCHASE_TO'],
  29. $CNF['FIELD_ALLOW_COMMENT_TO'],
  30. $CNF['FIELD_ALLOW_VOTE_TO'],
  31. $CNF['FIELD_NOTES_PURCHASED']
  32. ));
  33. }
  34. /**
  35. * Drops the replaced image file once the field is updated. Works for both
  36. * the site (actionUpdateImage) and API (update_image).
  37. */
  38. public function serviceUpdateImage($sFiledName, $iContentId, $sValue)
  39. {
  40. $CNF = &$this->_oConfig->CNF;
  41. $aData = $this->_oDb->getContentInfoById($iContentId);
  42. if(empty($aData) || !is_array($aData))
  43. return false;
  44. $mixedResult = parent::serviceUpdateImage($sFiledName, $iContentId, $sValue);
  45. if($mixedResult === false)
  46. return false;
  47. // Keep the file if it's still used as the other image (Icon and Header Image may share one).
  48. $iFileIdOld = (int)($aData[$sFiledName] ?? 0);
  49. $bUsed = false;
  50. foreach([$CNF['FIELD_THUMB'], $CNF['FIELD_COVER']] as $sField)
  51. if($sField != $sFiledName && (int)$aData[$sField] == $iFileIdOld)
  52. $bUsed = true;
  53. if($iFileIdOld && $iFileIdOld != (int)$sValue && !$bUsed && ($oStorage = BxDolStorage::getObjectInstance($CNF['OBJECT_STORAGE'])) !== false)
  54. $oStorage->deleteFile($iFileIdOld);
  55. return $mixedResult;
  56. }
  57. public function actionPerform()
  58. {
  59. $CNF = &$this->_oConfig->CNF;
  60. $aContentInfo = $this->_getContentInfo();
  61. if(empty($aContentInfo) || !is_array($aContentInfo))
  62. return echoJson(array('code' => 1));
  63. $sAction = bx_process_input(bx_get('action'));
  64. if(empty($CNF['MENU_ITEM_TO_METHOD'][$CNF['OBJECT_MENU_ACTIONS_VIEW_ENTRY']][$sAction]))
  65. return echoJson(array('code' => 2));
  66. $sMethodCheck = $CNF['MENU_ITEM_TO_METHOD'][$CNF['OBJECT_MENU_ACTIONS_VIEW_ENTRY']][$sAction];
  67. $sMethodPerform = '_perform' . bx_gen_method_name($sAction, array('-', '_'));
  68. if(!method_exists($this, $sMethodCheck) || $this->$sMethodCheck($aContentInfo) !== CHECK_ACTION_RESULT_ALLOWED || !method_exists($this, $sMethodPerform))
  69. return echoJson(array('code' => 3, 'msg' => _t('_sys_txt_access_denied')));
  70. return $this->$sMethodPerform($aContentInfo);
  71. }
  72. public function decodeDataAPI($aData, $aParams = [])
  73. {
  74. $CNF = $this->_oConfig->CNF;
  75. $aResult = parent::decodeDataAPI($aData, $aParams);
  76. $aResult = array_merge($aResult, [
  77. 'price_single' => $aData[$CNF['FIELD_PRICE_SINGLE']],
  78. 'price_recurring' => $aData[$CNF['FIELD_PRICE_RECURRING']],
  79. 'duration_recurring' => $aData[$CNF['FIELD_DURATION_RECURRING']],
  80. 'cover_raw' => $aData[$CNF['FIELD_COVER_RAW']],
  81. 'cover' => $this->serviceGetCover($aData[$CNF['FIELD_COVER']])
  82. ]);
  83. return $aResult;
  84. }
  85. public function actionCheckName()
  86. {
  87. $CNF = &$this->_oConfig->CNF;
  88. $sName = '';
  89. $sTitle = bx_process_input(bx_get('title'));
  90. if(empty($sTitle))
  91. return echoJson(array());
  92. $iId = (int)bx_get('id');
  93. if(!empty($iId)) {
  94. $aEntry = $this->_oDb->getContentInfoById($iId);
  95. if(strcmp($sTitle, $aEntry[$CNF['FIELD_NAME']]) == 0)
  96. $sName = $sTitle;
  97. }
  98. echoJson(array(
  99. 'title' => $sTitle,
  100. 'name' => !empty($sName) ? $sName : $this->_oConfig->getEntryName($sTitle, $iId)
  101. ));
  102. }
  103. public function actionGetSubentries()
  104. {
  105. $CNF = &$this->_oConfig->CNF;
  106. $sTerm = bx_get('term');
  107. $iLimit = (int)bx_get('limit');
  108. if(empty($iLimit))
  109. $iLimit = 10;
  110. $aResult = array();
  111. $aEntries = $this->_oDb->searchByAuthorTerm($this->_iProfileId, $sTerm, $iLimit);
  112. foreach ($aEntries as $aEntry)
  113. $aResult[] = array('value' => $aEntry[$CNF['FIELD_ID']], 'label' => $aEntry[$CNF['FIELD_TITLE']]);
  114. // sort result
  115. usort($aResult, function($r1, $r2) {
  116. return strcmp($r1['label'], $r2['label']);
  117. });
  118. echoJson(array_slice($aResult, 0, $iLimit));
  119. }
  120. public function serviceGetSafeServices()
  121. {
  122. return array_merge(parent::serviceGetSafeServices(), [
  123. 'EntityDownload' => '',
  124. 'EntityAuthorEntities' => '',
  125. 'BlockLicenses' => '',
  126. 'AddToCartApi' => '',
  127. 'SubscribeApi' => '',
  128. ]);
  129. }
  130. /**
  131. * @page service Service Calls
  132. * @section bx_market Market
  133. * @subsection bx_market-other Other
  134. * @subsubsection bx_market-get_searchable_fields get_searchable_fields
  135. *
  136. * @code bx_srv('bx_market', 'get_searchable_fields', [...]); @endcode
  137. *
  138. * Get a list of searchable fields. Is used in common search engine.
  139. *
  140. * @return an array with a list of searchable fields.
  141. *
  142. * @see BxMarketModule::serviceGetSearchableFields
  143. */
  144. /**
  145. * @ref bx_market-get_searchable_fields "get_searchable_fields"
  146. */
  147. public function serviceGetSearchableFields ($aInputsAdd = array())
  148. {
  149. $CNF = &$this->_oConfig->CNF;
  150. $aResult = parent::serviceGetSearchableFields($aInputsAdd);
  151. unset($aResult[$CNF['FIELD_PRICE_SINGLE']], $aResult[$CNF['FIELD_TRIAL_RECURRING']]);
  152. return $aResult;
  153. }
  154. /**
  155. * @page service Service Calls
  156. * @section bx_market Market
  157. * @subsection bx_market-page_blocks Page Blocks
  158. * @subsubsection bx_market-entity_create entity_create
  159. *
  160. * @code bx_srv('bx_market', 'entity_create', [...]); @endcode
  161. *
  162. * Get page block with product creation form or an error message if something wasn't configured correctly.
  163. *
  164. * @param $sDisplay form display name to use
  165. * @return HTML string with block content to display on the site, all necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
  166. *
  167. * @see BxMarketModule::serviceEntityCreate
  168. */
  169. /**
  170. * @ref bx_market-entity_create "entity_create"
  171. */
  172. public function serviceEntityCreate ($sDisplay = false)
  173. {
  174. $CNF = &$this->_oConfig->CNF;
  175. if(getParam($CNF['PARAM_NO_PAYMENTS']) != 'on') {
  176. $oPayments = BxDolPayments::getInstance();
  177. if(!$oPayments->isActive())
  178. return MsgBox(_t('_bx_market_err_no_payments'));
  179. if(!$oPayments->isAcceptingPayments($this->_iProfileId))
  180. return MsgBox(_t('_bx_market_err_not_accept_payments', $oPayments->getDetailsUrl()));
  181. }
  182. return parent::serviceEntityCreate($sDisplay);
  183. }
  184. /**
  185. * @page service Service Calls
  186. * @section bx_market Market
  187. * @subsection bx_market-page_blocks Page Blocks
  188. * @subsubsection bx_market-entity_download entity_download
  189. *
  190. * @code bx_srv('bx_market', 'entity_download', [...]); @endcode
  191. *
  192. * Get page block with a list of downloadable packages attached to the product. If something is wrong an error message is returned.
  193. *
  194. * @param $iContentId (optional) product's ID. If empty value is provided, an attempt to get it from GET/POST arrays will be performed.
  195. * @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.
  196. *
  197. * @see BxMarketModule::serviceEntityDownload
  198. */
  199. /**
  200. * @ref bx_market-entity_download "entity_download"
  201. */
  202. public function serviceEntityDownload ($iContentId = 0)
  203. {
  204. $CNF = &$this->_oConfig->CNF;
  205. if(!$iContentId)
  206. $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
  207. if(!$iContentId)
  208. return false;
  209. $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
  210. if(empty($aContentInfo) || !is_array($aContentInfo))
  211. return MsgBox(_t('_sys_txt_error_occured'));
  212. if($this->checkAllowedDownload($aContentInfo) !== CHECK_ACTION_RESULT_ALLOWED)
  213. return MsgBox(_t('_bx_market_err_access_denied'));
  214. $sJsObject = $this->_oConfig->getJsObject('entry');
  215. $oMenu = new BxTemplMenu(array('template' => 'menu_vertical.html', 'menu_id'=> 'bx-market-downloads', 'menu_items' => array(
  216. array('id' => 'bx-market-show-more', 'name' => 'bx-market-show-more', 'class' => '', 'link' => 'javascript:void(0)', 'target' => '_self', 'onclick' => 'javascript:' . $sJsObject . '.showMore();', 'title' => _t('_bx_market_menu_item_title_downloads_more')),
  217. )));
  218. $mixedResult = $this->_oTemplate->entryAttachmentsByStorage($CNF['OBJECT_STORAGE_FILES'], $aContentInfo, [
  219. 'filter_field' => ''
  220. ]);
  221. if($this->_bIsApi)
  222. foreach($mixedResult as $iKey => $aBlock)
  223. if($aBlock['type'] == 'entity_attachments')
  224. $mixedResult[$iKey]['type'] = 'market_attachments';
  225. return [
  226. 'menu' => $oMenu,
  227. 'content' => $mixedResult
  228. ];
  229. }
  230. /**
  231. * @page service Service Calls
  232. * @section bx_market Market
  233. * @subsection bx_market-page_blocks Page Blocks
  234. * @subsubsection bx_market-entity_rating entity_rating
  235. *
  236. * @code bx_srv('bx_market', 'entity_rating', [...]); @endcode
  237. *
  238. * Get page block with Stars based product's rating.
  239. *
  240. * @param $iContentId (optional) product's ID. If empty value is provided, an attempt to get it from GET/POST arrays will be performed.
  241. * @return HTML string with block content 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.
  242. *
  243. * @see BxMarketModule::serviceEntityRating
  244. */
  245. /**
  246. * @ref bx_market-entity_rating "entity_rating"
  247. */
  248. public function serviceEntityRating($iContentId = 0)
  249. {
  250. return $this->_serviceTemplateFunc ('entryRating', $iContentId);
  251. }
  252. /**
  253. * @page service Service Calls
  254. * @section bx_market Market
  255. * @subsection bx_market-page_blocks Page Blocks
  256. * @subsubsection bx_market-entity_author_entities entity_author_entities
  257. *
  258. * @code bx_srv('bx_market', 'entity_author_entities', [...]); @endcode
  259. *
  260. * Get page block with a list of other products of the same author.
  261. *
  262. * @param $iContentId (optional) product's ID. If empty value is provided, an attempt to get it from GET/POST arrays will be performed.
  263. * @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.
  264. *
  265. * @see BxMarketModule::serviceEntityAuthorEntities
  266. */
  267. /**
  268. * @ref bx_market-entity_author_entities "entity_author_entities"
  269. */
  270. public function serviceEntityAuthorEntities($iContentId = 0)
  271. {
  272. $CNF = &$this->_oConfig->CNF;
  273. $aContentInfo = $this->_getContentInfo($iContentId);
  274. if($aContentInfo === false)
  275. return false;
  276. $mixedResult = $this->_serviceBrowse ('author', ['author' => $aContentInfo[$CNF['FIELD_AUTHOR']], 'except' => [$iContentId], 'per_page' => 2], BX_DB_PADDING_DEF, true);
  277. if(!$mixedResult || !is_array($mixedResult))
  278. return $mixedResult;
  279. $sAuthor = ($oProfile = BxDolProfile::getInstance($aContentInfo[$CNF['FIELD_AUTHOR']])) !== false || ($oProfile = BxDolProfileUndefined::getInstance()) !== false ? $oProfile->getDisplayName() : '';
  280. $sTitle = _t('_bx_market_page_block_title_entry_author_entries', $sAuthor);
  281. if($this->_bIsApi)
  282. return [
  283. 'title' => $sTitle,
  284. 'content' => $mixedResult
  285. ];
  286. else
  287. $mixedResult['title'] = $sTitle;
  288. return $mixedResult;
  289. }
  290. /**
  291. * @page service Service Calls
  292. * @section bx_market Market
  293. * @subsection bx_market-page_blocks Page Blocks
  294. * @subsubsection bx_market-block_licenses block_licenses
  295. *
  296. * @code bx_srv('bx_market', 'block_licenses', [...]); @endcode
  297. *
  298. * Get page block with a list of licenses purchased by currently logged member.
  299. *
  300. * @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.
  301. *
  302. * @see BxMarketModule::serviceBlockLicenses
  303. */
  304. /**
  305. * @ref bx_market-block_licenses "block_licenses"
  306. */
  307. public function serviceBlockLicenses()
  308. {
  309. return $this->_getBlockLicenses();
  310. }
  311. /**
  312. * @page service Service Calls
  313. * @section bx_market Market
  314. * @subsection bx_market-page_blocks Page Blocks
  315. * @subsubsection bx_market-block_licenses_administration block_licenses_administration
  316. *
  317. * @code bx_srv('bx_market', 'block_licenses_administration', [...]); @endcode
  318. *
  319. * Get page block with a list of all licenses. It's needed for moderators/administrators.
  320. *
  321. * @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.
  322. *
  323. * @see BxMarketModule::serviceBlockLicensesAdministration
  324. */
  325. /**
  326. * @ref bx_market-block_licenses "block_licenses"
  327. */
  328. public function serviceBlockLicensesAdministration()
  329. {
  330. return $this->_getBlockLicenses('administration');
  331. }
  332. /**
  333. * @page service Service Calls
  334. * @section bx_market Market
  335. * @subsection bx_market-page_blocks Page Blocks
  336. * @subsubsection bx_market-block_licenses_note block_licenses_note
  337. *
  338. * @code bx_srv('bx_market', 'block_licenses_note', [...]); @endcode
  339. *
  340. * Get page block with a notice for licenses usage.
  341. *
  342. * @return HTML string with block content to display on the site.
  343. *
  344. * @see BxMarketModule::serviceBlockLicensesNote
  345. */
  346. /**
  347. * @ref bx_market-block_licenses_note "block_licenses_note"
  348. */
  349. public function serviceBlockLicensesNote()
  350. {
  351. return MsgBox(_t('_bx_market_page_block_content_licenses_note'));
  352. }
  353. /**
  354. * @page service Service Calls
  355. * @section bx_market Market
  356. * @subsection bx_market-licenses Licenses
  357. * @subsubsection bx_market-get_unused_licenses_num get_unused_licenses_num
  358. *
  359. * @code bx_srv('bx_market', 'get_unused_licenses_num', [...]); @endcode
  360. *
  361. * Get number of unused licenses for some profile. It can be used in menus with "alert" counters.
  362. *
  363. * @param $iProfileId profile to get unused licenses for, if omitted then currently logged in profile is used
  364. * @return an integer value with a number of unused licenses.
  365. *
  366. * @see BxMarketModule::serviceGetUnusedLicensesNum
  367. */
  368. /**
  369. * @ref bx_market-get_unused_licenses_num "get_unused_licenses_num"
  370. */
  371. public function serviceGetUnusedLicensesNum ($iProfileId = 0)
  372. {
  373. if(!$iProfileId)
  374. $iProfileId = bx_get_logged_profile_id();
  375. $aLicenses = $this->_oDb->getLicense(array('type' => 'new', 'profile_id' => (int)$iProfileId));
  376. return !empty($aLicenses) && is_array($aLicenses) ? count($aLicenses) : 0;
  377. }
  378. /**
  379. * @page service Service Calls
  380. * @section bx_market Market
  381. * @subsection bx_market-licenses Licenses
  382. * @subsubsection bx_market-has_license has_license
  383. *
  384. * @code bx_srv('bx_market', 'has_license', [...]); @endcode
  385. *
  386. * Check whether a profile has a license for specified product. Domain on which the license is used can be attached to checking.
  387. *
  388. * @param $iProfileId profile which ownership will be checked.
  389. * @param $iProductId product which the license(s) will be searched for.
  390. * @param $sDomain (optional) domain name on which the license is used.
  391. * @return boolean value determining where the license is available or not.
  392. *
  393. * @see BxMarketModule::serviceHasLicense
  394. */
  395. /**
  396. * @ref bx_market-has_license "has_license"
  397. */
  398. public function serviceHasLicense ($iProfileId, $iProductId, $sDomain = '')
  399. {
  400. return $this->_oDb->hasLicense($iProfileId, $iProductId, $sDomain);
  401. }
  402. /**
  403. * @page service Service Calls
  404. * @section bx_market Market
  405. * @subsection bx_market-licenses Licenses
  406. * @subsubsection bx_market-get_license get_license
  407. *
  408. * @code bx_srv('bx_market', 'has_license', [...]); @endcode
  409. *
  410. * Get a list of licenses which meet requirements provided in the input array.
  411. *
  412. * @param $aParams array of requirements which will be used for searching.
  413. * @return an array of licenses which meet requirements.
  414. *
  415. * @see BxMarketModule::serviceGetLicense
  416. */
  417. /**
  418. * @ref bx_market-get_license "get_license"
  419. */
  420. public function serviceGetLicense ($aParams)
  421. {
  422. return $this->_oDb->getLicense($aParams);
  423. }
  424. /**
  425. * @page service Service Calls
  426. * @section bx_market Market
  427. * @subsection bx_market-licenses Licenses
  428. * @subsubsection bx_market-register_license register_license
  429. *
  430. * @code bx_srv('bx_market', 'register_license', [...]); @endcode
  431. *
  432. * Register license(s) by provided details.
  433. *
  434. * @param $iProfileId
  435. * @return boolean value determining where the license was registered or not.
  436. *
  437. * @see BxMarketModule::serviceRegisterLicense
  438. */
  439. /**
  440. * @ref bx_market-register_license "register_license"
  441. */
  442. public function serviceRegisterLicense($iProfileId, $iProductId, $iCount, $sOrder, $sLicense, $sType = BX_PAYMENT_TYPE_SINGLE, $sDuration = '', $iTrial = 0)
  443. {
  444. return $this->_oDb->registerLicense($iProfileId, $iProductId, $iCount, $sOrder, $sLicense, $sType, $sDuration, $iTrial);
  445. }
  446. /**
  447. * @page service Service Calls
  448. * @section bx_market Market
  449. * @subsection bx_market-licenses Licenses
  450. * @subsubsection bx_market-unregister_license unregister_license
  451. *
  452. * @code bx_srv('bx_market', 'unregister_license', [...]); @endcode
  453. *
  454. * Unregister license(s) by provided details.
  455. *
  456. * @param $iProfileId
  457. * @return boolean value determining where the license was unregistered or not.
  458. *
  459. * @see BxMarketModule::serviceRegisterLicense
  460. */
  461. /**
  462. * @ref bx_market-unregister_license "unregister_license"
  463. */
  464. public function serviceUnregisterLicense($iProfileId, $iProductId, $sOrder, $sLicense, $sType = BX_PAYMENT_TYPE_SINGLE)
  465. {
  466. return $this->_oDb->unregisterLicense($iProfileId, $iProductId, $sOrder, $sLicense, $sType);
  467. }
  468. /**
  469. * @page service Service Calls
  470. * @section bx_market Market
  471. * @subsection bx_market-licenses Licenses
  472. * @subsubsection bx_market-update_license update_license
  473. *
  474. * @code bx_srv('bx_market', 'update_license', [...]); @endcode
  475. *
  476. * Update license(s) changing necessary fields. Updatable license(s) should meet requirements provided in the input array.
  477. *
  478. * @param $aSet an array of data to be saved
  479. * @param $aWhere an array of requirements which will be used for searching.
  480. * @return an array of licenses which meet requirements.
  481. *
  482. * @see BxMarketModule::serviceUpdateLicense
  483. */
  484. /**
  485. * @ref bx_market-update_license "update_license"
  486. */
  487. public function serviceUpdateLicense ($aSet, $aWhere)
  488. {
  489. return $this->_oDb->updateLicense($aSet, $aWhere);
  490. }
  491. /**
  492. * @page service Service Calls
  493. * @section bx_market Market
  494. * @subsection bx_market-browsing Browsing
  495. * @subsubsection bx_market-get_entry_by get_entry_by
  496. *
  497. * @code bx_srv('bx_market', 'get_entry_by', [...]); @endcode
  498. *
  499. * Get entry (product) which meets requirements.
  500. *
  501. * @param $sType string with search type.
  502. * @param $mixedValue mixed value to be used for searching.
  503. * @return an array describing a product which meets requirements.
  504. *
  505. * @see BxMarketModule::serviceGetEntryBy
  506. */
  507. /**
  508. * @ref bx_market-get_entry_by "get_entry_by"
  509. */
  510. public function serviceGetEntryBy($sType, $mixedValue)
  511. {
  512. return $this->_oDb->getContentInfoBy(array('type' => $sType, 'value' => $mixedValue));
  513. }
  514. /**
  515. * @page service Service Calls
  516. * @section bx_market Market
  517. * @subsection bx_market-browsing Browsing
  518. * @subsubsection bx_market-get_entries_by get_entries_by
  519. *
  520. * @code bx_srv('bx_market', 'get_entries_by', [...]); @endcode
  521. *
  522. * Get an array of entries (products) which meet requirements.
  523. *
  524. * @param $aParams an array of requirements which will be used for searching.
  525. * @return an array of products which meets requirements.
  526. *
  527. * @see BxMarketModule::serviceGetEntriesBy
  528. */
  529. /**
  530. * @ref bx_market-get_entries_by "get_entries_by"
  531. */
  532. public function serviceGetEntriesBy($aParams)
  533. {
  534. return $this->_oDb->getContentInfoBy($aParams);
  535. }
  536. /**
  537. * @page service Service Calls
  538. * @section bx_market Market
  539. * @subsection bx_market-browsing Browsing
  540. * @subsubsection bx_market-get_products_names get_products_names
  541. *
  542. * @code bx_srv('bx_market', 'get_products_names', [...]); @endcode
  543. *
  544. * Get an array of products names.
  545. *
  546. * @param $iVendorId return products of 1 vendor only
  547. * @param $iLimit limit the result artay
  548. * @return an array of products names
  549. *
  550. * @see BxMarketModule::serviceGetProductsNames
  551. */
  552. /**
  553. * @ref bx_market-get_products_names "get_products_names"
  554. */
  555. public function serviceGetProductsNames($iVendorId, $iLimit = 1000)
  556. {
  557. return $this->_oDb->getProductsNames($iVendorId, $iLimit);
  558. }
  559. /**
  560. * @page service Service Calls
  561. * @section bx_market Market
  562. * @subsection bx_market-entry Entry
  563. * @subsubsection bx_market-get_thumbnail get_thumbnail
  564. *
  565. * @code bx_srv('bx_market', 'get_thumbnail', [...]); @endcode
  566. *
  567. * Get an array of image URLs for the product's thumbnail. Returned images have different dimensions ('small' and 'big').
  568. *
  569. * @param $iPhotoId photo ID which is attached to a product as thumbnail.
  570. * @return an array of image URLs.
  571. *
  572. * @see BxMarketModule::serviceGetThumbnail
  573. */
  574. /**
  575. * @ref bx_market-get_thumbnail "get_thumbnail"
  576. */
  577. public function serviceGetThumbnail($iPhotoId)
  578. {
  579. $CNF = &$this->_oConfig->CNF;
  580. $oStorage = BxDolStorage::getObjectInstance($CNF['OBJECT_STORAGE']);
  581. $oImagesTranscoder = BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_IMAGES_TRANSCODER_GALLERY']);
  582. return array(
  583. 'small' => $oImagesTranscoder ? $oImagesTranscoder->getFileUrl($iPhotoId) : '',
  584. 'big' => $oStorage ? $oStorage->getFileUrlById($iPhotoId) : ''
  585. );
  586. }
  587. /**
  588. * @page service Service Calls
  589. * @section bx_market Market
  590. * @subsection bx_market-entry Entry
  591. * @subsubsection bx_market-get_cover get_cover
  592. *
  593. * @code bx_srv('bx_market', 'get_cover', [...]); @endcode
  594. *
  595. * Get an array of image URLs for the product's cover. Returned images have different dimensions ('small', 'large' and 'big').
  596. *
  597. * @param $iPhotoId photo ID which is attached to a product as cover.
  598. * @return an array of image URLs.
  599. *
  600. * @see BxMarketModule::serviceGetCover
  601. */
  602. /**
  603. * @ref bx_market-get_cover "get_cover"
  604. */
  605. public function serviceGetCover($iPhotoId)
  606. {
  607. $CNF = &$this->_oConfig->CNF;
  608. $oTiGallery = BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_IMAGES_TRANSCODER_GALLERY']);
  609. $oTiPage = BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_IMAGES_TRANSCODER_COVER']);
  610. $oStorage = BxDolStorage::getObjectInstance($CNF['OBJECT_STORAGE']);
  611. return array(
  612. 'medium' => $oTiGallery ? $oTiGallery->getFileUrl($iPhotoId) : '',
  613. 'large' => $oTiPage ? $oTiPage->getFileUrl($iPhotoId) : '',
  614. 'big' => $oStorage ? $oStorage->getFileUrlById($iPhotoId) : ''
  615. );
  616. }
  617. /**
  618. * @page service Service Calls
  619. * @section bx_market Market
  620. * @subsection bx_market-entry Entry
  621. * @subsubsection bx_market-get_file get_file
  622. *
  623. * @code bx_srv('bx_market', 'get_file', [...]); @endcode
  624. *
  625. * Get an array with file's description.
  626. *
  627. * @param $iFileId file ID which is attached to a product as package (version, update, etc).
  628. * @return an array with file's description.
  629. *
  630. * @see BxMarketModule::serviceGetFile
  631. */
  632. /**
  633. * @ref bx_market-get_file "get_file"
  634. */
  635. public function serviceGetFile($iFileId)
  636. {
  637. $CNF = &$this->_oConfig->CNF;
  638. $aFile = $this->_oDb->getFile(array(
  639. 'type' => 'file_id_ext',
  640. 'file_id' => $iFileId
  641. ));
  642. if(!empty($aFile) && is_array($aFile)) {
  643. $oStorage = BxDolStorage::getObjectInstance($CNF['OBJECT_STORAGE_FILES']);
  644. $aFile['file_url'] = $oStorage ? $oStorage->getFileUrlById($iFileId) : '';
  645. }
  646. return $aFile;
  647. }
  648. /**
  649. * @page service Service Calls
  650. * @section bx_market Market
  651. * @subsection bx_market-entry Entry
  652. * @subsubsection bx_market-get_files get_files
  653. *
  654. * @code bx_srv('bx_market', 'get_files', [...]); @endcode
  655. *
  656. * Get an array with files attached to the entry.
  657. *
  658. * @param $iEntryId product ID.
  659. * @param $sType file type ('version', 'update')
  660. * @return an array with files.
  661. *
  662. * @see BxMarketModule::serviceGetFiles
  663. */
  664. /**
  665. * @ref bx_market-get_files "get_files"
  666. */
  667. public function serviceGetFiles($iEntryId, $sType)
  668. {
  669. return $this->_oDb->getFile(array(
  670. 'type' => 'content_id_and_type',
  671. 'content_id' => $iEntryId,
  672. 'file_type' => $sType,
  673. 'ordered' => true
  674. ));
  675. }
  676. /**
  677. * @page service Service Calls
  678. * @section bx_market Market
  679. * @subsection bx_market-entry Entry
  680. * @subsubsection bx_market-get_updates get_updates
  681. *
  682. * @code bx_srv('bx_market', 'get_updates', [...]); @endcode
  683. *
  684. * Get an array with update(s)' description(s).
  685. *
  686. * @param $iContentId product's ID.
  687. * @param $sVersion (optional) if version is specified then it will be used for searching as 'Version From'.
  688. * @return an array with update(s)' description(s).
  689. *
  690. * @see BxMarketModule::serviceGetUpdates
  691. */
  692. /**
  693. * @ref bx_market-get_updates "get_updates"
  694. */
  695. public function serviceGetUpdates($iContentId, $sVersion = '')
  696. {
  697. $CNF = &$this->_oConfig->CNF;
  698. $aFile = $this->_oDb->getFile(array(
  699. 'type' => 'content_id_and_type',
  700. 'content_id' => $iContentId,
  701. 'file_type' => 'update',
  702. 'version' => $sVersion
  703. ));
  704. if(!empty($aFile) && is_array($aFile)) {
  705. $oStorage = BxDolStorage::getObjectInstance($CNF['OBJECT_STORAGE_FILES']);
  706. $aFile['file_url'] = $oStorage ? $oStorage->getFileUrlById($aFile['file_id']) : '';
  707. }
  708. return $aFile;
  709. }
  710. /**
  711. * @page service Service Calls
  712. * @section bx_market Market
  713. * @subsection bx_market-entry Entry
  714. * @subsubsection bx_market-get_screenshots get_screenshots
  715. *
  716. * @code bx_srv('bx_market', 'get_screenshots', [...]); @endcode
  717. *
  718. * Get an array with screenshots' descriptions.
  719. *
  720. * @param $iItemId product's ID.
  721. * @return an array with screenshots' descriptions.
  722. *
  723. * @see BxMarketModule::serviceGetScreenshots
  724. */
  725. /**
  726. * @ref bx_market-get_screenshots "get_screenshots"
  727. */
  728. public function serviceGetScreenshots($iItemId)
  729. {
  730. $CNF = &$this->_oConfig->CNF;
  731. if(!$iItemId)
  732. return [];
  733. $aData = $this->_oDb->getContentInfoById($iItemId);
  734. $aPhotos = $this->_oDb->getPhoto(array('type' => 'content_id', 'content_id' => $aData[$CNF['FIELD_ID']], 'except' => array($aData[$CNF['FIELD_THUMB']], $aData[$CNF['FIELD_COVER']])));
  735. if(empty($aPhotos) || !is_array($aPhotos))
  736. return [];
  737. $oStorage = BxDolStorage::getObjectInstance($CNF['OBJECT_STORAGE']);
  738. if(!$oStorage)
  739. return [];
  740. $oImagesTranscoder = BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_IMAGES_TRANSCODER_SCREENSHOT']);
  741. $aResult = [];
  742. foreach($aPhotos as $aPhoto) {
  743. $sUrlSm = '';
  744. $sUrlBg = $oStorage->getFileUrlById($aPhoto['file_id']);
  745. $aPhotoInfo = $oStorage->getFile($aPhoto['file_id']);
  746. if(strpos($aPhotoInfo['mime_type'], 'svg') !== false)
  747. $sUrlSm = $sUrlBg;
  748. else
  749. $sUrlSm = $oImagesTranscoder ? $oImagesTranscoder->getFileUrl($aPhoto['file_id']) : '';
  750. $aResult[] = [
  751. 'id' => $aPhoto['file_id'],
  752. 'url_sm' => $sUrlSm,
  753. 'url_bg' => $sUrlBg
  754. ];
  755. }
  756. return $aResult;
  757. }
  758. /**
  759. * @page service Service Calls
  760. * @section bx_market Market
  761. * @subsection bx_market-payments Payments
  762. * @subsubsection bx_market-get_payment_data get_payment_data
  763. *
  764. * @code bx_srv('bx_market', 'get_payment_data', [...]); @endcode
  765. *
  766. * Get an array with module's description. Is needed for payments processing module.
  767. *
  768. * @return an array with module's description.
  769. *
  770. * @see BxMarketModule::serviceGetPaymentData
  771. */
  772. /**
  773. * @ref bx_market-get_payment_data "get_payment_data"
  774. */
  775. public function serviceGetPaymentData()
  776. {
  777. $CNF = &$this->_oConfig->CNF;
  778. $oPermalink = BxDolPermalinks::getInstance();
  779. return array_merge($this->_aModule, [
  780. 'url_browse_order_common' => bx_absolute_url(bx_append_url_params($oPermalink->permalink($CNF['URL_LICENSES_COMMON']), ['filter' => '{order}'], false)),
  781. 'url_browse_order_administration' => bx_absolute_url(bx_append_url_params($oPermalink->permalink($CNF['URL_LICENSES_ADMINISTRATION']), ['filter' => '{order}'], false))
  782. ]);
  783. }
  784. /**
  785. * @page service Service Calls
  786. * @section bx_market Market
  787. * @subsection bx_market-payments Payments
  788. * @subsubsection bx_market-get_cart_item get_cart_item
  789. *
  790. * @code bx_srv('bx_market', 'get_cart_item', [...]); @endcode
  791. *
  792. * Get an array with prodict's description. Is used in Shopping Cart in payments processing module.
  793. *
  794. * @param $mixedItemId product's ID or Unique Name.
  795. * @return an array with prodict's description. Empty array is returned if something is wrong.
  796. *
  797. * @see BxMarketModule::serviceGetCartItem
  798. */
  799. /**
  800. * @ref bx_market-get_cart_item "get_cart_item"
  801. */
  802. public function serviceGetCartItem($mixedItemId)
  803. {
  804. $CNF = &$this->_oConfig->CNF;
  805. if(!$mixedItemId)
  806. return array();
  807. if(is_numeric($mixedItemId))
  808. $aItem = $this->_oDb->getContentInfoById((int)$mixedItemId);
  809. else
  810. $aItem = $this->_oDb->getContentInfoByName($mixedItemId);
  811. if(empty($aItem) || !is_array($aItem))
  812. return array();
  813. return array (
  814. 'id' => $aItem[$CNF['FIELD_ID']],
  815. 'author_id' => $aItem[$CNF['FIELD_AUTHOR']],
  816. 'name' => $aItem[$CNF['FIELD_NAME']],
  817. 'title' => $aItem[$CNF['FIELD_TITLE']],
  818. 'description' => $aItem[$CNF['FIELD_TEXT']],
  819. 'url' => bx_absolute_url(BxDolPermalinks::getInstance()->permalink('page.php?i=view-product&id=' . $aItem[$CNF['FIELD_ID']])),
  820. 'price_single' => $aItem[$CNF['FIELD_PRICE_SINGLE']],
  821. 'price_recurring' => $aItem[$CNF['FIELD_PRICE_RECURRING']],
  822. 'period_recurring' => 1,
  823. 'period_unit_recurring' => $aItem[$CNF['FIELD_DURATION_RECURRING']],
  824. 'trial_recurring' => $aItem[$CNF['FIELD_TRIAL_RECURRING']],
  825. 'added' => $aItem[$CNF['FIELD_ADDED']],
  826. );
  827. }
  828. /**
  829. * @page service Service Calls
  830. * @section bx_market Market
  831. * @subsection bx_market-payments Payments
  832. * @subsubsection bx_market-get_cart_items get_cart_items
  833. *
  834. * @code bx_srv('bx_market', 'get_cart_items', [...]); @endcode
  835. *
  836. * Get an array with prodicts' descriptions by seller. Is used in Manual Order Processing in payments processing module.
  837. *
  838. * @param $iSellerId seller ID.
  839. * @return an array with prodicts' descriptions. Empty array is returned if something is wrong or seller doesn't have any products.
  840. *
  841. * @see BxMarketModule::serviceGetCartItems
  842. */
  843. /**
  844. * @ref bx_market-get_cart_items "get_cart_items"
  845. */
  846. public function serviceGetCartItems($iSellerId)
  847. {
  848. $CNF = &$this->_oConfig->CNF;
  849. $iSellerId = (int)$iSellerId;
  850. if(empty($iSellerId))
  851. return array();
  852. $aItems = $this->_oDb->getEntriesByAuthor($iSellerId);
  853. $aResult = array();
  854. foreach($aItems as $aItem)
  855. $aResult[] = array(
  856. 'id' => $aItem[$CNF['FIELD_ID']],
  857. 'author_id' => $aItem[$CNF['FIELD_AUTHOR']],
  858. 'name' => $aItem[$CNF['FIELD_NAME']],
  859. 'title' => $aItem[$CNF['FIELD_TITLE']],
  860. 'description' => $aItem[$CNF['FIELD_TEXT']],
  861. 'url' => bx_absolute_url(BxDolPermalinks::getInstance()->permalink('page.php?i=view-product&id=' . $aItem[$CNF['FIELD_ID']])),
  862. 'price_single' => $aItem[$CNF['FIELD_PRICE_SINGLE']],
  863. 'price_recurring' => $aItem[$CNF['FIELD_PRICE_RECURRING']],
  864. 'period_recurring' => 1,
  865. 'period_unit_recurring' => $aItem[$CNF['FIELD_DURATION_RECURRING']],
  866. 'trial_recurring' => $aItem[$CNF['FIELD_TRIAL_RECURRING']]
  867. );
  868. return $aResult;
  869. }
  870. /**
  871. * @page service Service Calls
  872. * @section bx_market Market
  873. * @subsection bx_market-payments Payments
  874. * @subsubsection bx_market-register_cart_item register_cart_item
  875. *
  876. * @code bx_srv('bx_market', 'register_cart_item', [...]); @endcode
  877. *
  878. * Register a processed single time payment inside the Market module. Is called with payment processing module after the payment was registered there.
  879. *
  880. * @param $iClientId client ID.
  881. * @param $iSellerId seller ID
  882. * @param $iItemId item ID.
  883. * @param $iItemCount the number of purchased items.
  884. * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
  885. * @param $sLicense license number genereted with payment processing module for internal usage
  886. * @return an array with purchased prodict's description. Empty array is returned if something is wrong.
  887. *
  888. * @see BxMarketModule::serviceRegisterCartItem
  889. */
  890. /**
  891. * @ref bx_market-register_cart_item "register_cart_item"
  892. */
  893. public function serviceRegisterCartItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense)
  894. {
  895. return $this->_serviceRegisterItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense, BX_MARKET_LICENSE_TYPE_SINGLE);
  896. }
  897. /**
  898. * @page service Service Calls
  899. * @section bx_market Market
  900. * @subsection bx_market-payments Payments
  901. * @subsubsection bx_market-register_subscription_item register_subscription_item
  902. *
  903. * @code bx_srv('bx_market', 'register_subscription_item', [...]); @endcode
  904. *
  905. * Register a processed subscription (recurring payment) inside the Market module. Is called with payment processing module after the subscription was registered there.
  906. *
  907. * @param $iClientId client ID.
  908. * @param $iSellerId seller ID
  909. * @param $iItemId item ID.
  910. * @param $iItemCount the number of purchased items.
  911. * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
  912. * @param $sLicense license number genereted with payment processing module for internal usage
  913. * @return an array with subscribed prodict's description. Empty array is returned if something is wrong.
  914. *
  915. * @see BxMarketModule::serviceRegisterSubscriptionItem
  916. */
  917. /**
  918. * @ref bx_market-register_subscription_item "register_subscription_item"
  919. */
  920. public function serviceRegisterSubscriptionItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense)
  921. {
  922. return $this->_serviceRegisterItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense, BX_MARKET_LICENSE_TYPE_RECURRING);
  923. }
  924. /**
  925. * @page service Service Calls
  926. * @section bx_market Market
  927. * @subsection bx_market-payments Payments
  928. * @subsubsection bx_market-reregister_cart_item reregister_cart_item
  929. *
  930. * @code bx_srv('bx_market', 'reregister_cart_item', [...]); @endcode
  931. *
  932. * Reregister a single time payment inside the Market module. Is called with payment processing module after the payment was reregistered there.
  933. *
  934. * @param $iClientId client ID.
  935. * @param $iSellerId seller ID
  936. * @param $iItemIdOld old item ID.
  937. * @param $iItemIdNew new item ID.
  938. * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
  939. * @return an array with purchased prodict's description. Empty array is returned if something is wrong.
  940. *
  941. * @see BxMarketModule::serviceReregisterCartItem
  942. */
  943. /**
  944. * @ref bx_market-reregister_cart_item "reregister_cart_item"
  945. */
  946. public function serviceReregisterCartItem($iClientId, $iSellerId, $iItemIdOld, $iItemIdNew, $sOrder)
  947. {
  948. return $this->_serviceReregisterItem($iClientId, $iSellerId, $iItemIdOld, $iItemIdNew, $sOrder, BX_MARKET_LICENSE_TYPE_SINGLE);
  949. }
  950. /**
  951. * @page service Service Calls
  952. * @section bx_market Market
  953. * @subsection bx_market-payments Payments
  954. * @subsubsection bx_market-reregister_subscription_item reregister_subscription_item
  955. *
  956. * @code bx_srv('bx_market', 'reregister_subscription_item', [...]); @endcode
  957. *
  958. * Reregister a subscription (recurring payment) inside the Market module. Is called with payment processing module after the subscription was reregistered there.
  959. *
  960. * @param $iClientId client ID.
  961. * @param $iSellerId seller ID
  962. * @param $iItemIdOld old item ID.
  963. * @param $iItemIdNew new item ID.
  964. * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
  965. * @return an array with subscribed prodict's description. Empty array is returned if something is wrong.
  966. *
  967. * @see BxMarketModule::serviceReregisterSubscriptionItem
  968. */
  969. /**
  970. * @ref bx_market-reregister_subscription_item "reregister_subscription_item"
  971. */
  972. public function serviceReregisterSubscriptionItem($iClientId, $iSellerId, $iItemIdOld, $iItemIdNew, $sOrder)
  973. {
  974. return $this->_serviceReregisterItem($iClientId, $iSellerId, $iItemIdOld, $iItemIdNew, $sOrder, BX_MARKET_LICENSE_TYPE_RECURRING);
  975. }
  976. /**
  977. * @page service Service Calls
  978. * @section bx_market Market
  979. * @subsection bx_market-payments Payments
  980. * @subsubsection bx_market-unregister_cart_item unregister_cart_item
  981. *
  982. * @code bx_srv('bx_market', 'unregister_cart_item', [...]); @endcode
  983. *
  984. * Unregister an earlier processed single time payment inside the Market module. Is called with payment processing module after the payment was unregistered there.
  985. *
  986. * @param $iClientId client ID.
  987. * @param $iSellerId seller ID
  988. * @param $iItemId item ID.
  989. * @param $iItemCount the number of purchased items.
  990. * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
  991. * @param $sLicense license number genereted with payment processing module for internal usage
  992. * @return boolean value determining where the payment was unregistered or not.
  993. *
  994. * @see BxMarketModule::serviceUnregisterCartItem
  995. */
  996. /**
  997. * @ref bx_market-unregister_cart_item "unregister_cart_item"
  998. */
  999. public function serviceUnregisterCartItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense)
  1000. {
  1001. return $this->_serviceUnregisterItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense, BX_MARKET_LICENSE_TYPE_SINGLE);
  1002. }
  1003. /**
  1004. * @page service Service Calls
  1005. * @section bx_market Market
  1006. * @subsection bx_market-payments Payments
  1007. * @subsubsection bx_market-unregister_subscription_item unregister_subscription_item
  1008. *
  1009. * @code bx_srv('bx_market', 'unregister_subscription_item', [...]); @endcode
  1010. *
  1011. * Unregister an earlier processed subscription (recurring payment) inside the Market module. Is called with payment processing module after the subscription was unregistered there.
  1012. *
  1013. * @param $iClientId client ID.
  1014. * @param $iSellerId seller ID
  1015. * @param $iItemId item ID.
  1016. * @param $iItemCount the number of purchased items.
  1017. * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
  1018. * @param $sLicense license number genereted with payment processing module for internal usage
  1019. * @return boolean value determining where the subscription was unregistered or not.
  1020. *
  1021. * @see BxMarketModule::serviceUnregisterSubscriptionItem
  1022. */
  1023. /**
  1024. * @ref bx_market-unregister_subscription_item "unregister_subscription_item"
  1025. */
  1026. public function serviceUnregisterSubscriptionItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense)
  1027. {
  1028. return $this->_serviceUnregisterItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense, BX_MARKET_LICENSE_TYPE_RECURRING);
  1029. }
  1030. /**
  1031. * @page service Service Calls
  1032. * @section bx_market Market
  1033. * @subsection bx_market-payments Payments
  1034. * @subsubsection bx_market-cancel_subscription_item cancel_subscription_item
  1035. *
  1036. * @code bx_srv('bx_market', 'cancel_subscription_item', [...]); @endcode
  1037. *
  1038. * Cancel an earlier processed subscription (recurring payment) inside the Market module. Is called with payment processing module after the subscription was canceled there.
  1039. *
  1040. * @param $iClientId client ID.
  1041. * @param $iSellerId seller ID
  1042. * @param $iItemId item ID.
  1043. * @param $iItemCount the number of purchased items.
  1044. * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
  1045. * @return boolean value determining where the subscription was canceled or not.
  1046. *
  1047. * @see BxMarketModule::serviceCancelSubscriptionItem
  1048. */
  1049. /**
  1050. * @ref bx_market-cancel_subscription_item "cancel_subscription_item"
  1051. */
  1052. public function serviceCancelSubscriptionItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder)
  1053. {
  1054. //TODO: Do something if it's necessary.
  1055. return true;
  1056. }
  1057. public function serviceAddToCartApi($sDescriptor)
  1058. {
  1059. if(!$this->_bIsApi)
  1060. return;
  1061. $oPayment = BxDolPayments::getInstance();
  1062. $aDescriptor = $oPayment->getActiveObject()->_oConfig->descriptorS2A($sDescriptor);
  1063. if(!$aDescriptor || !is_array($aDescriptor))
  1064. return [bx_api_get_msg(_t('_sys_txt_error_occured'))]; //TODO: Ask Roman How to return error message.
  1065. $iSeller = (int)$aDescriptor[0];
  1066. $aResult = $oPayment->addToCart($iSeller, $this->_oConfig->getName(), (int)$aDescriptor[2], 1, true);
  1067. if(($iCode = $aResult['code'] ?? false) && (int)$iCode != 0)
  1068. return [bx_api_get_msg($aResult['message'])]; //TODO: Ask Roman How to return error message.
  1069. else
  1070. return [
  1071. 'url' => $oPayment->getCartUrl($iSeller)
  1072. ];
  1073. }
  1074. public function serviceSubscribeApi($sProvider, $sDescriptor)
  1075. {
  1076. if(!$this->_bIsApi)
  1077. return;
  1078. $oPayment = BxDolPayments::getInstance();
  1079. $aDescriptor = $oPayment->getActiveObject()->_oConfig->descriptorS2A($sDescriptor);
  1080. if(!$aDescriptor || !is_array($aDescriptor))
  1081. return [bx_api_get_msg(_t('_sys_txt_error_occured'))];
  1082. $iSeller = (int)$aDescriptor[0];
  1083. $aResult = $oPayment->subscribeWithAddons($iSeller, $sProvider, $this->_oConfig->getName(), (int)$aDescriptor[2], 1, true);
  1084. if(($iCode = $aResult['code'] ?? false) && (int)$iCode != 0)
  1085. return [bx_api_get_msg($aResult['message'])];
  1086. return [];
  1087. }
  1088. protected function _serviceRegisterItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense, $sType)
  1089. {
  1090. $CNF = &$this->_oConfig->CNF;
  1091. $aItem = $this->serviceGetCartItem($iItemId);
  1092. if(empty($aItem) || !is_array($aItem))
  1093. return array();
  1094. $aProduct = $this->_oDb->getContentInfoById($iItemId);
  1095. if(empty($aProduct) || !is_array($aProduct))
  1096. return array();
  1097. if(!BxDolPrivacy::getObjectInstance($CNF['OBJECT_PRIVACY_PURCHASE'])->check((int)$iItemId, $iClientId))
  1098. return array();
  1099. $iTrial = 0;
  1100. $sDuration = '';
  1101. $sAction = 'register';
  1102. if($sType == BX_MARKET_LICENSE_TYPE_RECURRING) {
  1103. $iTrial = $aProduct[$this->_oConfig->CNF['FIELD_TRIAL_RECURRING']];
  1104. $sDuration = $aProduct[$this->_oConfig->CNF['FIELD_DURATION_RECURRING']];
  1105. if($this->_oDb->hasLicenseByOrder($iClientId, $iItemId, $sOrder))
  1106. $sAction = 'prolong';
  1107. }
  1108. if(!$this->_oDb->{$sAction . 'License'}($iClientId, $iItemId, $iItemCount, $sOrder, $sLicense, $sType, $sDuration, $iTrial))
  1109. return array();
  1110. bx_alert($this->getName(), 'license_' . $sAction, 0, false, array(
  1111. 'product_id' => $iItemId,
  1112. 'profile_id' => $iClientId,
  1113. 'order' => $sOrder,
  1114. 'license' => $sLicense,
  1115. 'type' => $sType,
  1116. 'count' => $iItemCount,
  1117. 'duration' => $sDuration,
  1118. 'trial' => $iTrial
  1119. ));
  1120. $oClient = BxDolProfile::getInstanceMagic($iClientId);
  1121. $oSeller = BxDolProfile::getInstanceMagic($iSellerId);
  1122. $sSellerUrl = $oSeller->getUrl();
  1123. $sSellerName = $oSeller->getDisplayName();
  1124. $sNote = $aProduct[$CNF['FIELD_NOTES_PURCHASED']];
  1125. if(empty($sNote))
  1126. $sNote = _t('_bx_market_txt_purchased_note', $sSellerUrl, $sSellerName);
  1127. sendMailTemplate($CNF['ETEMPLATE_PURCHASED'], 0, $iClientId, array(
  1128. 'client_name' => $oClient->getDisplayName(),
  1129. 'product_name' => $aProduct[$CNF['FIELD_TITLE']],
  1130. 'product_url' => bx_absolute_url(BxDolPermalinks::getInstance()->permalink('page.php?i=view-product&id=' . $aProduct[$CNF['FIELD_ID']])),
  1131. 'vendor_url' => $sSellerUrl,
  1132. 'vendor_name' => $sSellerName,
  1133. 'license' => $sLicense,
  1134. 'notes' => $sNote,
  1135. ));
  1136. return $aItem;
  1137. }
  1138. protected function _serviceReregisterItem($iClientId, $iSellerId, $iItemIdOld, $iItemIdNew, $sOrder, $sType)
  1139. {
  1140. $aItemNew = $this->serviceGetCartItem($iItemIdNew);
  1141. if(empty($aItemNew) || !is_array($aItemNew))
  1142. return array();
  1143. if(!$this->_oDb->hasLicenseByOrder($iClientId, $iItemIdOld, $sOrder))
  1144. return array();
  1145. if(!$this->_oDb->updateLicense(array('product_id' => $iItemIdNew), array('profile_id' => $iClientId, 'product_id' => $iItemIdOld, 'order' => $sOrder)))
  1146. return array();
  1147. bx_alert($this->getName(), 'license_reregister', 0, false, array(
  1148. 'product_id_old' => $iItemIdOld,
  1149. 'product_id_new' => $iItemIdNew,
  1150. 'profile_id' => $iClientId,
  1151. 'order' => $sOrder,
  1152. 'type' => $sType
  1153. ));
  1154. return $aItemNew;
  1155. }
  1156. protected function _serviceUnregisterItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense, $sType)
  1157. {
  1158. if(!$this->_oDb->unregisterLicense($iClientId, $iItemId, $sOrder, $sLicense, $sType))
  1159. return false;
  1160. bx_alert($this->getName(), 'license_unregister', 0, false, array(
  1161. 'product_id' => $iItemId,
  1162. 'profile_id' => $iClientId,
  1163. 'order' => $sOrder,
  1164. 'license' => $sLicense,
  1165. 'type' => $sType,
  1166. 'count' => $iItemCount
  1167. ));
  1168. return true;
  1169. }
  1170. public function getEntryImageData($aContentInfo, $sField = 'FIELD_THUMB', $aTranscoders = [])
  1171. {
  1172. $CNF = &$this->_oConfig->CNF;
  1173. if(getParam($CNF['PARAM_USE_ICON']) == 'on' && !empty($aContentInfo[$CNF[$sField]]))
  1174. return parent::getEntryImageData($aContentInfo, $sField, $aTranscoders);
  1175. return parent::getEntryImageData($aContentInfo, 'FIELD_COVER', $aTranscoders);
  1176. }
  1177. public function getGhostTemplateVars($aFile, $iProfileId, $iContentId, $oStorage, $oImagesTranscoder)
  1178. {
  1179. $CNF = &$this->_oConfig->CNF;
  1180. $sMethod = '';
  1181. $sStorage = $oStorage->getObject();
  1182. switch($sStorage) {
  1183. case $CNF['OBJECT_STORAGE']:
  1184. $sMethod = 'getPhoto';
  1185. break;
  1186. case $CNF['OBJECT_STORAGE_FILES']:
  1187. $sMethod = 'getFile';
  1188. break;
  1189. }
  1190. $aFileInfo = $this->_oDb->$sMethod(['type' => 'file_id', 'file_id' => $aFile['id']]);
  1191. $bFileInfo = !empty($aFileInfo) && is_array($aFileInfo);
  1192. $bFileInfoTitle = $bFileInfo && isset($aFileInfo['title']);
  1193. $aTmplVars = [
  1194. 'js_object' => $this->_oConfig->getJsObject('form'),
  1195. 'file_title' => $bFileInfoTitle ? $aFileInfo['title'] : '',
  1196. 'file_title_attr' => $bFileInfoTitle ? bx_html_attribute($aFileInfo['title']) : '',
  1197. ];
  1198. if($sStorage == $CNF['OBJECT_STORAGE'])
  1199. return $aTmplVars;
  1200. $bFileInfoVersion = $bFileInfo && isset($aFileInfo['version']);
  1201. $bFileInfoTypeVersion = !$bFileInfo || ($bFileInfo && isset($aFileInfo['type']) && $aFileInfo['type'] == BX_MARKET_FILE_TYPE_VERSION);
  1202. $bFileInfoTypeUpdate = $bFileInfo && isset($aFileInfo['type']) && $aFileInfo['type'] == BX_MARKET_FILE_TYPE_UPDATE;
  1203. $aVersions = $this->_oDb->$sMethod(array('type' => 'content_id', 'content_id' => $iContentId));
  1204. $aTmplVars = array_merge($aTmplVars, [
  1205. 'file_version' => $bFileInfoVersion ? $aFileInfo['version'] : '',
  1206. 'file_version_attr' => $bFileInfoVersion ? bx_html_attribute($aFileInfo['version']) : '',
  1207. 'file_type_version_selected' => $bFileInfoTypeVersion ? ' selected="selected"' : '',
  1208. 'file_type_update_selected' => $bFileInfoTypeUpdate ? ' selected="selected"' : '',
  1209. 'file_type_version_elements' => !$bFileInfoTypeVersion ? ' style="display:none;"' : '',
  1210. 'file_type_update_elements' => !$bFileInfoTypeUpdate ? ' style="display:none;"' : '',
  1211. 'file_version_from_options' => $this->_oTemplate->getGhostTemplateFileOptions('version', $aFileInfo, $aVersions),
  1212. 'file_version_to_options' => $this->_oTemplate->getGhostTemplateFileOptions('version_to', $aFileInfo, $aVersions)
  1213. ]);
  1214. return $aTmplVars;
  1215. }
  1216. public function checkAllowedDelete (&$aDataEntry, $isPerformAction = false)
  1217. {
  1218. $CNF = &$this->_oConfig->CNF;
  1219. if($aDataEntry[$CNF['FIELD_AUTHOR']] == $this->_iProfileId) {
  1220. $aLicenses = $this->_oDb->getLicense(array('type' => 'product_id', 'product_id' => $aDataEntry[$CNF['FIELD_ID']]));
  1221. if(is_array($aLicenses) && count($aLicenses) > 0)
  1222. return _t('_sys_txt_access_denied');
  1223. }
  1224. return parent::checkAllowedDelete($aDataEntry, $isPerformAction);
  1225. }
  1226. public function checkAllowedSetCover ()
  1227. {
  1228. $aCheck = checkActionModule($this->_iProfileId, 'set cover', $this->getName(), false);
  1229. if($aCheck[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED)
  1230. return $aCheck[CHECK_ACTION_MESSAGE];
  1231. return CHECK_ACTION_RESULT_ALLOWED;
  1232. }
  1233. public function checkAllowedSetSubentries ()
  1234. {
  1235. $aCheck = checkActionModule($this->_iProfileId, 'set subentries', $this->getName(), false);
  1236. if($aCheck[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED)
  1237. return $aCheck[CHECK_ACTION_MESSAGE];
  1238. return CHECK_ACTION_RESULT_ALLOWED;
  1239. }
  1240. public function checkAllowedDownload($aDataEntry, $isPerformAction = false)
  1241. {
  1242. $CNF = &$this->_oConfig->CNF;
  1243. // moderator and owner always have access
  1244. if ($aDataEntry[$CNF['FIELD_AUTHOR']] == $this->_iProfileId || $this->_isModerator($isPerformAction))
  1245. return CHECK_ACTION_RESULT_ALLOWED;
  1246. // check ACL
  1247. $aCheck = checkActionModule($this->_iProfileId, 'download entry', $this->getName(), $isPerformAction);
  1248. if($aCheck[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED)
  1249. return $aCheck[CHECK_ACTION_MESSAGE];
  1250. if((float)$aDataEntry[$CNF['FIELD_PRICE_SINGLE']] == 0 && (float)$aDataEntry[$CNF['FIELD_PRICE_RECURRING']] == 0)
  1251. return CHECK_ACTION_RESULT_ALLOWED;
  1252. if(!$this->_oDb->hasLicense($this->_iProfileId, $aDataEntry[$CNF['FIELD_ID']]))
  1253. return CHECK_ACTION_RESULT_NOT_ALLOWED;
  1254. return CHECK_ACTION_RESULT_ALLOWED;
  1255. }
  1256. public function checkAllowedHide($aDataEntry, $isPerformAction = false)
  1257. {
  1258. $CNF = &$this->_oConfig->CNF;
  1259. if($aDataEntry[$CNF['FIELD_STATUS']] != 'active')
  1260. return CHECK_ACTION_RESULT_NOT_ALLOWED;
  1261. // moderator and owner always have access
  1262. if ($aDataEntry[$CNF['FIELD_AUTHOR']] == $this->_iProfileId || $this->_isModerator($isPerformAction))
  1263. return CHECK_ACTION_RESULT_ALLOWED;
  1264. return CHECK_ACTION_RESULT_NOT_ALLOWED;
  1265. }
  1266. public function checkAllowedUnhide($aDataEntry, $isPerformAction = false)
  1267. {
  1268. $CNF = &$this->_oConfig->CNF;
  1269. if($aDataEntry[$CNF['FIELD_STATUS']] == 'active')
  1270. return CHECK_ACTION_RESULT_NOT_ALLOWED;
  1271. // moderator and owner always have access
  1272. if ($aDataEntry[$CNF['FIELD_AUTHOR']] == $this->_iProfileId || $this->_isModerator($isPerformAction))
  1273. return CHECK_ACTION_RESULT_ALLOWED;
  1274. return CHECK_ACTION_RESULT_NOT_ALLOWED;
  1275. }
  1276. public function checkAllowedViewMoreMenu (&$aDataEntry, $isPerformAction = false)
  1277. {
  1278. $CNF = &$this->_oConfig->CNF;
  1279. $oMenu = BxTemplMenu::getObjectInstance($CNF['OBJECT_MENU_ACTIONS_VIEW_ENTRY_MORE']);
  1280. $oMenu->setContentId($aDataEntry[$CNF['FIELD_ID']]);
  1281. if(!$oMenu || !$oMenu->isVisible())
  1282. return CHECK_ACTION_RESULT_NOT_ALLOWED;
  1283. return CHECK_ACTION_RESULT_ALLOWED;
  1284. }
  1285. protected function _getBlockLicenses($sType = '')
  1286. {
  1287. $CNF = &$this->_oConfig->CNF;
  1288. $sGrid = $this->_oConfig->getGridObject('licenses' . (!empty($sType) ? '_' . $sType : ''));
  1289. $oGrid = BxDolGrid::getObjectInstance($sGrid);
  1290. if(!$oGrid)
  1291. return $this->_bIsApi ? [] : '';
  1292. $this->_oDb->updateLicense(['new' => 0], ['profile_id' => bx_get_logged_profile_id(), 'new' => 1]);
  1293. if($this->_bIsApi)
  1294. return [
  1295. 'content' => [bx_api_get_block('grid', $oGrid->getCodeAPI())],
  1296. 'menu' => ($oMenu = BxTemplMenu::getObjectInstance($CNF['OBJECT_MENU_LICENSES'])) ? $oMenu->getCodeAPI() : ''
  1297. ];
  1298. $this->_oTemplate->addJs(['licenses.js']);
  1299. return [
  1300. 'content' => $this->_oTemplate->getJsCode('licenses', ['sObjNameGrid' => $sGrid]) . $oGrid->getCode(),
  1301. 'menu' => $CNF['OBJECT_MENU_LICENSES']
  1302. ];
  1303. }
  1304. protected function _getContentInfo($iContentId = 0)
  1305. {
  1306. if(!$iContentId)
  1307. $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
  1308. if(!$iContentId)
  1309. return false;
  1310. $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
  1311. if(!$aContentInfo)
  1312. return false;
  1313. return $aContentInfo;
  1314. }
  1315. protected function _performHideProduct($aDataEntry) {
  1316. $CNF = &$this->_oConfig->CNF;
  1317. if(!$this->_oDb->updateContentInfoBy(array($CNF['FIELD_STATUS'] => 'hidden'), array($CNF['FIELD_ID'] => $aDataEntry[$CNF['FIELD_ID']])))
  1318. return echoJson(array());
  1319. $this->checkAllowedHide($aDataEntry, true);
  1320. return echoJson(array('reload' => 1));
  1321. }
  1322. protected function _performUnhideProduct($aDataEntry) {
  1323. $CNF = &$this->_oConfig->CNF;
  1324. if(!$this->_oDb->updateContentInfoBy(array($CNF['FIELD_STATUS'] => 'active'), array($CNF['FIELD_ID'] => $aDataEntry[$CNF['FIELD_ID']])))
  1325. return echoJson(array());
  1326. $this->checkAllowedHide($aDataEntry, true);
  1327. return echoJson(array('reload' => 1));
  1328. }
  1329. protected function _getContentForTimelinePost($aEvent, $aContentInfo, $aBrowseParams = array())
  1330. {
  1331. $CNF = &$this->_oConfig->CNF;
  1332. $aResult = parent::_getContentForTimelinePost($aEvent, $aContentInfo, $aBrowseParams);
  1333. if($this->_bIsApi)
  1334. foreach(['PRICE_SINGLE', 'PRICE_RECURRING', 'DURATION_RECURRING', 'TRIAL_RECURRING'] as $sKey)
  1335. $aResult[$CNF['FIELD_' . $sKey]] = $aContentInfo[$CNF['FIELD_' . $sKey]];
  1336. return $aResult;
  1337. }
  1338. }
  1339. /** @} */