BxAdsModule.php 96 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508
  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 Ads Ads
  7. * @ingroup UnaModules
  8. *
  9. * @{
  10. */
  11. define('BX_ADS_STATUS_OFFER', 'offer');
  12. define('BX_ADS_STATUS_SOLD', 'sold');
  13. define('BX_ADS_STATUS_ADMIN_UNPAID', 'unpaid');
  14. define('BX_ADS_COMMODITY_TYPE_PRODUCT', 'product');
  15. define('BX_ADS_COMMODITY_TYPE_PROMOTION', 'promotion');
  16. define('BX_ADS_OFFER_STATUS_ACCEPTED', 'accepted');
  17. define('BX_ADS_OFFER_STATUS_AWAITING', 'awaiting');
  18. define('BX_ADS_OFFER_STATUS_DECLINED', 'declined');
  19. define('BX_ADS_OFFER_STATUS_CANCELED', 'canceled');
  20. define('BX_ADS_OFFER_STATUS_PAID', 'paid');
  21. /**
  22. * Ads module
  23. */
  24. class BxAdsModule extends BxBaseModTextModule
  25. {
  26. protected $_aOfferStatuses;
  27. function __construct(&$aModule)
  28. {
  29. parent::__construct($aModule);
  30. $this->_oConfig->init($this->_oDb);
  31. $CNF = &$this->_oConfig->CNF;
  32. $this->_aSearchableNamesExcept = array_merge($this->_aSearchableNamesExcept, array(
  33. $CNF['FIELD_CATEGORY_VIEW'],
  34. $CNF['FIELD_CATEGORY_SELECT']
  35. ));
  36. $this->_aOfferStatuses = array(
  37. BX_ADS_OFFER_STATUS_ACCEPTED,
  38. BX_ADS_OFFER_STATUS_AWAITING,
  39. BX_ADS_OFFER_STATUS_DECLINED
  40. );
  41. }
  42. public function decodeDataApi ($aData, $bExtended = false)
  43. {
  44. $CNF = $this->_oConfig->CNF;
  45. $aResult = parent::decodeDataApi($aData, $bExtended);
  46. $aResult[$CNF['FIELD_PRICE']] = $aData[$CNF['FIELD_PRICE']];
  47. $aResult[$CNF['FIELD_QUANTITY']] = $aData[$CNF['FIELD_QUANTITY']];
  48. $aResult[$CNF['FIELD_NOTES_PURCHASED']] = $aData[$CNF['FIELD_NOTES_PURCHASED']];
  49. return $aResult;
  50. }
  51. public function actionLoadEntryFromSource()
  52. {
  53. $sSourceType = bx_process_url_param(bx_process_input(bx_get('source_type')));
  54. $sSource = bx_process_url_param(bx_process_input(bx_get('source')));
  55. if(empty($sSourceType) || empty($sSource))
  56. return echoJson(['code' => 1]);
  57. $aEntry = $this->serviceLoadEntryFromSource($sSourceType, $sSource);
  58. if(empty($aEntry) || !is_array($aEntry))
  59. return echoJson(['code' => 2]);
  60. return echoJson([
  61. 'code' => 0,
  62. 'fields' => $aEntry
  63. ]);
  64. }
  65. public function actionGetCategoryForm()
  66. {
  67. if(($iCategory = bx_get('category')) === false || (int)$iCategory == 0)
  68. return echoJson(['msg' => _t('_bx_ads_form_entry_input_category_select_err')]);
  69. return echoJson([
  70. 'eval' => $this->_oConfig->getJsObject('form') . '.onSelectCategory(oData)',
  71. 'content' => $this->serviceGetCreatePostForm([
  72. 'absolute_action_url' => true,
  73. 'dynamic_mode' => true
  74. ])
  75. ]);
  76. }
  77. public function actionCheckName()
  78. {
  79. $CNF = &$this->_oConfig->CNF;
  80. $iId = (int)bx_get($CNF['FIELD_ID']);
  81. $sTitle = bx_process_input(bx_get($CNF['FIELD_TITLE']));
  82. echoJson($this->serviceCheckName($sTitle, $iId));
  83. }
  84. public function actionInterested()
  85. {
  86. $CNF = &$this->_oConfig->CNF;
  87. $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
  88. $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
  89. if(empty($aContentInfo) || !is_array($aContentInfo))
  90. return echoJson(array());
  91. $iViewer = bx_get_logged_profile_id();
  92. $oViewer = BxDolProfile::getInstance($iViewer);
  93. if(!$oViewer)
  94. return echoJson(array());
  95. $iContentAuthor = (int)$aContentInfo[$CNF['FIELD_AUTHOR']];
  96. if($iContentAuthor == $iViewer)
  97. return echoJson(array('msg' => _t('_bx_ads_txt_err_your_own')));
  98. if($this->_oDb->isInterested($iContentId, $iViewer))
  99. return echoJson(array('msg' => _t('_bx_ads_txt_err_duplicate')));
  100. $iInterestId = $this->_oDb->insertInterested(array('entry_id' => $iContentId, 'profile_id' => $iViewer));
  101. if(!$iInterestId)
  102. return echoJson(array('msg' => _t('_bx_ads_txt_err_cannot_perform_action')));
  103. bx_alert($this->getName(), 'doInterest', $iContentId, $iViewer, array(
  104. 'subobject_id' => $iInterestId,
  105. 'subobject_author_id' => $iViewer,
  106. 'object_author_id' => $iContentAuthor
  107. ));
  108. if(getParam($CNF['PARAM_USE_IIN']) == 'on')
  109. sendMailTemplate($CNF['ETEMPLATE_INTERESTED'], 0, $iContentAuthor, array(
  110. 'viewer_name' => $oViewer->getDisplayName(),
  111. 'viewer_url' => $oViewer->getUrl(),
  112. 'ad_name' => $aContentInfo[$CNF['FIELD_TITLE']],
  113. 'ad_url' => bx_absolute_url(BxDolPermalinks::getInstance()->permalink('page.php', array(
  114. 'i' => $CNF['URI_VIEW_ENTRY'],
  115. $CNF['FIELD_ID'] => $iContentId
  116. )))
  117. ));
  118. return echoJson(array('msg' => _t('_bx_ads_txt_msg_author_notified')));
  119. }
  120. public function actionShow()
  121. {
  122. return echoJson($this->_actionChangeStatus(BX_BASE_MOD_TEXT_STATUS_ACTIVE));
  123. }
  124. public function actionHide()
  125. {
  126. return echoJson($this->_actionChangeStatus(BX_BASE_MOD_TEXT_STATUS_HIDDEN));
  127. }
  128. public function actionMakeOffer()
  129. {
  130. $CNF = &$this->_oConfig->CNF;
  131. $sJsObject = $this->_oConfig->getJsObject('entry');
  132. $iAuthorId = bx_get_logged_profile_id();
  133. $iContentId = bx_process_input(bx_get('content_id'), BX_DATA_INT);
  134. if(empty($iAuthorId))
  135. return echoJson(['code' => 1, 'eval' => 'window.open("' . BxDolPermalinks::getInstance()->permalink('page.php?i=login') . '", "_self");']);
  136. $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
  137. if(empty($aContentInfo) || !is_array($aContentInfo))
  138. return echoJson([]);
  139. if(($mixedCheck = $this->checkAllowedMakeOffer($aContentInfo)) !== CHECK_ACTION_RESULT_ALLOWED)
  140. return echoJson(['code' => 2, 'msg' => $mixedCheck]);
  141. $aOffer = $this->_oDb->getOffersBy([
  142. 'type' => 'content_and_author_ids',
  143. 'content_id' => $iContentId,
  144. 'author_id' => $iAuthorId,
  145. 'status' => BX_ADS_OFFER_STATUS_AWAITING
  146. ]);
  147. if(!empty($aOffer) && is_array($aOffer))
  148. return echoJson(['code' => 3, 'msg' => _t('_bx_ads_txt_err_duplicate')]);
  149. $aOffer = $this->_oDb->getOffersBy([
  150. 'type' => 'content_and_author_ids',
  151. 'content_id' => $iContentId,
  152. 'author_id' => $iAuthorId,
  153. 'status' => BX_ADS_OFFER_STATUS_ACCEPTED
  154. ]);
  155. if(!empty($aOffer) && is_array($aOffer))
  156. return echoJson(['code' => 4, 'msg' => _t('_bx_ads_txt_err_offer_accepted')]);
  157. $oForm = BxDolForm::getObjectInstance($CNF['OBJECT_FORM_OFFER'], $CNF['OBJECT_FORM_OFFER_DISPLAY_ADD']);
  158. $oForm->aFormAttrs['action'] = BX_DOL_URL_ROOT . bx_append_url_params($this->_oConfig->getBaseUri() . 'make_offer', ['content_id' => $iContentId]);
  159. $oForm->initChecker();
  160. if($oForm->isSubmittedAndValid()) {
  161. $iQuantity = (int)$oForm->getCleanValue($CNF['FIELD_OFR_QUANTITY']);
  162. $iQuantityAvailable = $this->getAvailableQuantity($aContentInfo);
  163. if($iQuantity > $iQuantityAvailable)
  164. return echoJson(['code' => 5, 'msg' => _t('_bx_ads_txt_err_offer_wrong_quantity', $iQuantityAvailable)]);
  165. $aValToAdd = ['content_id' => $iContentId, 'author_id' => $iAuthorId];
  166. if(($iId = (int)$oForm->insert($aValToAdd)) != 0) {
  167. $this->checkAllowedMakeOffer($aContentInfo, true);
  168. $this->onOfferAdded($iId, $aResult);
  169. $aResult = ['code' => 0, 'msg' => _t('_bx_ads_txt_msg_offer_added'), 'eval' => $sJsObject . '.onMakeOffer(oData);', 'id' => $iId];
  170. }
  171. else
  172. $aResult = ['code' => 6, 'msg' => _t('_bx_ads_txt_err_cannot_perform_action')];
  173. return echoJson($aResult);
  174. }
  175. $sContent = BxTemplFunctions::getInstance()->transBox($this->_oConfig->getHtmlIds('offer_popup'), $this->_oTemplate->parseHtmlByName('offer_popup.html', array(
  176. 'form_id' => $oForm->getId(),
  177. 'form' => $oForm->getCode(true)
  178. )));
  179. return echoJson(array('popup' => array('html' => $sContent, 'options' => array('closeOnOuterClick' => false, 'removeOnClose' => true))));
  180. }
  181. public function actionViewOffer()
  182. {
  183. $CNF = &$this->_oConfig->CNF;
  184. $iAuthorId = bx_get_logged_profile_id();
  185. $iOfferId = bx_process_input(bx_get('id'), BX_DATA_INT);
  186. $aOffer = $this->_oDb->getOffersBy(array('type' => 'id', 'id' => $iOfferId));
  187. if(empty($aOffer) || !is_array($aOffer))
  188. return echoJson(array());
  189. $oForm = BxDolForm::getObjectInstance($CNF['OBJECT_FORM_OFFER'], $CNF['OBJECT_FORM_OFFER_DISPLAY_VIEW']);
  190. $oForm->initChecker($aOffer);
  191. $sContent = BxTemplFunctions::getInstance()->transBox($this->_oConfig->getHtmlIds('offer_popup'), $this->_oTemplate->parseHtmlByName('offer_popup.html', array(
  192. 'form_id' => $oForm->getId(),
  193. 'form' => $oForm->getCode(true)
  194. )));
  195. return echoJson(array('popup' => array('html' => $sContent, 'options' => array('closeOnOuterClick' => true, 'removeOnClose' => true))));
  196. }
  197. public function actionAcceptOffer()
  198. {
  199. $iId = bx_process_input(bx_get('id'), BX_DATA_INT);
  200. if(($mixedResult = $this->offerAccept($iId)) !== true)
  201. return echoJson(['msg' => $mixedResult !== false ? $mixedResult : _t('_bx_ads_txt_err_cannot_perform_action')]);
  202. return echoJson(['msg' => _t('_bx_ads_txt_msg_offer_accepted'), 'reload' => 1]);
  203. }
  204. public function actionDeclineOffer()
  205. {
  206. $iId = bx_process_input(bx_get('id'), BX_DATA_INT);
  207. if(!$this->offerDecline($iId))
  208. return echoJson(array('msg' => _t('_bx_ads_txt_err_cannot_perform_action')));
  209. return echoJson(array('msg' => _t('_bx_ads_txt_msg_offer_declined'), 'reload' => 1));
  210. }
  211. public function actionCancelOffer()
  212. {
  213. $iId = bx_process_input(bx_get('id'), BX_DATA_INT);
  214. if(!$this->offerCancel($iId))
  215. return echoJson(['msg' => _t('_bx_ads_txt_err_cannot_perform_action')]);
  216. return echoJson(['msg' => _t('_bx_ads_txt_msg_offer_canceled'), 'reload' => 1]);
  217. }
  218. public function actionPayOffer()
  219. {
  220. $iId = bx_process_input(bx_get('id'), BX_DATA_INT);
  221. if(($mixedResult = $this->offerPay($iId)) !== false)
  222. return echoJson($mixedResult);
  223. return echoJson(array('msg' => _t('_bx_ads_txt_err_cannot_perform_action')));
  224. }
  225. public function actionShipped()
  226. {
  227. return echoJson($this->_actionMarkAs('shipped'));
  228. }
  229. public function actionReceived()
  230. {
  231. return echoJson($this->_actionMarkAs('received'));
  232. }
  233. public function actionRegisterImpression($iId)
  234. {
  235. echoJson($this->serviceRegisterImpression($iId));
  236. }
  237. public function actionRegisterClick($iId)
  238. {
  239. echoJson($this->serviceRegisterClick($iId));
  240. }
  241. public function serviceGetSafeServices()
  242. {
  243. return array_merge(parent::serviceGetSafeServices(), [
  244. 'IsSourcesAvaliable' => '',
  245. 'LoadEntryFromSource' => '',
  246. 'EntityReviews' => '',
  247. 'EntityReviewsRating' => '',
  248. 'CategoriesList' => '',
  249. 'BrowseCategory' => '',
  250. 'RegisterImpression' => '',
  251. 'RegisterClick' => '',
  252. 'BlockSourcesDetails' => ''
  253. ]);
  254. }
  255. public function serviceRegisterImpression($iId)
  256. {
  257. return ['code' => $this->_oDb->updatePromotionTracker($iId, 'impressions') ? 0 : 1];
  258. }
  259. public function serviceRegisterClick($iId)
  260. {
  261. $CNF = &$this->_oConfig->CNF;
  262. if(!$this->_oDb->updatePromotionTracker($iId, 'clicks'))
  263. return ['code' => 1];
  264. $sUrl = '';
  265. if($this->_oConfig->isSources()) {
  266. $aEntry = $this->_oDb->getContentInfoById($iId);
  267. if(!empty($aEntry) && is_array($aEntry) && !empty($aEntry[$CNF['FIELD_URL']]))
  268. $sUrl = $aEntry[$CNF['FIELD_URL']];
  269. }
  270. return [
  271. 'code' => 0,
  272. 'redirect' => !empty($sUrl) ? $sUrl : $this->_oConfig->getViewEntryUrl($iId)
  273. ];
  274. }
  275. public function serviceCheckName($sTitle, $iId = 0)
  276. {
  277. $CNF = &$this->_oConfig->CNF;
  278. if(empty($sTitle))
  279. return array();
  280. $sName = '';
  281. if(!empty($iId)) {
  282. $aEntry = $this->_oDb->getContentInfoById($iId);
  283. if(strcmp($sTitle, $aEntry[$CNF['FIELD_NAME']]) == 0)
  284. $sName = $sTitle;
  285. }
  286. return array(
  287. 'title' => $sTitle,
  288. 'name' => !empty($sName) ? $sName : $this->_oConfig->getEntryName($sTitle, $iId)
  289. );
  290. }
  291. public function serviceUpdateCategoriesStats($mixedContentInfo = false)
  292. {
  293. $aContentInfo = [];
  294. if(!empty($mixedContentInfo))
  295. $aContentInfo = !is_array($mixedContentInfo) ? $this->_oDb->getContentInfoById((int)$mixedContentInfo) : $mixedContentInfo;
  296. $iCategoryId = 0;
  297. if($aContentInfo && !empty($aContentInfo['category']))
  298. $iCategoryId = (int)$aContentInfo['category'];
  299. return $this->serviceUpdateCategoriesStatsByCategory($iCategoryId);
  300. }
  301. public function serviceUpdateCategoriesStatsByCategory($iCategoryId = 0)
  302. {
  303. $aParams = ['type' => 'collect_stats'];
  304. if($iCategoryId)
  305. $aParams['category_id'] = (int)$iCategoryId;
  306. $aStats = $this->_oDb->getCategories($aParams);
  307. if(empty($aStats) || !is_array($aStats))
  308. return true;
  309. $iUpdated = 0;
  310. foreach($aStats as $aStat)
  311. if($this->_oDb->updateCategory(array('items' => $aStat['count']), array('id' => $aStat['id'])))
  312. $iUpdated++;
  313. return count($aStats) == $iUpdated;
  314. }
  315. public function serviceGetCategoryOptions($iParentId, $bPleaseSelect = false)
  316. {
  317. $aValues = array();
  318. if($bPleaseSelect)
  319. $aValues[] = array('key' => '', 'value' => _t('_sys_please_select'));
  320. $this->_getCategoryOptions($iParentId, $aValues);
  321. return $aValues;
  322. }
  323. public function serviceGetSearchableFields($aInputsAdd = array())
  324. {
  325. $CNF = &$this->_oConfig->CNF;
  326. $aResult = parent::serviceGetSearchableFields(array_merge($aInputsAdd, $this->_getSearchableFields()));
  327. unset($aResult[$CNF['FIELD_NOTES_PURCHASED']]);
  328. unset($aResult[$CNF['FIELD_CATEGORY_VIEW']], $aResult[$CNF['FIELD_CATEGORY_SELECT']]);
  329. unset($aResult[$CNF['FIELD_PRICE']], $aResult[$CNF['FIELD_YEAR']]);
  330. return $aResult;
  331. }
  332. public function serviceGetSearchableFieldsExtended($aInputsAdd = array())
  333. {
  334. $CNF = &$this->_oConfig->CNF;
  335. $aInputsAdd = array_merge($aInputsAdd, $this->_getSearchableFields());
  336. if(isset($aInputsAdd[$CNF['FIELD_CATEGORY']])) {
  337. $aInputsAdd[$CNF['FIELD_CATEGORY']]['type'] = 'select';
  338. $aInputsAdd[$CNF['FIELD_CATEGORY']]['values_src'] = BxDolService::getSerializedService($this->_oConfig->getName(), 'get_category_options', array(0));
  339. }
  340. if(isset($aInputsAdd[$CNF['FIELD_PRICE']])) {
  341. $aInputsAdd[$CNF['FIELD_PRICE']]['search_type'] = 'text_range';
  342. $aInputsAdd[$CNF['FIELD_PRICE']]['search_operator'] = 'between';
  343. }
  344. if(isset($aInputsAdd[$CNF['FIELD_YEAR']])) {
  345. $aInputsAdd[$CNF['FIELD_YEAR']]['search_type'] = 'text_range';
  346. $aInputsAdd[$CNF['FIELD_YEAR']]['search_operator'] = 'between';
  347. }
  348. return parent::serviceGetSearchableFieldsExtended($aInputsAdd);
  349. }
  350. /**
  351. * Mark an ad as shipped/received by seller/bauer accordingly.
  352. * @param type $sAction - shipped/received action.
  353. * @param type $iContentId - an ad the action will be performed with.
  354. * @param integer $iProfileSrc - profile, who performed the action.
  355. * @param integer $iProfileDst - profile, the action is pointed on.
  356. * @return boolean - true or a string value with error message.
  357. */
  358. public function serviceMarkAs($sAction, $iContentId, $iProfileSrc = 0, $iProfileDst = 0)
  359. {
  360. $CNF = &$this->_oConfig->CNF;
  361. if(!$iProfileSrc)
  362. $iProfileSrc = bx_get_logged_profile_id();
  363. $sTxtError = '_bx_ads_txt_err_cannot_perform_action';
  364. $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
  365. $sMethodCheck = 'checkAllowedMark' . bx_gen_method_name($sAction) . 'ForProfile';
  366. if(!method_exists($this, $sMethodCheck))
  367. return _t($sTxtError);
  368. if(($mixedCheckResult = $this->$sMethodCheck($aContentInfo, false, $iProfileSrc)) !== CHECK_ACTION_RESULT_ALLOWED)
  369. return $mixedCheckResult;
  370. if((int)$this->_oDb->updateEntriesBy(array($CNF['FIELD_' . strtoupper($sAction)] => time()), array($CNF['FIELD_ID'] => $iContentId)) == 0)
  371. return _t($sTxtError);
  372. $this->$sMethodCheck($aContentInfo, true, $iProfileSrc);
  373. $sMethodOnResult = 'on' . bx_gen_method_name($sAction);
  374. if(method_exists($this, $sMethodOnResult))
  375. $this->$sMethodOnResult($aContentInfo, $iProfileSrc, $iProfileDst);
  376. return true;
  377. }
  378. public function serviceEntityCreate ($sParams = false)
  379. {
  380. $iCategory = is_numeric($sParams) ? (int)$sParams : 0;
  381. if(($sDisplay = $this->getCategoryDisplay('add', $iCategory)) !== false) {
  382. if(empty($sParams) || !is_array($sParams))
  383. $sParams = array();
  384. $sParams['display'] = $sDisplay;
  385. }
  386. if($iCategory)
  387. BxDolSession::getInstance()->setValue($sDisplay . '_category', $iCategory);
  388. return parent::serviceEntityCreate($sParams);
  389. }
  390. public function serviceEntityEditBudget ($iContentId = 0, $sDisplay = false)
  391. {
  392. $CNF = &$this->_oConfig->CNF;
  393. return parent::serviceEntityEdit($iContentId, $CNF['OBJECT_FORM_ENTRY_DISPLAY_EDIT_BUDGET']);
  394. }
  395. /**
  396. * @page service Service Calls
  397. * @section bx_ads Ads
  398. * @subsection bx_ads-page_blocks Page Blocks
  399. * @subsubsection bx_ads-entity_reviews entity_reviews
  400. *
  401. * @code bx_srv('bx_ads', 'entity_reviews', [...]); @endcode
  402. *
  403. * Get reviews for particular content
  404. * @param $iContentId content ID
  405. *
  406. * @see BxAdsModule::serviceEntityReviews
  407. */
  408. /**
  409. * @ref bx_ads-entity_reviews "entity_reviews"
  410. */
  411. public function serviceEntityReviews($iContentId = 0)
  412. {
  413. $CNF = &$this->_oConfig->CNF;
  414. if(empty($CNF['OBJECT_REVIEWS']))
  415. return false;
  416. return $this->_entityComments($CNF['OBJECT_REVIEWS'], $iContentId);
  417. }
  418. /**
  419. * @page service Service Calls
  420. * @section bx_ads Ads
  421. * @subsection bx_ads-page_blocks Page Blocks
  422. * @subsubsection bx_ads-entity_reviews_rating entity_reviews_rating
  423. *
  424. * @code bx_srv('bx_ads', 'entity_reviews_rating', [...]); @endcode
  425. *
  426. * Get reviews rating for particular content
  427. * @param $iContentId content ID
  428. *
  429. * @see BxAdsModule::serviceEntityReviewsRating
  430. */
  431. /**
  432. * @ref bx_ads-entity_reviews_rating "entity_reviews_rating"
  433. */
  434. public function serviceEntityReviewsRating($iContentId = 0)
  435. {
  436. $CNF = &$this->_oConfig->CNF;
  437. if(empty($CNF['OBJECT_REVIEWS']))
  438. return false;
  439. if(!$iContentId)
  440. $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
  441. if(!$iContentId)
  442. return false;
  443. $oCmts = BxDolCmts::getObjectInstance($CNF['OBJECT_REVIEWS'], $iContentId);
  444. if (!$oCmts || !$oCmts->isEnabled())
  445. return false;
  446. return $oCmts->getRatingBlock(array('in_designbox' => false));
  447. }
  448. public function serviceEntityPromotionGrowth($iContentId = 0)
  449. {
  450. return $this->_serviceTemplateFunc('entryPromotionGrowth', $iContentId);
  451. }
  452. public function serviceEntityPromotionSummary($iContentId = 0)
  453. {
  454. return $this->_serviceTemplateFunc('entryPromotionSummary', $iContentId);
  455. }
  456. public function serviceEntityPromotionRoi($iContentId = 0)
  457. {
  458. return $this->_serviceTemplateFunc('entryPromotionRoi', $iContentId);
  459. }
  460. /**
  461. * @page service Service Calls
  462. * @section bx_ads Ads
  463. * @subsection bx_ads-page_blocks Page Blocks
  464. * @subsubsection bx_ads-categories_list categories_list
  465. *
  466. * @code bx_srv('bx_ads', 'categories_list', [...]); @endcode
  467. *
  468. * Get reviews rating for particular content
  469. * @param $aParams additional params array, such as 'show_empty'
  470. *
  471. * @see BxAdsModule::serviceCategoriesList
  472. */
  473. /**
  474. * @ref bx_ads-categories_list "categories_list"
  475. */
  476. public function serviceCategoriesList($aParams = array())
  477. {
  478. if(!isset($aParams['show_empty']))
  479. $aParams['show_empty'] = true;
  480. return $this->_oTemplate->categoriesList($aParams);
  481. }
  482. /**
  483. * @page service Service Calls
  484. * @section bx_ads Ads
  485. * @subsection bx_ads-browse Browse
  486. * @subsubsection bx_ads-browse_category browse_category
  487. *
  488. * @code bx_srv('bx_ads', 'browse_category', [...]); @endcode
  489. *
  490. * Get reviews rating for particular content
  491. * @param $iCategoryId category ID
  492. * @param $aParams additional params array, such as empty_message, ajax_paginate, etc
  493. *
  494. * @see BxAdsModule::serviceBrowseCategory
  495. */
  496. /**
  497. * @ref bx_ads-browse_category "browse_category"
  498. */
  499. public function serviceBrowseCategory($sUnitView = false, $bEmptyMessage = true, $bAjaxPaginate = true, $aParams = [])
  500. {
  501. $mixedResult = parent::serviceBrowseCategory($sUnitView, $bEmptyMessage, $bAjaxPaginate, $aParams);
  502. if(empty($mixedResult['content']))
  503. return $mixedResult;
  504. $aCategory = $this->_oDb->getCategories([
  505. 'type' => 'id',
  506. 'id' => !empty($aParams['category']) ? (int)$aParams['category'] : bx_process_input(bx_get('category'), BX_DATA_INT)
  507. ]);
  508. if(!empty($aCategory['title']))
  509. $mixedResult['title'] = _t('_bx_ads_page_block_title_entries_by_category_mask', _t($aCategory['title']));
  510. return $mixedResult;
  511. }
  512. public function serviceGetTimelinePost($aEvent, $aBrowseParams = [])
  513. {
  514. $CNF = &$this->_oConfig->CNF;
  515. $mixedResult = parent::serviceGetTimelinePost($aEvent, $aBrowseParams);
  516. if(!$mixedResult)
  517. return $mixedResult;
  518. $aContentInfo = $this->_oDb->getContentInfoById($aEvent['object_id']);
  519. if($this->_oConfig->isSources() && !empty($aContentInfo[$CNF['FIELD_URL']]))
  520. $mixedResult['url'] = $aContentInfo[$CNF['FIELD_URL']];
  521. return $mixedResult;
  522. }
  523. public function serviceGetNotificationsData()
  524. {
  525. $sModule = $this->_aModule['name'];
  526. $sEventPrivacy = $sModule . '_allow_view_event_to';
  527. if(BxDolPrivacy::getObjectInstance($sEventPrivacy) === false)
  528. $sEventPrivacy = '';
  529. $aResult = parent::serviceGetNotificationsData();
  530. $aResult['handlers'] = array_merge($aResult['handlers'], array(
  531. array('group' => $sModule . '_interest', 'type' => 'insert', 'alert_unit' => $sModule, 'alert_action' => 'doInterest', 'module_name' => $sModule, 'module_method' => 'get_notifications_interest', 'module_class' => 'Module', 'module_event_privacy' => $sEventPrivacy),
  532. array('group' => $sModule . '_paid', 'type' => 'insert', 'alert_unit' => $sModule, 'alert_action' => 'license_register', 'module_name' => $sModule, 'module_method' => 'get_notifications_license_register', 'module_class' => 'Module', 'module_event_privacy' => $sEventPrivacy),
  533. //---> To Buyer
  534. array('group' => $sModule . '_shipped', 'type' => 'insert', 'alert_unit' => $sModule, 'alert_action' => 'shipped', 'module_name' => $sModule, 'module_method' => 'get_notifications_shipped', 'module_class' => 'Module', 'module_event_privacy' => $sEventPrivacy),
  535. //<---
  536. array('group' => $sModule . '_received', 'type' => 'insert', 'alert_unit' => $sModule, 'alert_action' => 'received', 'module_name' => $sModule, 'module_method' => 'get_notifications_received', 'module_class' => 'Module', 'module_event_privacy' => $sEventPrivacy),
  537. array('group' => $sModule . '_offer_added', 'type' => 'insert', 'alert_unit' => $sModule, 'alert_action' => 'offer_added', 'module_name' => $sModule, 'module_method' => 'get_notifications_offer_added', 'module_class' => 'Module', 'module_event_privacy' => $sEventPrivacy),
  538. //---> To Offerer
  539. array('group' => $sModule . '_offer_accepted', 'type' => 'insert', 'alert_unit' => $sModule, 'alert_action' => 'offer_accepted', 'module_name' => $sModule, 'module_method' => 'get_notifications_offer_accepted', 'module_class' => 'Module', 'module_event_privacy' => $sEventPrivacy),
  540. array('group' => $sModule . '_offer_declined', 'type' => 'insert', 'alert_unit' => $sModule, 'alert_action' => 'offer_declined', 'module_name' => $sModule, 'module_method' => 'get_notifications_offer_declined', 'module_class' => 'Module', 'module_event_privacy' => $sEventPrivacy),
  541. //<---
  542. array('group' => $sModule . '_offer_canceled', 'type' => 'insert', 'alert_unit' => $sModule, 'alert_action' => 'offer_canceled', 'module_name' => $sModule, 'module_method' => 'get_notifications_offer_canceled', 'module_class' => 'Module', 'module_event_privacy' => $sEventPrivacy)
  543. ));
  544. $aResult['settings'] = array_merge($aResult['settings'], array(
  545. array('group' => 'interest', 'unit' => $sModule, 'action' => 'doInterest', 'types' => array('personal')),
  546. array('group' => 'usage', 'unit' => $sModule, 'action' => 'license_register', 'types' => array('personal')),
  547. array('group' => 'usage', 'unit' => $sModule, 'action' => 'shipped', 'types' => array('personal')),
  548. array('group' => 'usage', 'unit' => $sModule, 'action' => 'received', 'types' => array('personal')),
  549. array('group' => 'usage', 'unit' => $sModule, 'action' => 'offer_added', 'types' => array('personal')),
  550. array('group' => 'usage', 'unit' => $sModule, 'action' => 'offer_accepted', 'types' => array('personal')),
  551. array('group' => 'usage', 'unit' => $sModule, 'action' => 'offer_declined', 'types' => array('personal')),
  552. array('group' => 'usage', 'unit' => $sModule, 'action' => 'offer_canceled', 'types' => array('personal')),
  553. ));
  554. $aResult['alerts'] = array_merge($aResult['alerts'], array(
  555. array('unit' => $sModule, 'action' => 'doInterest'),
  556. array('unit' => $sModule, 'action' => 'license_register'),
  557. array('unit' => $sModule, 'action' => 'shipped'),
  558. array('unit' => $sModule, 'action' => 'received'),
  559. array('unit' => $sModule, 'action' => 'offer_added'),
  560. array('unit' => $sModule, 'action' => 'offer_accepted'),
  561. array('unit' => $sModule, 'action' => 'offer_declined'),
  562. array('unit' => $sModule, 'action' => 'offer_canceled'),
  563. ));
  564. return $aResult;
  565. }
  566. public function serviceGetNotificationsInsertData($oAlert, $aHandler, $aDataItems)
  567. {
  568. $CNF = &$this->_oConfig->CNF;
  569. $aResult = [];
  570. switch($oAlert->sAction) {
  571. case 'license_register':
  572. $aContentInfo = $this->_oDb->getContentInfoById($oAlert->aExtras['product_id']);
  573. if(empty($aContentInfo) || !is_array($aContentInfo)) {
  574. $aResult = $aDataItems;
  575. break;
  576. }
  577. foreach($aDataItems as $aDataItem) {
  578. $aDataItem = array_merge($aDataItem, [
  579. 'owner_id' => $oAlert->aExtras['profile_id'],
  580. 'object_id' => $aContentInfo[$CNF['FIELD_ID']],
  581. 'object_owner_id' => $aContentInfo[$CNF['FIELD_AUTHOR']],
  582. 'object_privacy_view' => BX_DOL_PG_ALL
  583. ]);
  584. $aResult[] = $aDataItem;
  585. }
  586. break;
  587. case 'shipped':
  588. foreach($aDataItems as $aDataItem) {
  589. $aLicense = $this->_oDb->getLicense(['type' => 'entry_id', 'entry_id' => $aDataItem['object_id'], 'newest' => true]);
  590. if(!empty($aLicense) && is_array($aLicense))
  591. $aDataItem['object_owner_id'] = $aLicense['profile_id'];
  592. $aResult[] = $aDataItem;
  593. }
  594. break;
  595. case 'offer_added':
  596. case 'offer_canceled':
  597. foreach($aDataItems as $aDataItem) {
  598. $aDataItem['object_owner_id'] = $oAlert->aExtras['object_author_id'];
  599. $aResult[] = $aDataItem;
  600. }
  601. break;
  602. case 'offer_accepted':
  603. case 'offer_declined':
  604. foreach($aDataItems as $aDataItem) {
  605. $aDataItem['object_owner_id'] = $oAlert->aExtras['offer_author_id'];
  606. $aResult[] = $aDataItem;
  607. }
  608. break;
  609. default:
  610. $aResult = $aDataItems;
  611. }
  612. return $aResult;
  613. }
  614. public function serviceGetNotificationsInterest($aEvent)
  615. {
  616. $CNF = &$this->_oConfig->CNF;
  617. $iContentId = (int)$aEvent['object_id'];
  618. $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
  619. if(empty($aContentInfo) || !is_array($aContentInfo))
  620. return [];
  621. $iInterestedId = (int)$aEvent['subobject_id'];
  622. $aInterestedInfo = $this->_oDb->getInterested(['type' => 'id', 'id' => $iInterestedId]);
  623. if(empty($aInterestedInfo) || !is_array($aInterestedInfo))
  624. return [];
  625. if(($oInterestedProfile = BxDolProfile::getInstance($aInterestedInfo['profile_id'])) !== false)
  626. $sEntryUrl = $oInterestedProfile->getUrl();
  627. else
  628. $sEntryUrl = bx_absolute_url(BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $iContentId), '{bx_url_root}');
  629. return [
  630. 'entry_sample' => $CNF['T']['txt_sample_single'],
  631. 'entry_url' => $sEntryUrl,
  632. 'entry_caption' => $aContentInfo[$CNF['FIELD_TITLE']],
  633. 'entry_author' => $aContentInfo[$CNF['FIELD_AUTHOR']],
  634. 'subentry_sample' => $CNF['T']['txt_sample_interest_single'],
  635. 'subentry_url' => '',
  636. 'lang_key' => '_bx_ads_txt_ntfs_subobject_interested', //may be empty or not specified. In this case the default one from Notification module will be used.
  637. ];
  638. }
  639. public function serviceGetNotificationsLicenseRegister($aEvent)
  640. {
  641. return $this->_serviceGetNotificationsByEntryAndAction($aEvent, 'license_register');
  642. }
  643. public function serviceGetNotificationsShipped($aEvent)
  644. {
  645. $aResult = $this->_serviceGetNotificationsByEntryAndAction($aEvent, 'shipped');
  646. $aResult['entry_author'] = $aEvent['object_owner_id'];
  647. return $aResult;
  648. }
  649. public function serviceGetNotificationsReceived($aEvent)
  650. {
  651. return $this->_serviceGetNotificationsByEntryAndAction($aEvent, 'received');
  652. }
  653. public function serviceGetNotificationsOfferAdded($aEvent)
  654. {
  655. return $this->_serviceGetNotificationsByOfferAndAction($aEvent, 'offer_added');
  656. }
  657. public function serviceGetNotificationsOfferAccepted($aEvent)
  658. {
  659. $aResult = $this->_serviceGetNotificationsByOfferAndAction($aEvent, 'offer_accepted');
  660. $aResult['entry_author'] = $aEvent['object_owner_id'];
  661. return $aResult;
  662. }
  663. public function serviceGetNotificationsOfferDeclined($aEvent)
  664. {
  665. $aResult = $this->_serviceGetNotificationsByOfferAndAction($aEvent, 'offer_declined');
  666. $aResult['entry_author'] = $aEvent['object_owner_id'];
  667. return $aResult;
  668. }
  669. public function serviceGetNotificationsOfferCanceled($aEvent)
  670. {
  671. return $this->_serviceGetNotificationsByOfferAndAction($aEvent, 'offer_canceled');
  672. }
  673. protected function _serviceGetNotificationsByEntryAndAction($aEvent, $sAction)
  674. {
  675. $CNF = &$this->_oConfig->CNF;
  676. $iContentId = (int)$aEvent['object_id'];
  677. $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
  678. if(empty($aContentInfo) || !is_array($aContentInfo))
  679. return array();
  680. $sEntryUrl = bx_absolute_url(BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $iContentId), '{bx_url_root}');
  681. return array(
  682. 'entry_sample' => $CNF['T']['txt_sample_single'],
  683. 'entry_url' => $sEntryUrl,
  684. 'entry_caption' => $aContentInfo[$CNF['FIELD_TITLE']],
  685. 'entry_author' => $aContentInfo[$CNF['FIELD_AUTHOR']],
  686. 'subentry_sample' => '',
  687. 'subentry_url' => '',
  688. 'lang_key' => '_bx_ads_txt_ntfs_object_' . $sAction, //may be empty or not specified. In this case the default one from Notification module will be used.
  689. );
  690. }
  691. protected function _serviceGetNotificationsByOfferAndAction($aEvent, $sAction)
  692. {
  693. $CNF = &$this->_oConfig->CNF;
  694. $iOfferId = (int)$aEvent['object_id'];
  695. $aOfferInfo = $this->_oDb->getOffersBy(['type' => 'id', 'id' => $iOfferId]);
  696. if(empty($aOfferInfo) || !is_array($aOfferInfo))
  697. return array();
  698. $iContentId = $aOfferInfo[$CNF['FIELD_OFR_CONTENT']];
  699. $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
  700. if(empty($aContentInfo) || !is_array($aContentInfo))
  701. return array();
  702. $sEntryUrl = bx_absolute_url(BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $iContentId), '{bx_url_root}');
  703. return array(
  704. 'object_id' => $iContentId,
  705. 'entry_sample' => $CNF['T']['txt_sample_single'],
  706. 'entry_url' => $sEntryUrl,
  707. 'entry_caption' => $aContentInfo[$CNF['FIELD_TITLE']],
  708. 'entry_author' => $aContentInfo[$CNF['FIELD_AUTHOR']],
  709. 'subentry_sample' => '',
  710. 'subentry_url' => '',
  711. 'lang_key' => '_bx_ads_txt_ntfs_' . $sAction, //may be empty or not specified. In this case the default one from Notification module will be used.
  712. );
  713. }
  714. /**
  715. * @page service Service Calls
  716. * @section bx_ads Ads
  717. * @subsection bx_ads-page_blocks Page Blocks
  718. * @subsubsection bx_ads-block_licenses block_licenses
  719. *
  720. * @code bx_srv('bx_ads', 'block_licenses', [...]); @endcode
  721. *
  722. * Get page block with a list of licenses purchased by currently logged member.
  723. *
  724. * @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.
  725. *
  726. * @see BxAdsModule::serviceBlockLicenses
  727. */
  728. /**
  729. * @ref bx_ads-block_licenses "block_licenses"
  730. */
  731. public function serviceBlockLicenses()
  732. {
  733. return $this->_getBlockLicenses();
  734. }
  735. /**
  736. * @page service Service Calls
  737. * @section bx_ads Ads
  738. * @subsection bx_ads-page_blocks Page Blocks
  739. * @subsubsection bx_ads-block_licenses_administration block_licenses_administration
  740. *
  741. * @code bx_srv('bx_ads', 'block_licenses_administration', [...]); @endcode
  742. *
  743. * Get page block with a list of all licenses. It's needed for moderators/administrators.
  744. *
  745. * @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.
  746. *
  747. * @see BxAdsModule::serviceBlockLicensesAdministration
  748. */
  749. /**
  750. * @ref bx_ads-block_licenses "block_licenses"
  751. */
  752. public function serviceBlockLicensesAdministration()
  753. {
  754. return $this->_getBlockLicenses('administration');
  755. }
  756. /**
  757. * @page service Service Calls
  758. * @section bx_ads Ads
  759. * @subsection bx_ads-page_blocks Page Blocks
  760. * @subsubsection bx_ads-block_licenses_note block_licenses_note
  761. *
  762. * @code bx_srv('bx_ads', 'block_licenses_note', [...]); @endcode
  763. *
  764. * Get page block with a notice for licenses usage.
  765. *
  766. * @return HTML string with block content to display on the site.
  767. *
  768. * @see BxAdsModule::serviceBlockLicensesNote
  769. */
  770. /**
  771. * @ref bx_ads-block_licenses_note "block_licenses_note"
  772. */
  773. public function serviceBlockLicensesNote()
  774. {
  775. return MsgBox(_t('_bx_ads_page_block_content_licenses_note'));
  776. }
  777. /**
  778. * @page service Service Calls
  779. * @section bx_ads Ads
  780. * @subsection bx_ads-payments Payments
  781. * @subsubsection bx_ads-get_payment_data get_payment_data
  782. *
  783. * @code bx_srv('bx_ads', 'get_payment_data', [...]); @endcode
  784. *
  785. * Get an array with module's description. Is needed for payments processing module.
  786. *
  787. * @return an array with module's description.
  788. *
  789. * @see BxAdsModule::serviceGetPaymentData
  790. */
  791. /**
  792. * @ref bx_ads-get_payment_data "get_payment_data"
  793. */
  794. public function serviceGetPaymentData()
  795. {
  796. $CNF = &$this->_oConfig->CNF;
  797. $oPermalink = BxDolPermalinks::getInstance();
  798. $aResult = $this->_aModule;
  799. $aResult['url_browse_order_common'] = bx_absolute_url($oPermalink->permalink($CNF['URL_LICENSES_COMMON'], array('filter' => '{order}')));
  800. $aResult['url_browse_order_administration'] = bx_absolute_url($oPermalink->permalink($CNF['URL_LICENSES_ADMINISTRATION'], array('filter' => '{order}')));
  801. return $aResult;
  802. }
  803. /**
  804. * @page service Service Calls
  805. * @section bx_ads Ads
  806. * @subsection bx_ads-payments Payments
  807. * @subsubsection bx_ads-get_cart_item get_cart_item
  808. *
  809. * @code bx_srv('bx_ads', 'get_cart_item', [...]); @endcode
  810. *
  811. * Get an array with prodict's description. Is used in Shopping Cart in payments processing module.
  812. *
  813. * @param $mixedItemId product's ID or Unique Name.
  814. * @return an array with prodict's description. Empty array is returned if something is wrong.
  815. *
  816. * @see BxAdsModule::serviceGetCartItem
  817. */
  818. /**
  819. * @ref bx_ads-get_cart_item "get_cart_item"
  820. */
  821. public function serviceGetCartItem($mixedItemId, $iClientId = 0)
  822. {
  823. $CNF = &$this->_oConfig->CNF;
  824. if(!$mixedItemId || !is_numeric($mixedItemId))
  825. return [];
  826. $aCommodity = $this->_oDb->getCommodity(['sample' => 'id_with_entry', 'id' => (int)$mixedItemId]);
  827. if(empty($aCommodity) || !is_array($aCommodity))
  828. return [];
  829. $iItemId = (int)$aCommodity['id'];
  830. $sItemType = $aCommodity['type'];
  831. $iItemAuthor = 0;
  832. $fItemPrice = 0;
  833. switch($sItemType) {
  834. case BX_ADS_COMMODITY_TYPE_PRODUCT:
  835. $iItemAuthor = $aCommodity['entry_' . $CNF['FIELD_AUTHOR']];
  836. $fItemPrice = (float)$aCommodity['entry_' . $CNF['FIELD_PRICE']];
  837. if($this->_oConfig->isAuction() && (int)$aCommodity['entry_' . $CNF['FIELD_AUCTION']] != 0) {
  838. $aOffer = $this->_oDb->getOffersBy([
  839. 'type' => 'content_and_author_ids',
  840. 'content_id' => $iItemId,
  841. 'author_id' => $iClientId,
  842. 'status' => BX_ADS_OFFER_STATUS_ACCEPTED
  843. ]);
  844. if(!empty($aOffer) && is_array($aOffer))
  845. $fItemPrice = (float)$aOffer[$CNF['FIELD_OFR_AMOUNT']];
  846. }
  847. break;
  848. case BX_ADS_COMMODITY_TYPE_PROMOTION:
  849. $iItemAuthor = BxDolPayments::getInstance()->getOption('site_admin');
  850. $fItemPrice = (float)$aCommodity['amount'];
  851. break;
  852. }
  853. if(!$iClientId)
  854. $iClientId = bx_get_logged_profile_id();
  855. return [
  856. 'id' => $iItemId,
  857. 'author_id' => $iItemAuthor,
  858. 'name' => $aCommodity['entry_' . $CNF['FIELD_NAME']] . '-' . $sItemType,
  859. 'title' => $aCommodity['entry_' . $CNF['FIELD_TITLE']],
  860. 'description' => $sItemDescription = _t($CNF['T']['txt_cd_ct_' . $sItemType]),
  861. 'url' => bx_absolute_url(BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'], ['id' => $aCommodity['entry_' . $CNF['FIELD_ID']]])),
  862. 'price_single' => $fItemPrice,
  863. 'price_recurring' => '',
  864. 'period_recurring' => 0,
  865. 'period_unit_recurring' => '',
  866. 'trial_recurring' => ''
  867. ];
  868. }
  869. /**
  870. * @page service Service Calls
  871. * @section bx_ads Ads
  872. * @subsection bx_ads-payments Payments
  873. * @subsubsection bx_ads-get_cart_items get_cart_items
  874. *
  875. * @code bx_srv('bx_ads', 'get_cart_items', [...]); @endcode
  876. *
  877. * Get an array with prodicts' descriptions by seller. Is used in Manual Order Processing in payments processing module.
  878. *
  879. * @param $iSellerId seller ID.
  880. * @return an array with prodicts' descriptions. Empty array is returned if something is wrong or seller doesn't have any products.
  881. *
  882. * @see BxAdsModule::serviceGetCartItems
  883. */
  884. /**
  885. * @ref bx_ads-get_cart_items "get_cart_items"
  886. */
  887. public function serviceGetCartItems($iSellerId)
  888. {
  889. $CNF = &$this->_oConfig->CNF;
  890. $iSellerId = (int)$iSellerId;
  891. if(empty($iSellerId))
  892. return [];
  893. $aItems = $this->_oDb->getCommodity(['sample' => 'entry_author', 'author' => $iSellerId, 'type' => BX_ADS_COMMODITY_TYPE_PRODUCT]);
  894. $aResult = [];
  895. foreach($aItems as $aItem) {
  896. $aItemInfo = $this->_oDb->getContentInfoById((int)$aItem['entry_id']);
  897. if(empty($aItemInfo) || !is_array($aItemInfo) || $aItemInfo[$CNF['FIELD_STATUS']] != BX_BASE_MOD_TEXT_STATUS_ACTIVE || empty($aItemInfo[$CNF['FIELD_QUANTITY']]))
  898. continue;
  899. $aResult[] = $this->serviceGetCartItem($aItem['id']);
  900. }
  901. return $aResult;
  902. }
  903. /**
  904. * @page service Service Calls
  905. * @section bx_ads Ads
  906. * @subsection bx_ads-payments Payments
  907. * @subsubsection bx_ads-authorize_cart_item authorize_cart_item
  908. *
  909. * @code bx_srv('bx_ads', 'authorize_cart_item', [...]); @endcode
  910. *
  911. * Authorize the order to process a single time payment inside the Ads module in future. Is called with payment processing module after the order was authorized there.
  912. *
  913. * @param $iClientId client ID.
  914. * @param $iSellerId seller ID
  915. * @param $iItemId item ID.
  916. * @param $iItemCount the number of purchased items.
  917. * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
  918. * @return an array with authorize prodict's description. Empty array is returned if something is wrong.
  919. *
  920. * @see BxAdsModule::serviceAuthorizeCartItem
  921. */
  922. /**
  923. * @ref bx_ads-authorize_cart_item "authorize_cart_item"
  924. */
  925. public function serviceAuthorizeCartItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder)
  926. {
  927. $CNF = &$this->_oConfig->CNF;
  928. $aItem = $this->serviceGetCartItem($iItemId);
  929. if(empty($aItem) || !is_array($aItem))
  930. return [];
  931. $aCommodity = $this->_oDb->getCommodity(['sample' => 'id_with_entry', 'id' => (int)$iItemId]);
  932. if(empty($aCommodity) || !is_array($aCommodity))
  933. return [];
  934. bx_alert($this->getName(), 'order_authorize', 0, false, [
  935. 'id' => $aCommodity['id'],
  936. 'type' => $aCommodity['type'],
  937. 'product_id' => $aCommodity['entry_id'],
  938. 'profile_id' => $iClientId,
  939. 'order' => $sOrder,
  940. 'count' => $iItemCount
  941. ]);
  942. return $aItem;
  943. }
  944. /**
  945. * @page service Service Calls
  946. * @section bx_ads Ads
  947. * @subsection bx_ads-payments Payments
  948. * @subsubsection bx_ads-register_cart_item register_cart_item
  949. *
  950. * @code bx_srv('bx_ads', 'register_cart_item', [...]); @endcode
  951. *
  952. * Register a processed single time payment inside the Ads module. Is called with payment processing module after the payment was registered there.
  953. *
  954. * @param $iClientId client ID.
  955. * @param $iSellerId seller ID
  956. * @param $iItemId item ID.
  957. * @param $iItemCount the number of purchased items.
  958. * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
  959. * @param $sLicense license number genereted with payment processing module for internal usage
  960. * @return an array with purchased prodict's description. Empty array is returned if something is wrong.
  961. *
  962. * @see BxAdsModule::serviceRegisterCartItem
  963. */
  964. /**
  965. * @ref bx_ads-register_cart_item "register_cart_item"
  966. */
  967. public function serviceRegisterCartItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense)
  968. {
  969. $aCommodity = $this->_oDb->getCommodity(['sample' => 'id', 'id' => (int)$iItemId]);
  970. if(empty($aCommodity) || !is_array($aCommodity))
  971. return [];
  972. $sMethod = '_registerCartItem' . bx_gen_method_name($aCommodity['type']);
  973. if(!method_exists($this, $sMethod))
  974. return [];
  975. return $this->$sMethod($iClientId, $iSellerId, $aCommodity, $iItemCount, $sOrder, $sLicense);
  976. }
  977. protected function _registerCartItemProduct($iClientId, $iSellerId, $aCommodity, $iItemCount, $sOrder, $sLicense)
  978. {
  979. $CNF = &$this->_oConfig->CNF;
  980. $sModule = $this->getName();
  981. $aItem = $this->serviceGetCartItem($aCommodity['id']);
  982. if(empty($aItem) || !is_array($aItem))
  983. return [];
  984. $aEntry = $this->_oDb->getContentInfoById($aCommodity['entry_id']);
  985. if(empty($aEntry) || !is_array($aEntry))
  986. return [];
  987. $iEntryId = (int)$aCommodity['entry_id'];
  988. $iEntryQnt = (int)$aEntry[$CNF['FIELD_QUANTITY']];
  989. if(($iEntryQnt - $iItemCount) < 0 || !$this->_oDb->registerLicense($iClientId, $iEntryId, $iItemCount, $sOrder, $sLicense))
  990. return [];
  991. $aOffer = $this->_oDb->getOffersBy([
  992. 'type' => 'content_and_author_ids',
  993. 'content_id' => $iEntryId,
  994. 'author_id' => $iClientId,
  995. 'status' => BX_ADS_OFFER_STATUS_ACCEPTED
  996. ]);
  997. if(!empty($aOffer) && is_array($aOffer))
  998. $this->_oDb->updateOffer([$CNF['FIELD_OFR_STATUS'] => BX_ADS_OFFER_STATUS_PAID], [$CNF['FIELD_OFR_ID'] => $aOffer[$CNF['FIELD_OFR_ID']]]);
  999. $iEntryQnt -= $iItemCount;
  1000. $bEntrySold = $iEntryQnt == 0;
  1001. $aUpdate = [
  1002. $CNF['FIELD_QUANTITY'] => $iEntryQnt
  1003. ];
  1004. if($bEntrySold)
  1005. $aUpdate = array_merge($aUpdate, [
  1006. $CNF['FIELD_STATUS'] => BX_ADS_STATUS_SOLD,
  1007. $CNF['FIELD_SOLD'] => time()
  1008. ]);
  1009. $this->_oDb->updateEntriesBy($aUpdate, [$CNF['FIELD_ID'] => $iEntryId]);
  1010. bx_alert($sModule, 'license_register', 0, false, [
  1011. 'id' => $aCommodity['id'],
  1012. 'type' => $aCommodity['type'],
  1013. 'product_id' => $iEntryId,
  1014. 'profile_id' => $iClientId,
  1015. 'order' => $sOrder,
  1016. 'license' => $sLicense,
  1017. 'count' => $iItemCount
  1018. ]);
  1019. if($bEntrySold) {
  1020. $aParams = $this->_alertParams($aEntry);
  1021. bx_alert($sModule, 'sold', $iEntryId, false, $aParams);
  1022. }
  1023. $oAuthor = BxDolProfile::getInstanceMagic($aEntry[$CNF['FIELD_AUTHOR']]);
  1024. $oClient = BxDolProfile::getInstanceMagic($iClientId);
  1025. $oSeller = BxDolProfile::getInstanceMagic($iSellerId);
  1026. $sSellerUrl = $oSeller->getUrl();
  1027. $sSellerName = $oSeller->getDisplayName();
  1028. $sNote = $aEntry[$CNF['FIELD_NOTES_PURCHASED']];
  1029. if(empty($sNote))
  1030. $sNote = _t('_bx_ads_txt_purchased_note', $sSellerUrl, $sSellerName);
  1031. $sEmailTemplate = $CNF['ETEMPLATE_PURCHASED'];
  1032. $aEmailParams = [
  1033. 'client_name' => $oClient->getDisplayName(),
  1034. 'entry_name' => $aEntry[$CNF['FIELD_TITLE']],
  1035. 'entry_url' => bx_absolute_url(BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'], ['id' => $iEntryId])),
  1036. 'author_url' => $oAuthor->getUrl(),
  1037. 'author_name' => $oAuthor->getDisplayName(),
  1038. 'vendor_url' => $sSellerUrl,
  1039. 'vendor_name' => $sSellerName,
  1040. 'count' => (int)$iItemCount,
  1041. 'license' => $sLicense,
  1042. 'notes' => $sNote,
  1043. ];
  1044. $bCancel = false;
  1045. bx_alert($sModule, 'license_register_notif', 0, false, [
  1046. 'entry_id' => $iEntryId,
  1047. 'order' => $sOrder,
  1048. 'recipient_id' => &$iClientId,
  1049. 'email_template' => &$sEmailTemplate,
  1050. 'email_params' => &$aEmailParams,
  1051. 'cancel' => &$bCancel
  1052. ]);
  1053. if(!$bCancel)
  1054. sendMailTemplate($sEmailTemplate, 0, $iClientId, $aEmailParams);
  1055. return $aItem;
  1056. }
  1057. protected function _registerCartItemPromotion($iClientId, $iSellerId, $aCommodity, $iItemCount, $sOrder, $sLicense)
  1058. {
  1059. $CNF = &$this->_oConfig->CNF;
  1060. $aItem = $this->serviceGetCartItem($aCommodity['id']);
  1061. if(empty($aItem) || !is_array($aItem))
  1062. return [];
  1063. $aEntry = $this->_oDb->getContentInfoById($aCommodity['entry_id']);
  1064. if(empty($aEntry) || !is_array($aEntry))
  1065. return [];
  1066. $iEntryId = (int)$aCommodity['entry_id'];
  1067. if(!$this->_oDb->registerPromotion($aEntry[$CNF['FIELD_AUTHOR']], $aCommodity['id'], $iEntryId, $aCommodity['amount'], $sOrder, $sLicense))
  1068. return [];
  1069. if($aEntry[$CNF['FIELD_STATUS_ADMIN']] == BX_ADS_STATUS_ADMIN_UNPAID) {
  1070. $aUpdate[$CNF['FIELD_STATUS_ADMIN']] = BX_BASE_MOD_GENERAL_STATUS_ACTIVE;
  1071. if(!$this->_isModerator() && !$this->_oConfig->isAutoApproveEnabled())
  1072. $aUpdate[$CNF['FIELD_STATUS_ADMIN']] = BX_BASE_MOD_GENERAL_STATUS_PENDING;
  1073. $this->_oDb->updateEntriesBy($aUpdate, [$CNF['FIELD_ID'] => $iEntryId]);
  1074. }
  1075. bx_alert($this->getName(), 'promotion_register', 0, false, [
  1076. 'id' => $aCommodity['id'],
  1077. 'type' => $aCommodity['type'],
  1078. 'product_id' => $iEntryId,
  1079. 'profile_id' => $iClientId,
  1080. 'amount' => $aCommodity['amount'],
  1081. 'order' => $sOrder,
  1082. 'license' => $sLicense,
  1083. ]);
  1084. return $aItem;
  1085. }
  1086. /**
  1087. * @page service Service Calls
  1088. * @section bx_ads Ads
  1089. * @subsection bx_ads-payments Payments
  1090. * @subsubsection bx_ads-authorize_subscription_item authorize_subscription_item
  1091. *
  1092. * @code bx_srv('bx_ads', 'authorize_subscription_item', [...]); @endcode
  1093. *
  1094. * Authorize the order to process a subscription (recurring payment) inside the Ads module in future. Is called with payment processing module after the order for subscription was authorized there.
  1095. *
  1096. * @param $iClientId client ID.
  1097. * @param $iSellerId seller ID
  1098. * @param $iItemId item ID.
  1099. * @param $iItemCount the number of purchased items.
  1100. * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
  1101. * @return an array with authorize prodict's description. Empty array is returned if something is wrong.
  1102. *
  1103. * @see BxAdsModule::serviceAuthorizeSubscriptionItem
  1104. */
  1105. /**
  1106. * @ref bx_ads-authorize_subscription_item "authorize_subscription_item"
  1107. */
  1108. public function serviceAuthorizeSubscriptionItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder)
  1109. {
  1110. return [];
  1111. }
  1112. /**
  1113. * @page service Service Calls
  1114. * @section bx_ads Ads
  1115. * @subsection bx_ads-payments Payments
  1116. * @subsubsection bx_ads-register_subscription_item register_subscription_item
  1117. *
  1118. * @code bx_srv('bx_ads', 'register_subscription_item', [...]); @endcode
  1119. *
  1120. * Register a processed subscription (recurring payment) inside the Ads module. Is called with payment processing module after the subscription was registered there.
  1121. *
  1122. * @param $iClientId client ID.
  1123. * @param $iSellerId seller ID
  1124. * @param $iItemId item ID.
  1125. * @param $iItemCount the number of purchased items.
  1126. * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
  1127. * @param $sLicense license number genereted with payment processing module for internal usage
  1128. * @return an array with subscribed prodict's description. Empty array is returned if something is wrong.
  1129. *
  1130. * @see BxAdsModule::serviceRegisterSubscriptionItem
  1131. */
  1132. /**
  1133. * @ref bx_ads-register_subscription_item "register_subscription_item"
  1134. */
  1135. public function serviceRegisterSubscriptionItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense)
  1136. {
  1137. return [];
  1138. }
  1139. /**
  1140. * @page service Service Calls
  1141. * @section bx_ads Ads
  1142. * @subsection bx_ads-payments Payments
  1143. * @subsubsection bx_ads-reregister_cart_item reregister_cart_item
  1144. *
  1145. * @code bx_srv('bx_ads', 'reregister_cart_item', [...]); @endcode
  1146. *
  1147. * Reregister a single time payment inside the Ads module. Is called with payment processing module after the payment was reregistered there.
  1148. *
  1149. * @param $iClientId client ID.
  1150. * @param $iSellerId seller ID
  1151. * @param $iItemIdOld old item ID.
  1152. * @param $iItemIdNew new item ID.
  1153. * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
  1154. * @return an array with purchased prodict's description. Empty array is returned if something is wrong.
  1155. *
  1156. * @see BxAdsModule::serviceReregisterCartItem
  1157. */
  1158. /**
  1159. * @ref bx_ads-reregister_cart_item "reregister_cart_item"
  1160. */
  1161. public function serviceReregisterCartItem($iClientId, $iSellerId, $iItemIdOld, $iItemIdNew, $sOrder)
  1162. {
  1163. return [];
  1164. }
  1165. /**
  1166. * @page service Service Calls
  1167. * @section bx_ads Ads
  1168. * @subsection bx_ads-payments Payments
  1169. * @subsubsection bx_ads-reregister_subscription_item reregister_subscription_item
  1170. *
  1171. * @code bx_srv('bx_ads', 'reregister_subscription_item', [...]); @endcode
  1172. *
  1173. * Reregister a subscription (recurring payment) inside the Ads module. Is called with payment processing module after the subscription was reregistered there.
  1174. *
  1175. * @param $iClientId client ID.
  1176. * @param $iSellerId seller ID
  1177. * @param $iItemIdOld old item ID.
  1178. * @param $iItemIdNew new item ID.
  1179. * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
  1180. * @return an array with subscribed prodict's description. Empty array is returned if something is wrong.
  1181. *
  1182. * @see BxAdsModule::serviceReregisterSubscriptionItem
  1183. */
  1184. /**
  1185. * @ref bx_ads-reregister_subscription_item "reregister_subscription_item"
  1186. */
  1187. public function serviceReregisterSubscriptionItem($iClientId, $iSellerId, $iItemIdOld, $iItemIdNew, $sOrder)
  1188. {
  1189. return [];
  1190. }
  1191. /**
  1192. * @page service Service Calls
  1193. * @section bx_ads Ads
  1194. * @subsection bx_ads-payments Payments
  1195. * @subsubsection bx_ads-unregister_cart_item unregister_cart_item
  1196. *
  1197. * @code bx_srv('bx_ads', 'unregister_cart_item', [...]); @endcode
  1198. *
  1199. * Unregister an earlier processed single time payment inside the Ads module. Is called with payment processing module after the payment was unregistered there.
  1200. *
  1201. * @param $iClientId client ID.
  1202. * @param $iSellerId seller ID
  1203. * @param $iItemId item ID.
  1204. * @param $iItemCount the number of purchased items.
  1205. * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
  1206. * @param $sLicense license number genereted with payment processing module for internal usage
  1207. * @return boolean value determining where the payment was unregistered or not.
  1208. *
  1209. * @see BxAdsModule::serviceUnregisterCartItem
  1210. */
  1211. /**
  1212. * @ref bx_ads-unregister_cart_item "unregister_cart_item"
  1213. */
  1214. public function serviceUnregisterCartItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense)
  1215. {
  1216. $aCommodity = $this->_oDb->getCommodity(['sample' => 'id', 'id' => (int)$iItemId]);
  1217. if(empty($aCommodity) || !is_array($aCommodity))
  1218. return [];
  1219. $sMethod = '_unregisterCartItem' . bx_gen_method_name($aCommodity['type']);
  1220. if(!method_exists($this, $sMethod))
  1221. return [];
  1222. return $this->$sMethod($iClientId, $iSellerId, $aCommodity, $iItemCount, $sOrder, $sLicense);
  1223. }
  1224. protected function _unregisterCartItemProduct($iClientId, $iSellerId, $aCommodity, $iItemCount, $sOrder, $sLicense)
  1225. {
  1226. $iEntryId = (int)$aCommodity['entry_id'];
  1227. if(!$this->_oDb->unregisterLicense($iClientId, $iEntryId, $sOrder, $sLicense))
  1228. return false;
  1229. bx_alert($this->getName(), 'license_unregister', 0, false, [
  1230. 'id' => $aCommodity['id'],
  1231. 'type' => $aCommodity['type'],
  1232. 'product_id' => $iEntryId,
  1233. 'profile_id' => $iClientId,
  1234. 'order' => $sOrder,
  1235. 'license' => $sLicense,
  1236. 'count' => $iItemCount
  1237. ]);
  1238. return true;
  1239. }
  1240. protected function _unregisterCartItemPromotion($iClientId, $iSellerId, $aCommodity, $iItemCount, $sOrder, $sLicense)
  1241. {
  1242. $CNF = &$this->_oConfig->CNF;
  1243. $aEntry = $this->_oDb->getContentInfoById($aCommodity['entry_id']);
  1244. if(empty($aEntry) || !is_array($aEntry))
  1245. return false;
  1246. $iEntryId = (int)$aCommodity['entry_id'];
  1247. if(!$this->_oDb->unregisterPromotion($aEntry[$CNF['FIELD_AUTHOR']], $aCommodity['id'], $iEntryId, $sOrder, $sLicense))
  1248. return false;
  1249. bx_alert($this->getName(), 'promotion_unregister', 0, false, [
  1250. 'id' => $aCommodity['id'],
  1251. 'type' => $aCommodity['type'],
  1252. 'product_id' => $iEntryId,
  1253. 'profile_id' => $iClientId,
  1254. 'amount' => $aCommodity['amount'],
  1255. 'order' => $sOrder,
  1256. 'license' => $sLicense
  1257. ]);
  1258. return true;
  1259. }
  1260. /**
  1261. * @page service Service Calls
  1262. * @section bx_ads Ads
  1263. * @subsection bx_ads-payments Payments
  1264. * @subsubsection bx_ads-unregister_subscription_item unregister_subscription_item
  1265. *
  1266. * @code bx_srv('bx_ads', 'unregister_subscription_item', [...]); @endcode
  1267. *
  1268. * Unregister an earlier processed subscription (recurring payment) inside the Ads module. Is called with payment processing module after the subscription was unregistered there.
  1269. *
  1270. * @param $iClientId client ID.
  1271. * @param $iSellerId seller ID
  1272. * @param $iItemId item ID.
  1273. * @param $iItemCount the number of purchased items.
  1274. * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
  1275. * @param $sLicense license number genereted with payment processing module for internal usage
  1276. * @return boolean value determining where the subscription was unregistered or not.
  1277. *
  1278. * @see BxAdsModule::serviceUnregisterSubscriptionItem
  1279. */
  1280. /**
  1281. * @ref bx_ads-unregister_subscription_item "unregister_subscription_item"
  1282. */
  1283. public function serviceUnregisterSubscriptionItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense)
  1284. {
  1285. return true;
  1286. }
  1287. /**
  1288. * @page service Service Calls
  1289. * @section bx_ads Ads
  1290. * @subsection bx_ads-payments Payments
  1291. * @subsubsection bx_ads-cancel_subscription_item cancel_subscription_item
  1292. *
  1293. * @code bx_srv('bx_ads', 'cancel_subscription_item', [...]); @endcode
  1294. *
  1295. * Cancel an earlier processed subscription (recurring payment) inside the Ads module. Is called with payment processing module after the subscription was canceled there.
  1296. *
  1297. * @param $iClientId client ID.
  1298. * @param $iSellerId seller ID
  1299. * @param $iItemId item ID.
  1300. * @param $iItemCount the number of purchased items.
  1301. * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
  1302. * @return boolean value determining where the subscription was canceled or not.
  1303. *
  1304. * @see BxAdsModule::serviceCancelSubscriptionItem
  1305. */
  1306. /**
  1307. * @ref bx_ads-cancel_subscription_item "cancel_subscription_item"
  1308. */
  1309. public function serviceCancelSubscriptionItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder)
  1310. {
  1311. return true;
  1312. }
  1313. public function serviceGetOffersCount($sStatus = '')
  1314. {
  1315. if(!$this->_oConfig->isAuction())
  1316. return 0;
  1317. if(empty($sStatus) || !in_array($sStatus, $this->_aOfferStatuses))
  1318. $sStatus = BX_ADS_OFFER_STATUS_AWAITING;
  1319. $iUserId = bx_get_logged_profile_id();
  1320. return $this->_oDb->getOffersBy(array('type' => 'content_author_id', 'author_id' => $iUserId, 'status' => $sStatus, 'count' => true));
  1321. }
  1322. public function serviceGetLiveUpdates($sStatus, $aMenuItemParent, $aMenuItemChild, $iCount = 0)
  1323. {
  1324. if(!in_array($sStatus, $this->_aOfferStatuses))
  1325. return false;
  1326. $iUserId = bx_get_logged_profile_id();
  1327. $iCountNew = $this->_oDb->getOffersBy(array('type' => 'content_author_id', 'author_id' => $iUserId, 'status' => $sStatus, 'count' => true));
  1328. if($iCountNew == $iCount)
  1329. return false;
  1330. return array(
  1331. 'count' => $iCountNew, // required
  1332. 'method' => 'bx_menu_show_live_update(oData)', // required
  1333. 'data' => array(
  1334. 'code' => BxDolTemplate::getInstance()->parseHtmlByTemplateName('menu_item_addon', array(
  1335. 'content' => '{count}'
  1336. )),
  1337. 'mi_parent' => $aMenuItemParent,
  1338. 'mi_child' => $aMenuItemChild
  1339. ), // optional, may have some additional data to be passed in JS method provided using 'method' param above.
  1340. );
  1341. }
  1342. public function serviceOffers()
  1343. {
  1344. $CNF = &$this->_oConfig->CNF;
  1345. if(!$this->_oConfig->isAuction())
  1346. return '';
  1347. $oGrid = BxDolGrid::getObjectInstance($CNF['OBJECT_GRID_OFFERS_ALL']);
  1348. if(!$oGrid)
  1349. return '';
  1350. return $oGrid->getCode();
  1351. }
  1352. public function serviceEntityOffers($iContentId = 0)
  1353. {
  1354. $CNF = &$this->_oConfig->CNF;
  1355. if(!$this->_oConfig->isAuction())
  1356. return '';
  1357. $oGrid = BxDolGrid::getObjectInstance($CNF['OBJECT_GRID_OFFERS']);
  1358. if(!$oGrid)
  1359. return '';
  1360. if(empty($iContentId) && ($_iContentId = bx_get('id')) !== false)
  1361. $iContentId = (int)$_iContentId;
  1362. $oGrid->setContentId($iContentId);
  1363. return $oGrid->getCode();
  1364. }
  1365. public function serviceEntityOfferAccepted($iContentId = 0)
  1366. {
  1367. $CNF = &$this->_oConfig->CNF;
  1368. if(!$this->_oConfig->isAuction())
  1369. return '';
  1370. $iUserId = bx_get_logged_profile_id();
  1371. if(empty($iContentId) && ($_iContentId = bx_get('id')) !== false)
  1372. $iContentId = (int)$_iContentId;
  1373. $aContent = $this->_oDb->getContentInfoById($iContentId);
  1374. if(empty($aContent) || !is_array($aContent) || $aContent[$CNF['FIELD_QUANTITY']] <= 0)
  1375. return '';
  1376. $aOffer = $this->_oDb->getOffersBy(array(
  1377. 'type' => 'content_and_author_ids',
  1378. 'content_id' => $iContentId,
  1379. 'author_id' => $iUserId,
  1380. 'status' => BX_ADS_OFFER_STATUS_ACCEPTED
  1381. ));
  1382. if(empty($aOffer) || !is_array($aOffer))
  1383. return '';
  1384. return $this->_oTemplate->entryOfferAccepted($iUserId, $aContent, $aOffer);
  1385. }
  1386. public function serviceIsSourcesAvaliable()
  1387. {
  1388. return $this->_oConfig->isSources();
  1389. }
  1390. public function serviceGetSources($iAuthorId)
  1391. {
  1392. $aSources = $this->_oDb->getSources(['sample' => 'all']);
  1393. $aOptions = $this->_oDb->getSourcesOptions($iAuthorId);
  1394. $aResult = [];
  1395. foreach($aSources as $sSource => $aSource) {
  1396. if(!isset($aOptions[$aSource['option_prefix'] . 'active']) || $aOptions[$aSource['option_prefix'] . 'active']['value'] != 'on')
  1397. continue;
  1398. foreach($aOptions as $sName => $aOption)
  1399. if(strpos($sName, $aSource['option_prefix']) !== false)
  1400. $aSource['options'][$sName] = $aOption;
  1401. $aResult[$sSource] = $aSource;
  1402. }
  1403. return $aResult;
  1404. }
  1405. public function serviceGetSource($iAuthorId, $sAuthorSource = '')
  1406. {
  1407. $aSourcesOptions = $this->serviceGetSources($iAuthorId);
  1408. if(empty($aSourcesOptions) || !is_array($aSourcesOptions))
  1409. return false;
  1410. $mixedResult = false;
  1411. if(!empty($sAuthorSource)) {
  1412. if(!empty($aSourcesOptions[$sAuthorSource]) && is_array($aSourcesOptions[$sAuthorSource]))
  1413. $mixedResult = $aSourcesOptions[$sAuthorSource];
  1414. }
  1415. else
  1416. $mixedResult = array_shift($aSourcesOptions);
  1417. return $mixedResult;
  1418. }
  1419. public function serviceLoadEntryFromSource($sSourceType, $sSource)
  1420. {
  1421. $iProfileId = bx_get_logged_profile_id();
  1422. $oSource = $this->getObjectSource($sSourceType, $iProfileId);
  1423. if(!$oSource)
  1424. return [];
  1425. return $oSource->getEntry($sSource);
  1426. }
  1427. public function serviceBlockSourcesDetails($iProfileId = 0)
  1428. {
  1429. $CNF = &$this->_oConfig->CNF;
  1430. if(!isLogged())
  1431. return bx_is_api() ? [bx_api_get_msg(_t('_Access denied'))] : ['content' => MsgBox(_t('_Access denied'))];
  1432. $iProfileId = !empty($iProfileId) ? $iProfileId : bx_get_logged_profile_id();
  1433. $oForm = BxTemplFormView::getObjectInstance($CNF['OBJECT_FORM_SOURCES_DETAILS'], $CNF['OBJECT_FORM_SOURCES_DETAILS_DISPLAY_EDIT']);
  1434. $oForm->setProfileId($iProfileId);
  1435. $oForm->initChecker();
  1436. if($oForm->isSubmitted()) {
  1437. if($oForm->isValid()) {
  1438. $aOptions = $this->_oDb->getSourcesOptions();
  1439. foreach($aOptions as $aOption) {
  1440. $sValue = bx_get($aOption['name']) !== false ? bx_get($aOption['name']) : '';
  1441. $this->_oDb->updateSourceOption($iProfileId, $aOption['id'], bx_process_input($sValue));
  1442. }
  1443. if (bx_is_api()){
  1444. return [
  1445. bx_api_get_block('form', $oForm->getCodeAPI(), ['ext' => ['name' => $this->getName(), 'request' => ['url' => '/api.php?r=' . $this->getName() . '/block_sources_details', 'immutable' => true]]]),
  1446. bx_api_get_block('redirect', ['uri' => '/' . BxDolPermalinks::getInstance()->permalink($CNF['URL_SOURCES']), 'timeout' => 100])
  1447. ];
  1448. }
  1449. else{
  1450. header('Location: ' . bx_absolute_url(BxDolPermalinks::getInstance()->permalink($CNF['URL_SOURCES'])));
  1451. return;
  1452. }
  1453. }
  1454. else
  1455. foreach($oForm->aInputs as $aInput)
  1456. if(!empty($aInput['error']) && !empty($aInput['attrs']['bx-data-source'])) {
  1457. $sSourceBlock = 'source_' . (int)$aInput['attrs']['bx-data-source'] . '_begin';
  1458. if(!empty($oForm->aInputs[$sSourceBlock]))
  1459. $oForm->aInputs[$sSourceBlock]['collapsed'] = false;
  1460. }
  1461. }
  1462. return bx_is_api() ? [bx_api_get_block('form', $oForm->getCodeAPI(), ['ext' => ['name' => $this->getName(), 'request' => ['url' => '/api.php?r=' . $this->getName() . '/block_sources_details', 'immutable' => true]]])] : ['content' => $oForm->getCode()];
  1463. }
  1464. public function isEntryActive($aContentInfo)
  1465. {
  1466. $CNF = &$this->_oConfig->CNF;
  1467. $iViewer = bx_get_logged_profile_id();
  1468. $bModerator = $this->_isModerator();
  1469. $mixedResult = null;
  1470. bx_alert($this->getName(), 'is_entry_active', 0, 0, ['viewer_id' => $iViewer, 'is_moderator' => $bModerator, 'content_info' => $aContentInfo, 'override_result' => &$mixedResult]);
  1471. if($mixedResult !== null)
  1472. return $mixedResult;
  1473. if($aContentInfo[$CNF['FIELD_AUTHOR']] == $iViewer || $bModerator)
  1474. return true;
  1475. if(isset($CNF['FIELD_STATUS']) && !in_array($aContentInfo[$CNF['FIELD_STATUS']], array(BX_BASE_MOD_TEXT_STATUS_ACTIVE, BX_ADS_STATUS_OFFER, BX_ADS_STATUS_SOLD)))
  1476. return false;
  1477. if(isset($CNF['FIELD_STATUS_ADMIN']) && $aContentInfo[$CNF['FIELD_STATUS_ADMIN']] != 'active')
  1478. return false;
  1479. return true;
  1480. }
  1481. public function isAuction($aContentInfo)
  1482. {
  1483. $CNF = &$this->_oConfig->CNF;
  1484. return $this->_oConfig->isAuction() && (int)$aContentInfo[$CNF['FIELD_AUCTION']] != 0;
  1485. }
  1486. public function isAllowedMakeOffer($mixedContent, $isPerformAction = false)
  1487. {
  1488. return $this->checkAllowedMakeOffer($mixedContent, $isPerformAction) === CHECK_ACTION_RESULT_ALLOWED;
  1489. }
  1490. public function checkAllowedMakeOffer($mixedContent, $isPerformAction = false)
  1491. {
  1492. $CNF = &$this->_oConfig->CNF;
  1493. $sTxtError = '_sys_txt_access_denied';
  1494. $iProfileId = bx_get_logged_profile_id();
  1495. if(!is_array($mixedContent))
  1496. $mixedContent = $this->_oDb->getContentInfoById((int)$mixedContent);
  1497. if(empty($mixedContent) || !is_array($mixedContent))
  1498. return _t($sTxtError);
  1499. if(!$this->isAuction($mixedContent) || (int)$mixedContent[$CNF['FIELD_QUANTITY']] <= 0)
  1500. return _t($sTxtError);
  1501. if($mixedContent[$CNF['FIELD_AUTHOR']] == $iProfileId)
  1502. return _t($sTxtError);
  1503. $aCheck = checkActionModule($iProfileId, 'make offer', $this->getName(), $isPerformAction);
  1504. if($aCheck[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED)
  1505. return $aCheck[CHECK_ACTION_MESSAGE];
  1506. return CHECK_ACTION_RESULT_ALLOWED;
  1507. }
  1508. public function isAllowedViewOffers($mixedContent, $isPerformAction = false)
  1509. {
  1510. return $this->checkAllowedViewOffers($mixedContent, $isPerformAction) === CHECK_ACTION_RESULT_ALLOWED;
  1511. }
  1512. public function checkAllowedViewOffers($mixedContent, $isPerformAction = false)
  1513. {
  1514. $CNF = &$this->_oConfig->CNF;
  1515. $sTxtError = '_sys_txt_access_denied';
  1516. if(!is_array($mixedContent))
  1517. $mixedContent = $this->_oDb->getContentInfoById((int)$mixedContent);
  1518. if(empty($mixedContent) || !is_array($mixedContent))
  1519. return _t($sTxtError);
  1520. if(!$this->isAuction($mixedContent))
  1521. return _t($sTxtError);
  1522. if($this->_isModerator())
  1523. return CHECK_ACTION_RESULT_ALLOWED;
  1524. if($mixedContent[$CNF['FIELD_AUTHOR']] == bx_get_logged_profile_id())
  1525. return CHECK_ACTION_RESULT_ALLOWED;
  1526. return _t($sTxtError);
  1527. }
  1528. public function isAllowedMarkShipped($mixedContent, $isPerformAction = false)
  1529. {
  1530. return $this->checkAllowedMarkShipped($mixedContent, $isPerformAction) === CHECK_ACTION_RESULT_ALLOWED;
  1531. }
  1532. public function checkAllowedMarkShipped($mixedContent, $isPerformAction = false)
  1533. {
  1534. return $this->checkAllowedMarkShippedForProfile($mixedContent, $isPerformAction);
  1535. }
  1536. public function checkAllowedMarkShippedForProfile($mixedContent, $isPerformAction = false, $iProfileId = false)
  1537. {
  1538. $CNF = &$this->_oConfig->CNF;
  1539. $sTxtError = '_sys_txt_access_denied';
  1540. if(!$iProfileId)
  1541. $iProfileId = bx_get_logged_profile_id();
  1542. if(!is_array($mixedContent))
  1543. $mixedContent = $this->_oDb->getContentInfoById((int)$mixedContent);
  1544. if(empty($mixedContent) || !is_array($mixedContent) || !$this->isSingle($mixedContent))
  1545. return _t($sTxtError);
  1546. if((int)$mixedContent[$CNF['FIELD_SHIPPED']] != 0 || $mixedContent[$CNF['FIELD_STATUS']] != BX_ADS_STATUS_SOLD || $mixedContent[$CNF['FIELD_AUTHOR']] != $iProfileId)
  1547. return _t($sTxtError);
  1548. return CHECK_ACTION_RESULT_ALLOWED;
  1549. }
  1550. public function isAllowedMarkReceived($mixedContent, $isPerformAction = false)
  1551. {
  1552. return $this->checkAllowedMarkReceived($mixedContent, $isPerformAction) === CHECK_ACTION_RESULT_ALLOWED;
  1553. }
  1554. public function checkAllowedMarkReceived($mixedContent, $isPerformAction = false)
  1555. {
  1556. return $this->checkAllowedMarkReceivedForProfile($mixedContent, $isPerformAction);
  1557. }
  1558. public function checkAllowedMarkReceivedForProfile($mixedContent, $isPerformAction = false, $iProfileId = false)
  1559. {
  1560. $CNF = &$this->_oConfig->CNF;
  1561. $sTxtError = '_sys_txt_access_denied';
  1562. if(!$iProfileId)
  1563. $iProfileId = bx_get_logged_profile_id();
  1564. if(!is_array($mixedContent))
  1565. $mixedContent = $this->_oDb->getContentInfoById((int)$mixedContent);
  1566. if(empty($mixedContent) || !is_array($mixedContent) || !$this->isSingle($mixedContent))
  1567. return _t($sTxtError);
  1568. if((int)$mixedContent[$CNF['FIELD_RECEIVED']] != 0 || !$this->_oDb->hasLicense($iProfileId, $mixedContent[$CNF['FIELD_ID']]))
  1569. return _t($sTxtError);
  1570. return CHECK_ACTION_RESULT_ALLOWED;
  1571. }
  1572. public function onPublished($iContentId)
  1573. {
  1574. $this->serviceUpdateCategoriesStats($iContentId);
  1575. parent::onPublished($iContentId);
  1576. }
  1577. public function onOfferAdded($iOfferId, &$aResult)
  1578. {
  1579. $CNF = &$this->_oConfig->CNF;
  1580. $aOfferInfo = $this->_oDb->getOffersBy(array('type' => 'id', 'id' => $iOfferId));
  1581. if(empty($aOfferInfo) || !is_array($aOfferInfo))
  1582. return;
  1583. $iContentId = (int)$aOfferInfo[$CNF['FIELD_OFR_CONTENT']];
  1584. $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
  1585. if(empty($aContentInfo) || !is_array($aContentInfo))
  1586. return;
  1587. $iViewer = bx_get_logged_profile_id();
  1588. $oViewer = BxDolProfile::getInstanceMagic($iViewer);
  1589. if(getParam($CNF['PARAM_USE_IIN']) == 'on')
  1590. sendMailTemplate($CNF['ETEMPLATE_OFFER_ADDED'], 0, $aContentInfo[$CNF['FIELD_AUTHOR']], array(
  1591. 'viewer_name' => $oViewer->getDisplayName(),
  1592. 'viewer_url' => $oViewer->getUrl(),
  1593. 'entry_name' => $aContentInfo[$CNF['FIELD_TITLE']],
  1594. 'entry_url' => bx_absolute_url(BxDolPermalinks::getInstance()->permalink('page.php', array(
  1595. 'i' => $CNF['URI_VIEW_ENTRY'],
  1596. $CNF['FIELD_ID'] => $iContentId
  1597. )))
  1598. ));
  1599. $aParams = $this->_alertParamsOffer($aContentInfo, $aOfferInfo);
  1600. $aParams['override_result'] = &$aResult;
  1601. bx_alert($this->getName(), 'offer_added', $iOfferId, $aOfferInfo[$CNF['FIELD_OFR_AUTHOR']], $aParams);
  1602. }
  1603. public function onOfferAccepted($iOfferId)
  1604. {
  1605. $CNF = &$this->_oConfig->CNF;
  1606. $aOfferInfo = $this->_oDb->getOffersBy(array('type' => 'id', 'id' => $iOfferId));
  1607. if(empty($aOfferInfo) || !is_array($aOfferInfo))
  1608. return;
  1609. $iContentId = (int)$aOfferInfo[$CNF['FIELD_OFR_CONTENT']];
  1610. $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
  1611. if(empty($aContentInfo) || !is_array($aContentInfo))
  1612. return;
  1613. if($aContentInfo[$CNF['FIELD_STATUS']] != BX_ADS_STATUS_OFFER && ($this->isSingle($aContentInfo) || $this->getAvailableQuantity($aContentInfo) <= 0))
  1614. if(!$this->_oDb->updateEntriesBy([$CNF['FIELD_STATUS'] => BX_ADS_STATUS_OFFER], [$CNF['FIELD_ID'] => $iContentId]))
  1615. return;
  1616. $this->serviceUpdateCategoriesStats($iContentId);
  1617. $iOfferer = (int)$aOfferInfo[$CNF['FIELD_OFR_AUTHOR']];
  1618. $oOfferer = BxDolProfile::getInstanceMagic($iOfferer);
  1619. if(getParam($CNF['PARAM_USE_IIN']) == 'on')
  1620. sendMailTemplate($CNF['ETEMPLATE_OFFER_ACCEPTED'], 0, $iOfferer, array(
  1621. 'offerer_name' => $oOfferer->getDisplayName(),
  1622. 'offerer_url' => $oOfferer->getUrl(),
  1623. 'entry_name' => $aContentInfo[$CNF['FIELD_TITLE']],
  1624. 'entry_url' => bx_absolute_url(BxDolPermalinks::getInstance()->permalink('page.php', array(
  1625. 'i' => $CNF['URI_VIEW_ENTRY'],
  1626. $CNF['FIELD_ID'] => $iContentId
  1627. )))
  1628. ));
  1629. $aParams = $this->_alertParamsOffer($aContentInfo, $aOfferInfo);
  1630. bx_alert($this->getName(), 'offer_accepted', $iOfferId, $aContentInfo[$CNF['FIELD_AUTHOR']], $aParams);
  1631. }
  1632. public function onOfferDeclined($iOfferId)
  1633. {
  1634. $CNF = &$this->_oConfig->CNF;
  1635. $aOfferInfo = $this->_oDb->getOffersBy(array('type' => 'id', 'id' => $iOfferId));
  1636. if(empty($aOfferInfo) || !is_array($aOfferInfo))
  1637. return;
  1638. $iContentId = (int)$aOfferInfo[$CNF['FIELD_OFR_CONTENT']];
  1639. $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
  1640. if(empty($aContentInfo) || !is_array($aContentInfo))
  1641. return;
  1642. $iOfferer = (int)$aOfferInfo[$CNF['FIELD_OFR_AUTHOR']];
  1643. $oOfferer = BxDolProfile::getInstanceMagic($iOfferer);
  1644. if(getParam($CNF['PARAM_USE_IIN']) == 'on')
  1645. sendMailTemplate($CNF['ETEMPLATE_OFFER_DECLINED'], 0, $iOfferer, array(
  1646. 'offerer_name' => $oOfferer->getDisplayName(),
  1647. 'offerer_url' => $oOfferer->getUrl(),
  1648. 'entry_name' => $aContentInfo[$CNF['FIELD_TITLE']],
  1649. 'entry_url' => bx_absolute_url(BxDolPermalinks::getInstance()->permalink('page.php', array(
  1650. 'i' => $CNF['URI_VIEW_ENTRY'],
  1651. $CNF['FIELD_ID'] => $iContentId
  1652. )))
  1653. ));
  1654. $aParams = $this->_alertParamsOffer($aContentInfo, $aOfferInfo);
  1655. bx_alert($this->getName(), 'offer_declined', $iOfferId, $aContentInfo[$CNF['FIELD_AUTHOR']], $aParams);
  1656. }
  1657. public function onOfferCanceled($iOfferId)
  1658. {
  1659. $CNF = &$this->_oConfig->CNF;
  1660. $aOfferInfo = $this->_oDb->getOffersBy(['type' => 'id', 'id' => $iOfferId]);
  1661. if(empty($aOfferInfo) || !is_array($aOfferInfo))
  1662. return;
  1663. $iContentId = (int)$aOfferInfo[$CNF['FIELD_OFR_CONTENT']];
  1664. $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
  1665. if(empty($aContentInfo) || !is_array($aContentInfo))
  1666. return;
  1667. if(!$this->_oDb->updateEntriesBy([$CNF['FIELD_STATUS'] => BX_BASE_MOD_TEXT_STATUS_ACTIVE], [$CNF['FIELD_ID'] => $iContentId]))
  1668. return;
  1669. $this->serviceUpdateCategoriesStats($iContentId);
  1670. $iOfferer = (int)$aOfferInfo[$CNF['FIELD_OFR_AUTHOR']];
  1671. $oOfferer = BxDolProfile::getInstanceMagic($iOfferer);
  1672. if(getParam($CNF['PARAM_USE_IIN']) == 'on')
  1673. sendMailTemplate($CNF['ETEMPLATE_OFFER_CANCELED'], 0, (int)$aContentInfo[$CNF['FIELD_AUTHOR']], [
  1674. 'offerer_name' => $oOfferer->getDisplayName(),
  1675. 'offerer_url' => $oOfferer->getUrl(),
  1676. 'entry_name' => $aContentInfo[$CNF['FIELD_TITLE']],
  1677. 'entry_url' => bx_absolute_url(BxDolPermalinks::getInstance()->permalink('page.php', [
  1678. 'i' => $CNF['URI_VIEW_ENTRY'],
  1679. $CNF['FIELD_ID'] => $iContentId
  1680. ]))
  1681. ]);
  1682. $aParams = $this->_alertParamsOffer($aContentInfo, $aOfferInfo);
  1683. bx_alert($this->getName(), 'offer_canceled', $iOfferId, $aOfferInfo[$CNF['FIELD_OFR_AUTHOR']], $aParams);
  1684. }
  1685. /**
  1686. * Common methods.
  1687. */
  1688. public function onShipped($mixedContent, $iProfileSrc = 0, $iProfileDst = 0)
  1689. {
  1690. $CNF = &$this->_oConfig->CNF;
  1691. if(!is_array($mixedContent))
  1692. $mixedContent = $this->_oDb->getContentInfoById((int)$mixedContent);
  1693. $iContentId = (int)$mixedContent[$CNF['FIELD_ID']];
  1694. if(empty($iProfileSrc))
  1695. $iProfileSrc = (int)$mixedContent[$CNF['FIELD_AUTHOR']];
  1696. $oProfileSrc = BxDolProfile::getInstanceMagic($iProfileSrc);
  1697. $aOffer = $this->_oDb->getOffersBy(array('type' => 'accepted', 'content_id' => $iContentId));
  1698. $bOffer = !empty($aOffer) && is_array($aOffer);
  1699. if(empty($iProfileDst) && $bOffer)
  1700. $iProfileDst = (int)$aOffer[$CNF['FIELD_OFR_AUTHOR']];
  1701. if(!empty($oProfileSrc) && !empty($iProfileDst) && getParam($CNF['PARAM_USE_IIN']) == 'on')
  1702. sendMailTemplate($CNF['ETEMPLATE_SHIPPED'], 0, $iProfileDst, array(
  1703. 'vendor_name' => $oProfileSrc->getDisplayName(),
  1704. 'vendor_url' => $oProfileSrc->getUrl(),
  1705. 'entry_name' => $mixedContent[$CNF['FIELD_TITLE']],
  1706. 'entry_url' => bx_absolute_url(BxDolPermalinks::getInstance()->permalink('page.php', array(
  1707. 'i' => $CNF['URI_VIEW_ENTRY'],
  1708. $CNF['FIELD_ID'] => $iContentId
  1709. )))
  1710. ));
  1711. $aParams = $this->_alertParams($mixedContent);
  1712. $aParams = array_merge($aParams, array(
  1713. 'profile_src' => $iProfileSrc,
  1714. 'profile_dst' => $iProfileDst,
  1715. 'offer_id' => $bOffer ? (int)$aOffer[$CNF['FIELD_OFR_ID']] : 0,
  1716. ));
  1717. bx_alert($this->getName(), 'shipped', $iContentId, false, $aParams);
  1718. }
  1719. public function onReceived($mixedContent, $iProfileSrc = 0, $iProfileDst = 0)
  1720. {
  1721. $CNF = &$this->_oConfig->CNF;
  1722. if(!is_array($mixedContent))
  1723. $mixedContent = $this->_oDb->getContentInfoById((int)$mixedContent);
  1724. $iContentId = (int)$mixedContent[$CNF['FIELD_ID']];
  1725. if(empty($iProfileDst))
  1726. $iProfileDst = (int)$mixedContent[$CNF['FIELD_AUTHOR']];
  1727. $aOffer = $this->_oDb->getOffersBy(array('type' => 'accepted', 'content_id' => $iContentId));
  1728. $bOffer = !empty($aOffer) && is_array($aOffer);
  1729. if(empty($iProfileSrc) && $bOffer)
  1730. $iProfileSrc = (int)$aOffer[$CNF['FIELD_OFR_AUTHOR']];
  1731. $oProfileSrc = BxDolProfile::getInstanceMagic($iProfileSrc);
  1732. if(!empty($iProfileSrc) && !empty($iProfileDst) && getParam($CNF['PARAM_USE_IIN']) == 'on')
  1733. sendMailTemplate($CNF['ETEMPLATE_RECEIVED'], 0, $iProfileDst, array(
  1734. 'client_name' => $oProfileSrc->getDisplayName(),
  1735. 'client_url' => $oProfileSrc->getUrl(),
  1736. 'entry_name' => $mixedContent[$CNF['FIELD_TITLE']],
  1737. 'entry_url' => bx_absolute_url(BxDolPermalinks::getInstance()->permalink('page.php', array(
  1738. 'i' => $CNF['URI_VIEW_ENTRY'],
  1739. $CNF['FIELD_ID'] => $iContentId
  1740. )))
  1741. ));
  1742. $aParams = $this->_alertParams($mixedContent);
  1743. $aParams = array_merge($aParams, array(
  1744. 'profile_src' => $iProfileSrc,
  1745. 'profile_dst' => $iProfileDst,
  1746. 'offer_id' => $bOffer ? (int)$aOffer[$CNF['FIELD_OFR_ID']] : 0,
  1747. ));
  1748. bx_alert($this->getName(), 'received', $iContentId, false, $aParams);
  1749. }
  1750. public function getObjectSource($sSource, $iProfileId = 0)
  1751. {
  1752. $aSource = $this->_oDb->getSources(array('sample' => 'by_name', 'name' => $sSource));
  1753. if(empty($aSource) || !is_array($aSource) || empty($aSource['class_name']))
  1754. return false;
  1755. if(!empty($iProfileId)) {
  1756. $aSource['author'] = (int)$iProfileId;
  1757. $aSource['options'] = $this->_oDb->getSourcesOptions((int)$iProfileId, $aSource['id']);
  1758. }
  1759. $sClassPath = !empty($aSource['class_file']) ? BX_DIRECTORY_PATH_ROOT . $aSource['class_file'] : $this->_oConfig->getClassPath() . $aSource['class_name'] . '.php';
  1760. if(!file_exists($sClassPath))
  1761. return false;
  1762. require_once($sClassPath);
  1763. return new $aSource['class_name']($this->_iProfileId, $aSource, $this);
  1764. }
  1765. public function offerAccept($iId)
  1766. {
  1767. $CNF = &$this->_oConfig->CNF;
  1768. $aOfferInfo = $this->_oDb->getOffersBy(['type' => 'id', 'id' => $iId]);
  1769. if(empty($aOfferInfo) || !is_array($aOfferInfo))
  1770. return false;
  1771. $iContentId = (int)$aOfferInfo[$CNF['FIELD_OFR_CONTENT']];
  1772. $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
  1773. if(empty($aContentInfo) || !is_array($aContentInfo))
  1774. return false;
  1775. $iQuantity = (int)$aOfferInfo[$CNF['FIELD_OFR_QUANTITY']];
  1776. $iQuantityAvailable = $this->getAvailableQuantity($aContentInfo);
  1777. if($iQuantity > $iQuantityAvailable)
  1778. return _t('_bx_ads_txt_err_offer_wrong_quantity', $iQuantityAvailable);
  1779. if(!$this->_oDb->updateOffer([$CNF['FIELD_OFR_STATUS'] => BX_ADS_OFFER_STATUS_ACCEPTED], [$CNF['FIELD_OFR_ID'] => $iId]))
  1780. return false;
  1781. $this->onOfferAccepted($iId);
  1782. return true;
  1783. }
  1784. public function offerDecline($iId)
  1785. {
  1786. $CNF = &$this->_oConfig->CNF;
  1787. if(!$this->_oDb->updateOffer([$CNF['FIELD_OFR_STATUS'] => BX_ADS_OFFER_STATUS_DECLINED], [$CNF['FIELD_OFR_ID'] => $iId]))
  1788. return false;
  1789. $this->onOfferDeclined($iId);
  1790. return true;
  1791. }
  1792. public function offerCancel($iId)
  1793. {
  1794. $CNF = &$this->_oConfig->CNF;
  1795. if(!$this->_oDb->updateOffer([$CNF['FIELD_OFR_STATUS'] => BX_ADS_OFFER_STATUS_CANCELED], [$CNF['FIELD_OFR_ID'] => $iId]))
  1796. return false;
  1797. $this->onOfferCanceled($iId);
  1798. return true;
  1799. }
  1800. public function offerPay($iId)
  1801. {
  1802. $CNF = &$this->_oConfig->CNF;
  1803. $aOffer = $this->_oDb->getOffersBy(array('type' => 'id', 'id' => $iId));
  1804. if(empty($aOffer) || !is_array($aOffer))
  1805. return false;
  1806. $iContent = (int)$aOffer[$CNF['FIELD_OFR_CONTENT']];
  1807. $aContent = $this->_oDb->getContentInfoById($iContent);
  1808. $iContentAuthor = (int)$aContent[$CNF['FIELD_AUTHOR']];
  1809. $aReturn = array(
  1810. 'redirect' => bx_absolute_url(BxDolPermalinks::getInstance()->permalink('page.php', array(
  1811. 'i' => $CNF['URI_VIEW_ENTRY'],
  1812. $CNF['FIELD_ID'] => $aOffer[$CNF['FIELD_OFR_CONTENT']]
  1813. )))
  1814. );
  1815. $oPayments = BxDolPayments::getInstance();
  1816. $aResult = $oPayments->addToCart($iContentAuthor, $this->getName(), $iContent, $aOffer[$CNF['FIELD_OFR_QUANTITY']]);
  1817. if(!empty($aResult) && is_array($aResult)) {
  1818. if(!empty($aResult['message']))
  1819. $aReturn['msg'] = $aResult['message'];
  1820. if(isset($aResult['code']) && (int)$aResult['code'] == 0)
  1821. $aReturn['redirect'] = $oPayments->getCartUrl($iContentAuthor);
  1822. }
  1823. return $aReturn;
  1824. }
  1825. public function processMetasAdd($iContentId)
  1826. {
  1827. if(!parent::processMetasAdd($iContentId))
  1828. return false;
  1829. $CNF = &$this->_oConfig->CNF;
  1830. $oMetatags = BxDolMetatags::getObjectInstance($CNF['OBJECT_METATAGS']);
  1831. $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
  1832. $aCategoryTypes = $this->_oDb->getCategoryTypes(array('type' => 'all'));
  1833. foreach($aCategoryTypes as $aCategoryType)
  1834. $oMetatags->metaAddAuto($iContentId, $aContentInfo, $CNF, $aCategoryType['display_add']);
  1835. return true;
  1836. }
  1837. public function processMetasEdit($iContentId, $oForm)
  1838. {
  1839. if(!parent::processMetasEdit($iContentId, $oForm))
  1840. return false;
  1841. $CNF = &$this->_oConfig->CNF;
  1842. $oMetatags = BxDolMetatags::getObjectInstance($CNF['OBJECT_METATAGS']);
  1843. $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
  1844. $aCategoryTypes = $this->_oDb->getCategoryTypes(array('type' => 'all'));
  1845. foreach($aCategoryTypes as $aCategoryType)
  1846. $oMetatags->metaAddAuto($iContentId, $aContentInfo, $CNF, $aCategoryType['display_edit']);
  1847. return true;
  1848. }
  1849. public function getCategoryDisplay($sDisplayType, $iCategory = 0)
  1850. {
  1851. if(empty($iCategory) && bx_get('category') !== false)
  1852. $iCategory = (int)bx_get('category');
  1853. if(empty($iCategory))
  1854. return false;
  1855. $aCategory = $this->_oDb->getCategories(array('type' => 'id_full', 'id' => $iCategory));
  1856. $sKey = 'type_display_' . $sDisplayType;
  1857. if(empty($aCategory[$sKey]))
  1858. return false;
  1859. return $aCategory[$sKey];
  1860. }
  1861. public function isSingle($mixedContent)
  1862. {
  1863. $CNF = &$this->_oConfig->CNF;
  1864. if(!is_array($mixedContent))
  1865. $mixedContent = $this->_oDb->getContentInfoById((int)$mixedContent);
  1866. return (int)$mixedContent[$CNF['FIELD_SINGLE']] == 1;
  1867. }
  1868. public function getAvailableQuantity($mixedContent)
  1869. {
  1870. $CNF = &$this->_oConfig->CNF;
  1871. if(!is_array($mixedContent))
  1872. $mixedContent = $this->_oDb->getContentInfoById((int)$mixedContent);
  1873. if(!$this->_oConfig->isAuction() || (int)$mixedContent[$CNF['FIELD_AUCTION']] == 0)
  1874. return (int)$mixedContent[$CNF['FIELD_QUANTITY']];
  1875. $iQuantity = (int)$this->_oDb->getOffersBy([
  1876. 'type' => 'quantity_reserved',
  1877. 'content_id' => $mixedContent[$CNF['FIELD_ID']],
  1878. 'status' => BX_ADS_OFFER_STATUS_ACCEPTED
  1879. ]);
  1880. return (int)$mixedContent[$CNF['FIELD_QUANTITY']] - $iQuantity;
  1881. }
  1882. /**
  1883. * Internal methods.
  1884. */
  1885. protected function _actionMarkAs($sAction)
  1886. {
  1887. $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
  1888. if(($mixedResult = $this->serviceMarkAs($sAction, $iContentId)) !== true)
  1889. return array('msg' => $mixedResult);
  1890. return array(
  1891. 'reload' => 1
  1892. );
  1893. }
  1894. protected function _actionChangeStatus($sStatus)
  1895. {
  1896. $CNF = &$this->_oConfig->CNF;
  1897. $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
  1898. $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
  1899. if(($mixedResult = $this->checkAllowedEdit($aContentInfo)) !== CHECK_ACTION_RESULT_ALLOWED)
  1900. return array('msg' => $mixedResult);
  1901. if(!$this->_oDb->updateEntriesBy(array($CNF['FIELD_STATUS'] => $sStatus), array($CNF['FIELD_ID'] => $iContentId)))
  1902. return array('msg' => _t('_bx_ads_txt_err_cannot_perform_action'));
  1903. $this->serviceUpdateCategoriesStats($aContentInfo);
  1904. return array(
  1905. 'reload' => 1
  1906. );
  1907. }
  1908. protected function _serviceEntityForm ($sFormMethod, $iContentId = 0, $sDisplay = false, $sCheckFunction = false, $bErrorMsg = true)
  1909. {
  1910. $CNF = &$this->_oConfig->CNF;
  1911. $mixedContent = $this->_getContent($iContentId, true);
  1912. if($mixedContent === false)
  1913. return false;
  1914. list($iContentId, $aContentInfo) = $mixedContent;
  1915. $sDisplayType = false;
  1916. switch($sFormMethod) {
  1917. case 'editDataForm':
  1918. if($sDisplay === false)
  1919. $sDisplayType = 'edit';
  1920. break;
  1921. case 'viewDataForm':
  1922. case 'viewDataEntry':
  1923. $sDisplayType = 'view';
  1924. break;
  1925. }
  1926. if($sDisplayType !== false && ($sDisplayNew = $this->getCategoryDisplay($sDisplayType, $aContentInfo[$CNF['FIELD_CATEGORY']])) !== false)
  1927. $sDisplay = $sDisplayNew;
  1928. return parent::_serviceEntityForm ($sFormMethod, $iContentId, $sDisplay, $sCheckFunction, $bErrorMsg);
  1929. }
  1930. protected function _getCategoryOptions($iParentId, &$aValues)
  1931. {
  1932. $aCategories = $this->_oDb->getCategories(array('type' => 'parent_id', 'parent_id' => $iParentId, 'active' => true));
  1933. foreach($aCategories as $aCategory) {
  1934. $aValues[] = array('key' => $aCategory['id'], 'value' => str_repeat('--', (int)$aCategory['level']) . ' ' . _t($aCategory['title']));
  1935. $this->_getCategoryOptions($aCategory['id'], $aValues);
  1936. }
  1937. }
  1938. protected function _getSearchableFields($mixedDisplayType = '')
  1939. {
  1940. $CNF = &$this->_oConfig->CNF;
  1941. if(empty($mixedDisplayType))
  1942. $mixedDisplayType = array('add', 'edit');
  1943. $aResult = array();
  1944. $aDisplays = $this->_oDb->getDisplays($this->_oConfig->getName() . '_entry', $mixedDisplayType);
  1945. foreach($aDisplays as $aDisplay) {
  1946. if($aDisplay['display_name'] == $CNF['OBJECT_FORM_ENTRY_DISPLAY_ADD'])
  1947. continue;
  1948. $oForm = BxDolForm::getObjectInstance($CNF['OBJECT_FORM_ENTRY'], $aDisplay['display_name'], $this->_oTemplate);
  1949. if(!$oForm)
  1950. continue;
  1951. $aResult = array_merge($aResult, $oForm->aInputs);
  1952. }
  1953. return $aResult;
  1954. }
  1955. protected function _getContentForTimelinePost($aEvent, $aContentInfo, $aBrowseParams = array())
  1956. {
  1957. $CNF = &$this->_oConfig->CNF;
  1958. $bDynamic = isset($aBrowseParams['dynamic_mode']) && (bool)$aBrowseParams['dynamic_mode'] === true;
  1959. $sCategory = '';
  1960. if(!empty($CNF['FIELD_CATEGORY']) && !empty($aContentInfo[$CNF['FIELD_CATEGORY']])) {
  1961. $iCategory = (int)$aContentInfo[$CNF['FIELD_CATEGORY']];
  1962. $aCategory = $this->_oDb->getCategories(array('type' => 'id', 'id' => $iCategory));
  1963. $sCategory = _t($aCategory['title']);
  1964. $sCategoryLink = bx_absolute_url(BxDolPermalinks::getInstance()->permalink($CNF['URL_CATEGORIES'], array($CNF['GET_PARAM_CATEGORY'] => $iCategory)));
  1965. }
  1966. $sPrice = _t('_bx_ads_txt_free');
  1967. if(!empty($CNF['FIELD_PRICE']) && !empty($aContentInfo[$CNF['FIELD_PRICE']]))
  1968. $sPrice = _t_format_currency_ext((float)$aContentInfo[$CNF['FIELD_PRICE']], [
  1969. 'sign' => BxDolPayments::getInstance()->getCurrencySign((int)$aContentInfo[$CNF['FIELD_AUTHOR']])
  1970. ]);
  1971. $sInclude = $this->_oTemplate->addCss(array('timeline.css'), $bDynamic);
  1972. $aResult = parent::_getContentForTimelinePost($aEvent, $aContentInfo, $aBrowseParams);
  1973. if(bx_is_api()){
  1974. $aResult['price'] = $sPrice;
  1975. $aResult['category_title'] = $sCategory;
  1976. }
  1977. else{
  1978. $aResult['text'] = $this->_oTemplate->parseHtmlByName('timeline_post_text.html', array(
  1979. 'category_link' => $sCategoryLink,
  1980. 'category_title' => $sCategory,
  1981. 'category_title_attr' => bx_html_attribute($sCategory),
  1982. 'price' => $sPrice,
  1983. 'text' => $aResult['text']
  1984. )) . ($bDynamic ? $sInclude : '');
  1985. }
  1986. if($this->_oConfig->isSources() && !empty($aContentInfo[$CNF['FIELD_URL']]))
  1987. $aResult['url'] = $aContentInfo[$CNF['FIELD_URL']];
  1988. if($this->_oConfig->isPromotion()) {
  1989. $sJsObject = $this->_oConfig->getJsObject('main');
  1990. $sHtmlId = $this->_oConfig->getHtmlIds('unit') . $aContentInfo[$CNF['FIELD_ID']] . '-' . time() . '-' . mt_rand(0, 100);
  1991. $aResult = array_merge($aResult, [
  1992. 'url' => 'javascript:void(0)',
  1993. 'onclick' => 'return ' . $sJsObject . '.registerClick(this, ' . $aContentInfo[$CNF['FIELD_ID']] . ')',
  1994. 'raw' => $this->_oTemplate->parseHtmlByName('timeline_post_promotion.html', [
  1995. 'html_id' => $sHtmlId,
  1996. 'js_code' => $this->_oTemplate->_wrapInTagJsCode($sJsObject . '.registerTrakerForTimeline(' . $aContentInfo[$CNF['FIELD_ID']] . ', \'' . $sHtmlId . '\');')
  1997. ])
  1998. ]);
  1999. }
  2000. return $aResult;
  2001. }
  2002. protected function _getBlockLicenses($sType = '')
  2003. {
  2004. $CNF = &$this->_oConfig->CNF;
  2005. $sGrid = $CNF['OBJECT_GRID_LICENSES' . (!empty($sType) ? '_' . strtoupper($sType) : '')];
  2006. $oGrid = BxDolGrid::getObjectInstance($sGrid);
  2007. if(!$oGrid)
  2008. return '';
  2009. $this->_oDb->updateLicense(array('new' => 0), array('profile_id' => bx_get_logged_profile_id(), 'new' => 1));
  2010. $this->_oTemplate->addJs(array('licenses.js'));
  2011. return array(
  2012. 'content' => $this->_oTemplate->getJsCode('licenses', array('sObjNameGrid' => $sGrid)) . $oGrid->getCode(),
  2013. 'menu' => $CNF['OBJECT_MENU_LICENSES']
  2014. );
  2015. }
  2016. protected function _alertParamsOffer($aContentInfo, $aOfferInfo)
  2017. {
  2018. $CNF = &$this->_oConfig->CNF;
  2019. $aParams = array(
  2020. 'object_id' => (int)$aContentInfo[$CNF['FIELD_ID']],
  2021. 'object_author_id' => (int)$aContentInfo[$CNF['FIELD_AUTHOR']],
  2022. 'offer_id' => (int)$aOfferInfo[$CNF['FIELD_OFR_ID']],
  2023. 'offer_author_id' => (int)$aOfferInfo[$CNF['FIELD_OFR_AUTHOR']],
  2024. );
  2025. if(isset($aContentInfo[$CNF['FIELD_ALLOW_VIEW_TO']]))
  2026. $aParams['privacy_view'] = $aContentInfo[$CNF['FIELD_ALLOW_VIEW_TO']];
  2027. return $aParams;
  2028. }
  2029. }
  2030. /** @} */