BxMessengerTemplate.php 128 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979
  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 Messenger Messenger
  7. * @ingroup UnaModules
  8. *
  9. * @{
  10. */
  11. /**
  12. * Module representation
  13. */
  14. class BxMessengerTemplate extends BxBaseModGeneralTemplate
  15. {
  16. function __construct(&$oConfig, &$oDb)
  17. {
  18. parent::__construct($oConfig, $oDb);
  19. }
  20. /**
  21. * Attach js and css files for messenger depends on page with messenger block
  22. *@param string $sMode
  23. */
  24. public function loadCssJs($sMode = 'all'){
  25. $aCss = [
  26. 'main.css',
  27. 'video-conference.css',
  28. 'video-recorder.css',
  29. 'emoji.css',
  30. 'messenger-phone.css',
  31. 'quill.bubble.css',
  32. 'menu-accordion.css',
  33. 'lot-briefs.css',
  34. 'text-area.css',
  35. 'menu-column.css',
  36. 'history.css',
  37. 'history-header.css',
  38. 'message.css',
  39. 'talk.css',
  40. 'talks-list.css',
  41. 'info-block.css',
  42. 'time-divider.css',
  43. 'message-menu.css',
  44. 'giphy.css',
  45. 'tailwind-messenger.css',
  46. 'create-list.css',
  47. 'attachment.css',
  48. 'scroll-elements.css',
  49. '3rd-libs.css',
  50. 'talk-info.css'
  51. ];
  52. $aJs = [
  53. 'primus.js',
  54. 'record-video.js',
  55. 'editor.js',
  56. 'storage.js',
  57. 'connect.js',
  58. 'status.js',
  59. 'lazy-loading.js',
  60. 'selectors.js',
  61. 'jot-menu.js',
  62. 'giphy.js',
  63. 'messenger.js',
  64. 'RecordRTC.min.js',
  65. 'adapter.js',
  66. 'soundjs.min.js',
  67. 'quill.min.js',
  68. 'nav-menu.js',
  69. 'utils.js',
  70. 'media-accordion.js',
  71. 'notification-bubbles.js',
  72. 'jquery-ui/jquery.ui.widget.min.js',
  73. 'jquery-ui/jquery.ui.tooltip.min.js',
  74. 'emoji.js',
  75. 'create-convo-menu.js'
  76. ];
  77. if ($sMode === 'all')
  78. array_push($aCss, 'messenger.css');
  79. if ($sMode === 'view')
  80. array_push($aCss, 'talk-block.css');
  81. if ($this->_oConfig->CNF['USE_MENTIONS']) {
  82. array_push($aCss, 'quill.mention.css');
  83. array_push($aJs, 'quill.mention.min.js');
  84. }
  85. $this->initFilesUploader();
  86. $this->addCss($aCss);
  87. $this->addJs($aJs);
  88. }
  89. /**
  90. * Main function to build post messages area with messages history
  91. *@param int $iProfileId logged member id
  92. *@param int $iLotId id of conversation. It can be empty if new talk
  93. *@param int $iJotId jot id, allows to load history from jot's position
  94. *@return string html code
  95. */
  96. public function getHistory($iProfileId, $iLotId = BX_IM_EMPTY, $iJotId = BX_IM_EMPTY){
  97. $CNF = $this->_oConfig->CNF;
  98. $aParams = [
  99. 'content' => $this -> parseHtmlByName('history-block.html', array(
  100. 'content' => MsgBox(_t('_bx_messenger_empty_history'))
  101. )),
  102. 'info' => $this -> parseHtmlByName('info-area.html', []),
  103. 'new_msg_active' => 'none',
  104. 'unread_count' => 0
  105. ];
  106. if ($iLotId){
  107. $iUnreadLotsJots = $this->_oDb->getUnreadJotsMessagesCount($iProfileId, $iLotId);
  108. if ($iUnreadLotsJots && !$iJotId)
  109. $iJotId = $this -> _oDb -> getFirstUnreadJot($iProfileId, $iLotId);
  110. $sContent = $this->getHistoryArea(['profile_id' => $iProfileId, 'lot' => $iLotId, 'jot' => $iJotId],
  111. $iUnreadLotsJots && $iUnreadLotsJots < (int)($CNF['MAX_JOTS_BY_DEFAULT']/2));
  112. $aParams = [
  113. 'content' => $sContent,
  114. 'new_msg_active' => $iUnreadLotsJots ? 'block' : 'none',
  115. 'unread_count' => $iUnreadLotsJots,
  116. 'info' => $this -> parseHtmlByName('info-area.html', []),
  117. ];
  118. }
  119. $aParams['bx_if:search'] = array(
  120. 'condition' => $this->_oConfig->isSearchCriteria(BX_SEARCH_CRITERIA_CONTENT),
  121. 'content' => []
  122. );
  123. return bx_is_api() ? $aParams : $this -> parseHtmlByName('history.html', $aParams);
  124. }
  125. public function getHistoryArea($aData, $bRead = false, $bEmptyMessage = false){
  126. $CNF = $this->_oConfig->CNF;
  127. $iProfileId = isset($aData['profile_id']) ? (int)$aData['profile_id']: BX_IM_EMPTY;
  128. $iLotId = isset($aData['lot']) ? (int)$aData['lot']: BX_IM_EMPTY;
  129. $iJotId = isset($aData['jot']) ? (int)$aData['jot']: BX_IM_EMPTY;
  130. $sArea = isset($aData['area']) ? $aData['area']: '';
  131. $sContent = !$bEmptyMessage ? MsgBox(_t('_bx_messenger_empty_history')) : '';
  132. if ($iLotId){
  133. $aJots = $this -> getJotsOfLot($iProfileId,
  134. array(
  135. 'lot_id' => $iLotId,
  136. 'limit' => $CNF['MAX_JOTS_BY_DEFAULT'],
  137. 'start' => $iJotId,
  138. 'display' => true,
  139. 'select' => true,
  140. 'views' => true,
  141. 'read' => $bRead,
  142. 'area' => $sArea
  143. ));
  144. if (!empty($aJots) && isset($aJots['content']))
  145. $sContent = $aJots['content'];
  146. }
  147. if (bx_is_api())
  148. return $aJots;
  149. return $this -> parseHtmlByName('history-block.html', array(
  150. 'content' => $sContent
  151. ));
  152. }
  153. public function getTextArea($iProfileId, $iLotId = 0, $bHideTopics = false){
  154. $CNF = $this->_oConfig->CNF;
  155. $mixedResult = $this->_oConfig->isAllowedAction(BX_MSG_ACTION_SEND_MESSAGE, $iProfileId);
  156. if (!$iProfileId || $mixedResult !== true)
  157. return '';
  158. $bRecorder = $this->_oConfig->isAllowedAction(BX_MSG_ACTION_VIDEO_RECORDER, $iProfileId) === true;
  159. $bFiles = $this->_oConfig->isAllowedAction(BX_MSG_ACTION_SEND_FIELS, $iProfileId) === true;
  160. $bGiphy = $CNF['GIPHY']['api_key'] !== '';
  161. $bSmiles = true;
  162. $bCheckAction = $this->_oConfig->isAllowedAction(BX_MSG_ACTION_ADMINISTRATE_TALKS, $iProfileId) === true;
  163. $bIsAuthor = $bCheckAction || $this->_oDb->isAuthor($iLotId, $iProfileId);
  164. $mixedOptions = $this->_oDb->getLotSettings($iLotId);
  165. if ($mixedOptions !== FALSE && is_array($mixedOptions) && !$bIsAuthor) {
  166. if (!in_array(BX_MSG_SETTING_MSG, $mixedOptions))
  167. return '';
  168. $bFiles &= in_array(BX_MSG_SETTING_FILES, $mixedOptions);
  169. $bRecorder &= in_array(BX_MSG_SETTING_VIDEO_RECORD, $mixedOptions);
  170. $bGiphy &= in_array(BX_MSG_SETTING_GIPHY, $mixedOptions);
  171. $bSmiles = in_array(BX_MSG_SETTING_SMILES, $mixedOptions);
  172. }
  173. $aVars = [
  174. 'bx_if:giphy' => [
  175. 'condition' => $bGiphy,
  176. 'content' => []
  177. ],
  178. 'bx_if:recording' => [
  179. 'condition' => $bRecorder,
  180. 'content' => []
  181. ],
  182. 'bx_if:files' => [
  183. 'condition' => $bFiles,
  184. 'content' => []
  185. ],
  186. 'bx_if:smiles' => [
  187. 'condition' => $bSmiles,
  188. 'content' => []
  189. ],
  190. 'bx_if:text' => [
  191. 'condition' => true,
  192. 'content' => []
  193. ],
  194. 'giphy' => $bGiphy ? $this->getGiphyPanel() : '',
  195. 'bx_if:topics' => [
  196. 'condition' => !$iLotId && !$bHideTopics,
  197. 'content' => []
  198. ]
  199. ];
  200. $sTextArea = $this -> parseHtmlByName('text-area.html', $aVars);
  201. bx_alert($this->_oConfig->getObject('alert'), 'text_area_before', $iLotId, $iProfileId, [
  202. 'content' => &$sTextArea
  203. ]);
  204. return $sTextArea;
  205. }
  206. public function initFilesUploader(){
  207. $this->addCss(array(
  208. 'filepond-custom.css',
  209. 'filepond-plugin-media-preview.min.css',
  210. BX_DIRECTORY_PATH_PLUGINS_PUBLIC . 'filepond/|filepond.min.css',
  211. BX_DIRECTORY_PATH_PLUGINS_PUBLIC . 'filepond/|filepond-plugin-image-preview.min.css'
  212. ));
  213. $this->addJs(array(
  214. 'uploader.js',
  215. 'filepond/filepond.min.js',
  216. 'filepond/filepond-plugin-image-preview.min.js',
  217. 'filepond/filepond-plugin-file-validate-size.min.js',
  218. 'filepond-plugin-media-preview.min.js',
  219. 'filepond-plugin-file-rename.min.js'
  220. ));
  221. $this->addJsTranslation(array(
  222. '_bx_messenger_upload_delete',
  223. '_bx_messenger_delete_confirm',
  224. '_bx_messenger_upload_invalid_file_type',
  225. '_bx_messenger_max_files_upload_error',
  226. '_bx_messenger_upload_is_complete',
  227. '_bx_messenger_upload_cancelled',
  228. '_bx_messenger_uploading_file',
  229. '_bx_messenger_invalid_server_response',
  230. '_bx_messenger_uploading_remove_button',
  231. '_bx_messenger_file_is_too_large_error',
  232. '_bx_messenger_file_is_too_large_error_details',
  233. '_bx_messenger_file_type_is_not_allowed',
  234. '_bx_messenger_empty_history',
  235. '_bx_messenger_create_talk_confirm'
  236. ));
  237. }
  238. private function getJotMenuCode($iJotId){
  239. $CNF = &$this->_oConfig->CNF;
  240. $oMenu = BxTemplMenu::getObjectInstance($CNF['OBJECT_MENU_JOT_MENU']);
  241. $oMenu->setContentId($iJotId);
  242. foreach($CNF['JOT-MENU-TO-SHOW'] as &$sName)
  243. $aItems['bx_repeat:items'][] = $oMenu->getMenuItemByName($sName);
  244. $aItems['jot_menu'] = $oMenu->getCode();
  245. return $this->parseHtmlByName('jot-menu.html', $aItems);
  246. }
  247. private function getFileMenuCode($iFileId, $bAllowedDelete){
  248. $CNF = &$this->_oConfig->CNF;
  249. $oStorage = new BxMessengerStorage($CNF['OBJECT_STORAGE']);
  250. $aFile = $oStorage->getFile($iFileId);
  251. $aMenuItems = [
  252. [
  253. 'onclick' => "{$CNF['JSMain']}.downloadFile({$iFileId})",
  254. 'href' => $this->_oConfig->getBaseUri() . "download_file/{$iFileId}",
  255. 'attrs' => 'download="' . $aFile[$CNF['FIELD_ST_NAME']] . '"',
  256. 'title' => _t('_bx_messenger_file_download'),
  257. 'icon' => 'download'
  258. ],
  259. [
  260. 'permissions' => true,
  261. 'href' => 'javascript:void(0)',
  262. 'attrs' => '',
  263. 'onclick' => "{$CNF['JSMain']}.removeFile(this, {$iFileId})",
  264. 'title' => _t('_bx_messenger_upload_delete'),
  265. 'icon' => 'trash'
  266. ],
  267. ];
  268. $aVars = [];
  269. foreach ($aMenuItems as &$aItem) {
  270. if (isset($aItem['permissions']) && !$bAllowedDelete)
  271. continue;
  272. $aVars['bx_repeat:menu'][] = $aItem;
  273. }
  274. return $this->parseHtmlByName('file-menu.html', $aVars);
  275. }
  276. /**
  277. * Returns right side file's menu in talk history. Allows to remove or download the file
  278. *@param int $iFileId file id in storage table
  279. *@param boolean $bIsDeleteAllowed is the vendor of the file
  280. *@return string html
  281. */
  282. public function getFileMenu($iFileId, $bIsDeleteAllowed = false){
  283. return $this -> getFileMenuCode($iFileId, $bIsDeleteAllowed);
  284. }
  285. /**
  286. * Main function to build post message block for any page
  287. * @param int $iProfileId logged member id
  288. * @param int $iLotId id of conversation. It can be empty if new talk
  289. * @param int $iJotId id of the message in history
  290. * @param bool $bIsBlockVersion
  291. * @return array content and title of the block
  292. */
  293. public function getTalkBlock($iProfileId, $iLotId = BX_IM_EMPTY, $iJotId = BX_IM_EMPTY, $bIsBlockVersion = false){
  294. $aData = [
  295. 'header' => $this->getTalkHeader($iLotId, $iProfileId, $bIsBlockVersion),
  296. 'history' => $this->getHistory($iProfileId, $iLotId, $iJotId)
  297. ];
  298. return bx_is_api() ? $aData : $this -> parseHtmlByName('talk.html', array(
  299. 'header' => $this->getTalkHeader($iLotId, $iProfileId, $bIsBlockVersion),
  300. 'top_area'=> $this->getHistoryTopArea(),
  301. 'history' => $this->getHistory($iProfileId, $iLotId, $iJotId),
  302. 'text_area' => $this->getTextArea($iProfileId, $iLotId)
  303. ));
  304. }
  305. public function getTalkBlockByUserName($iViewer, $iProfileId){
  306. return $this -> parseHtmlByName('talk.html', array(
  307. 'header' => $this->getTalkHeaderForUsername($iViewer, $iProfileId),
  308. 'top_area'=> $this->getHistoryTopArea(),
  309. 'history' => $this-> getHistory($iViewer),
  310. 'text_area' => $this->getTextArea($iViewer)
  311. ));
  312. }
  313. public function getTalkHeaderForUsername($iViewer, $iProfileId, $bWrap = true){
  314. $oViewer = $this -> getObjectUser($iViewer);
  315. $oProfile = $this -> getObjectUser($iProfileId);
  316. if (!$oProfile || !$oViewer)
  317. return '';
  318. return $bWrap ? $this -> parseHtmlByName('talk-header.html', array(
  319. 'buttons' => '',
  320. 'back_title' => bx_js_string(_t('_bx_messenger_lots_menu_back_title')),
  321. 'title' => $this->getThumbsWithUsernames($iProfileId),
  322. 'menu_button' => $this -> parseHtmlByName('mobile-menu-button.html', array())
  323. )): $this->getThumbsWithUsernames($iProfileId);
  324. }
  325. public function getThumbsWithUsernames($mixedProfiles){
  326. if (empty($mixedProfiles))
  327. return '';
  328. $aProfiles = $aVars = array();
  329. if (!is_array($mixedProfiles))
  330. $aProfiles[] = (int)$mixedProfiles;
  331. else
  332. $aProfiles = $mixedProfiles;
  333. foreach($aProfiles as &$iProfileId){
  334. $oProfile = $this -> getObjectUser($iProfileId);
  335. if (!$oProfile)
  336. continue;
  337. $sThumb = $oProfile->getThumb();
  338. $bThumb = stripos($sThumb, 'no-picture') === FALSE;
  339. $sDisplayName = $oProfile->getDisplayName();
  340. $aVars['bx_repeat:usernames'][] = array(
  341. 'username' => $sDisplayName,
  342. 'bx_if:avatars' => array(
  343. 'condition' => $bThumb,
  344. 'content' => array(
  345. 'thumb' => $sThumb,
  346. 'title' => $sDisplayName,
  347. )
  348. ),
  349. 'bx_if:letters' => array(
  350. 'condition' => !$bThumb,
  351. 'content' => array(
  352. 'color' => implode(', ', BxDolTemplate::getColorCode($iProfileId, 1.0)),
  353. 'title' => $sDisplayName,
  354. 'letter' => mb_substr($sDisplayName, 0, 1)
  355. )
  356. )
  357. );
  358. }
  359. return $this -> parseHtmlByName('thumb-usernames.html', $aVars);
  360. }
  361. /**
  362. * @param integer $iLotId Talk's id
  363. * @param integer $iProfileId Viewer id
  364. * @param bool $bIsBlockVersion indicates if it is Block Messenger version
  365. * @return false|string
  366. */
  367. public function getTalkHeader($iLotId, $iProfileId, $bIsBlockVersion = false, $isArray = false){
  368. $CNF = &$this->_oConfig->CNF;
  369. $aLotInfo = array();
  370. if ($iLotId)
  371. $aLotInfo = $this -> _oDb -> getLotInfoById($iLotId);
  372. $sTitle = _t('_bx_messenger_page_block_title');
  373. if (!empty($aLotInfo))
  374. {
  375. if ($aLotInfo[$CNF['FIELD_TITLE']])
  376. $sTitle = $aLotInfo[$CNF['FIELD_TITLE']];
  377. if (!$bIsBlockVersion && $this->_oDb->isLinkedTitle($aLotInfo[$CNF['FIELD_TYPE']]))
  378. $sTitle = _t('_bx_messenger_linked_title', '<a href ="' . $this->_oConfig->getPageLink($aLotInfo[$CNF['FIELD_URL']]) . '">' . $sTitle . '</a>');
  379. else if (!empty($aLotInfo[$CNF['FIELD_TITLE']]))
  380. $sTitle = _t($aLotInfo[$CNF['FIELD_TITLE']]);
  381. else if ($aLotInfo[$CNF['FIELD_TYPE']] == BX_IM_TYPE_PRIVATE)
  382. $sTitle = $this -> getParticipantsNames($iProfileId, $iLotId);
  383. if ($aLotInfo[$CNF['FIELD_CLASS']] === BX_MSG_TALK_CLASS_MARKET) {
  384. $aParticipants = $this->_oDb->getParticipantsList($iLotId, true, $iProfileId);
  385. if (count($aParticipants) == 1) {
  386. $sOpponent = BxDolProfile::getInstance(current($aParticipants))->getDisplayName();
  387. $sTitle = $this->_oConfig->replaceConstant(_t('_bx_messenger_talk_types_market_title'), array('opponent' => $sOpponent));
  388. }
  389. }
  390. }
  391. $aVars = [
  392. 'buttons' => $this->getTalkHeaderButtons($iLotId, $bIsBlockVersion),
  393. 'title' => $sTitle,
  394. 'menu_button' => !$bIsBlockVersion ? $this->parseHtmlByName('mobile-menu-button.html', []) : ''
  395. ];
  396. return $isArray || bx_is_api() ? $aVars : $this -> parseHtmlByName('talk-header.html', $aVars);
  397. }
  398. public function getHistoryTopArea($sContent = ''){
  399. return $this -> parseHtmlByName('history-top-area.html', ['content' => $sContent]);
  400. }
  401. public function getThreadTalkHeader($iProfileId, $iJotId){
  402. $CNF = &$this->_oConfig->CNF;
  403. $aParentLotInfo = $this->_oDb->getLotByJotId($iJotId);
  404. if (empty($aParentLotInfo))
  405. return '';
  406. $iLotId = $aParentLotInfo[$CNF['FIELD_ID']];
  407. $sTitle = $this -> getParticipantsNames($iProfileId, $aParentLotInfo[$CNF['FIELD_ID']]);
  408. $aVars = array(
  409. 'buttons' => $this->getTalkHeaderButtons($iLotId, false),
  410. 'title' => $sTitle,
  411. 'menu_button' => $this->parseHtmlByName('mobile-menu-button.html', array())
  412. );
  413. return $this -> parseHtmlByName('talk-thread-header.html', $aVars);
  414. }
  415. public function getTalkHeaderButtons($iLotId, $bIsBlockVersion = false){
  416. $CNF = &$this->_oConfig->CNF;
  417. $oMenu = BxTemplMenu::getObjectInstance($CNF['OBJECT_MENU_ACTIONS_TALK_MENU']);
  418. $oMenu->setMessengerType($bIsBlockVersion);
  419. $oMenu->setTemplateById(BX_DB_MENU_TEMPLATE_TABS);
  420. $oMenu->setContentId($iLotId);
  421. return $oMenu->getCode();
  422. }
  423. /**
  424. * Create top of the block with participants names and statuses
  425. *@param int $iProfileId logged member id
  426. *@param int $iLotId id of conversation. It can be empty if new talk
  427. *@return string HTML code
  428. */
  429. public function getParticipantsNames($iProfileId, $iLotId){
  430. $aNickNames = array();
  431. $aParticipantsList = $this->_oDb->getParticipantsList($iLotId, true, $iProfileId);
  432. if (empty($aParticipantsList))
  433. return '';
  434. $iCount = count($aParticipantsList);
  435. $aParticipantsList = array_slice($aParticipantsList, 0, $this->_oConfig->CNF['PARAM_ICONS_NUMBER']);
  436. if (count($aParticipantsList) == 1)
  437. {
  438. $oProfile = $this -> getObjectUser($aParticipantsList[0]);
  439. if ($oProfile)
  440. {
  441. $aNickNames['bx_repeat:users'][] = array(
  442. 'profile_username' => $oProfile -> getUrl(),
  443. 'username' => $oProfile -> getDisplayName(),
  444. );
  445. }
  446. $sCode = $this -> parseHtmlByName('status_usernames.html', $aNickNames);
  447. }
  448. else
  449. {
  450. foreach($aParticipantsList as $iParticipant)
  451. {
  452. $oProfile = $this -> getObjectUser($iParticipant);
  453. if ($oProfile)
  454. $aNickNames[] = $oProfile->getDisplayName();
  455. }
  456. $sOthers = $iCount > (int)$this -> _oConfig -> CNF['PARAM_ICONS_NUMBER'] ? _t('_bx_messenger_lot_title_participants_number', $iCount - (int)$this -> _oConfig -> CNF['PARAM_ICONS_NUMBER']) : '';
  457. $sCode = $this -> parseHtmlByName('simple_usernames.html', array('usernames' => implode(', ', $aNickNames) . " {$sOthers}"));
  458. }
  459. return $sCode;
  460. }
  461. function getProfileItem($iProfileId){
  462. $oProfile = $this -> getObjectUser($iProfileId);
  463. if (!$oProfile)
  464. return false;
  465. $sThumb = $oProfile->getThumb();
  466. $bThumb = stripos($sThumb, 'no-picture') === FALSE;
  467. $sDisplayName = $oProfile->getDisplayName();
  468. $iUserId = $oProfile -> id();
  469. return [
  470. 'name' => $sDisplayName,
  471. 'id' => $iUserId,
  472. 'bx_if:avatars' => array(
  473. 'condition' => $bThumb,
  474. 'content' => array(
  475. 'thumb' => $sThumb,
  476. 'title' => $sDisplayName,
  477. )
  478. ),
  479. 'bx_if:letters' => array(
  480. 'condition' => !$bThumb,
  481. 'content' => array(
  482. 'color' => implode(', ', BxDolTemplate::getColorCode($iUserId, 1.0)),
  483. 'title' => $sDisplayName,
  484. 'letter' => mb_substr($sDisplayName, 0, 1)
  485. )
  486. )
  487. ];
  488. }
  489. function getProfilesListWithDesign($iLotId = 0, $aProfilesList = []){
  490. $aProfilesList = empty($aProfilesList) && $iLotId ? $this->_oDb->getParticipantsList($iLotId) : $aProfilesList;
  491. if (empty($aProfilesList))
  492. return '';
  493. $sProfilesList = '';
  494. foreach($aProfilesList as &$iValue) {
  495. if (!($aProfile = $this->getProfileItem($iValue)))
  496. continue;
  497. $sProfilesList .= $this->parseHtmlByName('edit-profiles-list-item.html', $aProfile);
  498. }
  499. return $sProfilesList;
  500. }
  501. public function _getBroadcastFields()
  502. {
  503. $CNF = &$this->_oConfig->CNF;
  504. if(!isset($CNF['OBJECT_FORM_FILTER']))
  505. return [];
  506. $oForm = BxDolForm::getObjectInstance($CNF['OBJECT_FORM_FILTER'], $CNF['OBJECT_FORM_FILTER_DISPLAY'], $this);
  507. if(!$oForm)
  508. return [];
  509. return $oForm->aInputs;
  510. }
  511. function getNotificationFormData(){
  512. $aNotifFields = [];
  513. if ($aNotifications = $this->_oDb->getNotificationsSettings($this->_oConfig->getName() . '_' . BX_MSG_NTFS_BROADCAST)) {
  514. $aNotifValues = [];
  515. foreach ($aNotifications as $sKey => $iValue) {
  516. if ((int)$iValue)
  517. $aNotifValues[$sKey] = _t("_bx_messenger_broadcast_field_{$sKey}");
  518. }
  519. if (!empty($aNotifValues)){
  520. $aNotifFields['notifications'] = [
  521. 'type' => 'checkbox_set',
  522. 'skip' => true,
  523. 'caption' => _t('_bx_messenger_broadcast_field_notify'),
  524. 'info' => _t('_bx_messenger_broadcast_field_notify_info'),
  525. 'name' => 'notify_by',
  526. 'attrs' => ['class' => 'flex items-center'],
  527. 'attrs_wrapper' => ['class' => 'flex items-center'],
  528. 'value' => array_keys($aNotifValues),
  529. 'values' => $aNotifValues
  530. ];
  531. }
  532. }
  533. return $aNotifFields;
  534. }
  535. function getCreateListArea($iLotId = 0, $mixedProfiles = [], $bEmptyDefaultList = false){
  536. $sContent = '';
  537. $CNF = &$this->_oConfig->CNF;
  538. if ($this->_oConfig->CNF['SHOW-FRIENDS'] && !$bEmptyDefaultList)
  539. $sContent = $this->getFriendsList();
  540. $sProfilesList = $iLotId ? $this->getProfilesListWithDesign($iLotId, $mixedProfiles) : '';
  541. $oCreateMenu = BxTemplMenu::getObjectInstance($CNF['OBJECT_MENU_CREATE_CONVO_MENU']);
  542. return $this->parseHtmlByName('create-list.html', [
  543. 'items' => $sContent,
  544. 'menu_button' => $this->parseHtmlByName('mobile-menu-button.html', []),
  545. 'profiles_list' => $sProfilesList,
  546. 'bx_if:broadcast' => [
  547. 'condition' => $this->_oConfig->isAllowedAction(BX_MSG_ACTION_CREATE_BROADCASTS) === true && !$iLotId,
  548. 'content' => [
  549. 'convo_menu' => $oCreateMenu !== FALSE ? $oCreateMenu->getCode() : '',
  550. ],
  551. ],
  552. 'bx_if:edit' => [
  553. 'condition' => $iLotId,
  554. 'content' => [ 'id' => $iLotId ]
  555. ]
  556. ]);
  557. }
  558. /**
  559. * Search friends function which shows fiends only if member have no any talks yet
  560. *@param string $sParam keywords
  561. *@return string html code
  562. */
  563. function getFriendsList($sParam = '', $bListAsArray = false){
  564. $iLimit = (int)$this->_oConfig->CNF['PARAM_FRIENDS_NUM_BY_DEFAULT'] ?? 5;
  565. $sContent = MsgBox(_t('_Empty'));
  566. if (!$this->_oConfig->CNF['SHOW-FRIENDS'])
  567. return $sContent;
  568. $aFriends = [];
  569. if ($sParam)
  570. {
  571. $aUsers = BxDolService::call('system', 'profiles_search', array($sParam, $iLimit), 'TemplServiceProfiles');
  572. if (empty($aUsers))
  573. return $sContent;
  574. foreach($aUsers as &$aValue)
  575. $aFriends[] = $aValue['value'];
  576. }
  577. else
  578. {
  579. bx_import('BxDolConnection');
  580. $oConnection = BxDolConnection::getObjectInstance('sys_profiles_friends');
  581. if (!$oConnection || !$aFriends = $oConnection->getConnectionsAsArray('content', bx_get_logged_profile_id(), 0, false, 0, $iLimit + 1, BX_CONNECTIONS_ORDER_ADDED_DESC))
  582. return $sContent;
  583. }
  584. return $this->getProfilesListPreviewForCreateTalkArea($aFriends, !$bListAsArray);
  585. }
  586. function getProfilesListPreviewForCreateTalkArea($aList, $bWrap = true){
  587. $aItems = [];
  588. foreach($aList as &$iValue){
  589. if (!($oProfile = $this -> getObjectUser($iValue)))
  590. continue;
  591. $sThumb = $oProfile->getThumb();
  592. $bThumb = stripos($sThumb, 'no-picture') === FALSE;
  593. $sDisplayName = $oProfile->getDisplayName();
  594. $aItems[] = array(
  595. 'name' => $sDisplayName,
  596. 'id' => $oProfile -> id(),
  597. 'bx_if:avatars' => array(
  598. 'condition' => $bThumb,
  599. 'content' => array(
  600. 'thumb' => $sThumb,
  601. 'title' => $sDisplayName,
  602. )
  603. ),
  604. 'bx_if:letters' => array(
  605. 'condition' => !$bThumb,
  606. 'content' => array(
  607. 'color' => implode(', ', BxDolTemplate::getColorCode($iValue, 1.0)),
  608. 'title' => $sDisplayName,
  609. 'letter' => mb_substr($sDisplayName, 0, 1)
  610. )
  611. )
  612. );
  613. }
  614. if (!$bWrap)
  615. return $aItems;
  616. return $this -> parseHtmlByName('profiles-list.html', ['bx_repeat:profiles' => $aItems]);
  617. }
  618. /**
  619. * List of Lots (left side block content)
  620. *@param int $iProfileId logged member id
  621. *@param array $aLots list of lost to show
  622. *@param boolean $bShowTime display time(last message) in the right side of the lot
  623. *@return string html code
  624. */
  625. function getLotsPreview($iProfileId, $aLots, $bShowTime = true){
  626. $CNF = &$this->_oConfig->CNF;
  627. $sContent = '';
  628. $aContent = [];
  629. foreach($aLots as &$aLot) {
  630. $aVars = [];
  631. $aParticipantsList = $this -> _oDb -> getParticipantsList($aLot[$CNF['FIELD_ID']], true, $iProfileId);
  632. $iParticipantsCount = count($aParticipantsList);
  633. $aParticipantsList = $iParticipantsCount ? array_slice($aParticipantsList, 0, $CNF['PARAM_ICONS_NUMBER']) : [$iProfileId];
  634. $oAuthor = null;
  635. $sGroupName = $sModuleTitle = $sThumb = $sModuleIcon = '';
  636. $bIsGroupTalk = isset($aLot[$CNF['FMGL_GROUP_ID']]) && (int)$aLot[$CNF['FMGL_GROUP_ID']];
  637. if ($bIsGroupTalk) {
  638. $aGroupInfo = $this->_oDb->getGroup($aLot[$CNF['FMGL_GROUP_ID']]);
  639. if ($aGroupInfo[$CNF['FMG_MODULE']] !== BX_MSG_TALK_TYPE_PAGES) {
  640. $oGroupProfile = BxDolProfile::getInstance($aGroupInfo[$CNF['FMG_PROFILE_ID']]);
  641. if ($oGroupProfile) {
  642. $sThumb = $oGroupProfile->getIcon();
  643. if (!$sThumb)
  644. $sThumb = bx_srv($aGroupInfo[$CNF['FMG_MODULE']], 'get_thumb', [$oGroupProfile->getContentId()]);
  645. $aVars['author_module'] = $sModule = $oGroupProfile->getModule();
  646. $sModuleTitle = _t('_' . $oGroupProfile->getModule());
  647. $aGroupItemInfo = BxDolService::call($oGroupProfile->getModule(), 'get_info', [$oGroupProfile->getContentId(), false]);
  648. if (!empty($aGroupItemInfo)) {
  649. $oModule = BxDolModule::getInstance($aGroupInfo[$CNF['FMG_MODULE']]);
  650. if ($oModule->_oConfig) {
  651. $oMCNF = $oModule->_oConfig->CNF;
  652. $sGroupName = isset($aGroupItemInfo[$oMCNF['FIELD_TITLE']]) ? $aGroupItemInfo[$oMCNF['FIELD_TITLE']] : '';
  653. }
  654. }
  655. }
  656. if (!$sThumb)
  657. $sThumb = BxDolModule::getInstance($aGroupInfo[$CNF['FMG_MODULE']])->_oTemplate->getImageUrl('no-picture.svg');
  658. $sModuleIcon = $sThumb;
  659. } else
  660. {
  661. $sModuleIcon = $this->_oConfig->getPageIcon();
  662. $sThumb = $sModuleIcon;
  663. $aVars['author_module'] = 'bx_pages';
  664. $sModuleTitle = _t('_bx_messenger_pages');
  665. $aUrl = array();
  666. parse_str($aGroupInfo[$CNF['FMG_URL']], $aUrl);
  667. if (isset($aUrl['i']) && ($oPage = BxTemplPage::getObjectInstanceByURI($aUrl['i']))) {
  668. $aPageObject = $oPage->getObject();
  669. $sGroupName = _t($aPageObject['title']);
  670. }
  671. }
  672. $aVars['bx_repeat:avatars'][] = [
  673. 'bx_if:avatars' => [
  674. 'condition' => true,
  675. 'content' => [
  676. 'title' => $sModuleTitle,
  677. 'thumb' => $sModuleIcon,
  678. ]
  679. ],
  680. 'bx_if:letters' => [
  681. 'condition' => false,
  682. 'content' => []
  683. ]
  684. ];
  685. }
  686. else
  687. {
  688. $oAuthor = $this->getObjectUser(
  689. $aLot[$CNF['FIELD_TYPE']] == BX_IM_TYPE_BROADCAST || $iParticipantsCount !== 1
  690. ? $aLot[$CNF['FIELD_AUTHOR']]
  691. : current($aParticipantsList)
  692. );
  693. $sThumb = $oAuthor->getThumb();
  694. $bThumb = stripos($sThumb, 'no-picture') === FALSE;
  695. $sTitle = $oAuthor->getDisplayName();
  696. $aVars['bx_repeat:avatars'][] = array(
  697. 'bx_if:avatars' => array(
  698. 'condition' => $bThumb,
  699. 'content' => array(
  700. 'title' => $sTitle,
  701. 'thumb' => $sThumb,
  702. )
  703. ),
  704. 'bx_if:letters' => array(
  705. 'condition' => !$bThumb,
  706. 'content' => array(
  707. 'color' => implode(', ', BxDolTemplate::getColorCode($aLot[$CNF['FIELD_AUTHOR']], 1.0)),
  708. 'letter' => mb_substr($sTitle, 0, 1)
  709. )
  710. )
  711. );
  712. }
  713. if (!$CNF['HIDE-PARTS']) {
  714. $aLastAnsweredParticipants = $this->_oDb->getLatestJotsAuthors($aLot[$CNF['FIELD_ID']]);
  715. $aParticipantsViewList = [];
  716. foreach ($aLastAnsweredParticipants as $iParticipant) {
  717. $oProfile = $this->getObjectUser($iParticipant);
  718. if ($oProfile) {
  719. $sThumb = $oProfile->getThumb();
  720. $bThumb = stripos($sThumb, 'no-picture') === FALSE;
  721. $sDisplayName = $oProfile->getDisplayName();
  722. $aParticipantsViewList[] = array(
  723. 'bx_if:avatars' => array(
  724. 'condition' => $bThumb,
  725. 'content' => array(
  726. 'title' => $sDisplayName,
  727. 'thumb' => $sThumb,
  728. )
  729. ),
  730. 'bx_if:letters' => array(
  731. 'condition' => !$bThumb,
  732. 'content' => array(
  733. 'color' => implode(', ', BxDolTemplate::getColorCode($iParticipant, 1.0)),
  734. 'letter' => mb_substr($sDisplayName, 0, 1)
  735. )
  736. )
  737. );
  738. }
  739. }
  740. $aVars['bx_if:parts_list'] = ['condition' => true, 'content' => ['bx_repeat:participants' => $aParticipantsViewList]];
  741. } else
  742. $aVars['bx_if:parts_list'] = ['condition' => false, 'content' => []];
  743. if (!empty($aLot[$CNF['FIELD_TITLE']]))
  744. $sTitle = _t($aLot[$CNF['FIELD_TITLE']]);
  745. else
  746. {
  747. $aNickNamesTitles = [];
  748. foreach ($aParticipantsList as &$iPartId)
  749. $aNickNamesTitles[] = $this->getObjectUser($iPartId)->getDisplayName();
  750. if ($iParticipantsCount > 3)
  751. $sTitle = implode(', ', array_slice($aNickNamesTitles, 0, $CNF['PARAM_ICONS_NUMBER'])) . '...';
  752. else
  753. $sTitle = implode(', ', $aNickNamesTitles);
  754. }
  755. $sStatus = $sCount = '';
  756. if ($iParticipantsCount <= 1 && $oAuthor && !$bIsGroupTalk){
  757. $sStatus = (method_exists($oAuthor, 'isOnline') ? $oAuthor -> isOnline() : false) ?
  758. $this -> getOnlineStatus($oAuthor-> id(), 1) :
  759. $this -> getOnlineStatus($oAuthor-> id(), 0) ;
  760. }
  761. else
  762. $sCount = '<div class="bx-def-label bx-def-font-middle status">' . $iParticipantsCount .'</div>';
  763. $aVars[$CNF['FIELD_ID']] = $aLot[$CNF['FIELD_ID']];
  764. $aVars[$CNF['FIELD_TITLE']] = $sTitle;
  765. $aVars['number'] = $sCount;
  766. $aVars['status'] = $sStatus;
  767. $aLatestJots = $this -> _oDb -> getLatestJot($aLot[$CNF['FIELD_ID']]);
  768. $aVars[$CNF['FIELD_MESSAGE']] = $aVars['sender_username'] = '';
  769. $iTime = bx_time_js($aLot[$CNF['FIELD_ADDED']], BX_FORMAT_DATE);
  770. if (bx_is_api()) {
  771. $iTime = $aLot[$CNF['FIELD_ADDED']];
  772. }
  773. $aVars[$CNF['FIELD_AUTHOR']] = $aLot[$CNF['FIELD_AUTHOR']];
  774. $sMessage = '';
  775. if (!empty($aLatestJots)) {
  776. $aAttachType = [];
  777. if ($aLatestJots[$CNF['FIELD_MESSAGE_AT_TYPE']])
  778. $aAttachType = array($aLatestJots[$CNF['FIELD_MESSAGE_AT_TYPE']] => $aLatestJots[$CNF['FIELD_MESSAGE_AT']]);
  779. else if ($aLatestJots[$CNF['FIELD_MESSAGE_AT']])
  780. $aAttachType = @unserialize($aLatestJots[$CNF['FIELD_MESSAGE_AT']]);
  781. if (isset($aLatestJots[$CNF['FIELD_MESSAGE']])) {
  782. $sMessage = preg_replace( '/<br\W*?\/>|\n/', " ", $aLatestJots[$CNF['FIELD_MESSAGE']]);
  783. $sMessage = html2txt($sMessage);
  784. if (isset($aAttachType[BX_ATT_TYPE_REPOST]))
  785. {
  786. $sMessage = $this -> _oConfig -> cleanRepostLinks($sMessage, $aAttachType[BX_ATT_TYPE_REPOST]);
  787. $sMessage = $sMessage ? $sMessage : _t('_bx_messenger_repost_message');
  788. }
  789. $sMessage = BxTemplFunctions::getInstance()->getStringWithLimitedLength($sMessage, $CNF['MAX_PREV_JOTS_SYMBOLS']);
  790. }
  791. if (!$sMessage){
  792. if (isset($aAttachType[BX_ATT_TYPE_FILES]))
  793. $sMessage = _t('_bx_messenger_attached_files_message', $this -> _oDb -> getJotFiles($aLatestJots[$CNF['FIELD_MESSAGE_ID']], true));
  794. if (isset($aAttachType[BX_ATT_TYPE_GIPHY]))
  795. $sMessage = _t('_bx_messenger_attached_giphy_message');
  796. if ((int)$aLatestJots[$CNF['FIELD_MESSAGE_VIDEOC']])
  797. $sMessage = _t('_bx_messenger_lots_menu_video_conf_start');
  798. }
  799. if ($oSender = $this -> getObjectUser($aLatestJots[$CNF['FIELD_MESSAGE_AUTHOR']]))
  800. {
  801. $aVars['sender_username'] = $oSender -> id() == $iProfileId ? _t('_bx_messenger_you_username_title') : $oSender -> getDisplayName();
  802. $sModuleIcon = $sModuleIcon ? $sModuleIcon : $oSender -> getIcon();
  803. }
  804. $iTime = bx_is_api() ? $aLatestJots[$CNF['FIELD_MESSAGE_ADDED']] : bx_time_js($aLatestJots[$CNF['FIELD_MESSAGE_ADDED']], BX_FORMAT_DATE);
  805. }
  806. $iUnreadJotsCount = $this->_oDb->getNewJots($iProfileId, $aLot[$CNF['FIELD_ID']], true);
  807. $aVars['class'] = $iUnreadJotsCount ? 'unread-lot' : '';
  808. $aVars['title_class'] = $iUnreadJotsCount ? 'bx-def-font-extrabold' : '';
  809. $aVars['message_class'] = $iUnreadJotsCount ? 'bx-def-font-semibold' : '';
  810. $aVars['view_in_chat'] = '';
  811. $aVars['bubble_class'] = $iUnreadJotsCount ? '' : 'hidden';
  812. $aVars['count'] = $iUnreadJotsCount;
  813. $aVars['participants'] = $aLot[$CNF['FIELD_PARTICIPANTS']];
  814. $aVars['bx_if:user'] = [
  815. 'condition' => $sModuleIcon,
  816. 'content' => [
  817. 'talk_type' => $bIsGroupTalk ? $sModuleTitle : $aVars['sender_username'],
  818. 'icon' => $sModuleIcon,
  819. 'message' => $bIsGroupTalk && $sGroupName ? $sGroupName : $sMessage
  820. ]
  821. ];
  822. $aVars['bx_if:timer'] = ['condition' => $bShowTime, 'content' => [ 'time' => $iTime ]];
  823. $oTemplate = &$this;
  824. bx_alert($this->_oConfig->getObject('alert'), 'talk_preview_data', $aLot[$CNF['FIELD_ID']], $aLot[$CNF['FIELD_ID']], [
  825. 'vars' => &$aVars,
  826. 'template' => &$oTemplate,
  827. 'talk' => $aLot,
  828. ]);
  829. $aContent[] = $aVars;
  830. $sContent .= $oTemplate->parseHtmlByName('lots-briefs.html', $aVars);
  831. }
  832. return bx_is_api() ? $aContent : $sContent;
  833. }
  834. /**
  835. * Builds top talk area with Profiles names and Statuses
  836. *@param int $iProfileId logget member id
  837. *@param int $iStatus member status
  838. *@return string html code
  839. */
  840. private function getOnlineStatus($iProfileId, $iStatus){
  841. switch($iStatus){
  842. case 0:
  843. $sTitle = _t('_bx_messenger_offline');
  844. $sClass = 'offline';
  845. break;
  846. case 2:
  847. $sTitle = _t('_bx_messenger_away');
  848. $sClass = 'away';
  849. break;
  850. default:
  851. $sTitle = _t('_bx_messenger_online');
  852. $sClass = 'online';
  853. }
  854. return !bx_is_api() ? $this -> parseHtmlByName('online-status.html', array(
  855. 'id' => (int)$iProfileId,
  856. 'title' => $sTitle,
  857. 'class' => $sClass
  858. )) : $sClass ;
  859. }
  860. /**
  861. * Returns html with users show viewed the message
  862. * @param $iJotId int message id
  863. * @param $iExcludeProfile int exclude defined profile id from the list
  864. * @return bool|string
  865. */
  866. public function getViewedJotProfiles($iJotId, $iExcludeProfile = 0){
  867. $CNF = $this->_oConfig->CNF;
  868. $aJotInfo = $this -> _oDb -> getJotById($iJotId);
  869. if (empty($aJotInfo))
  870. return '';
  871. $aResult = $aParticipants = $this -> _oDb -> getParticipantsList($aJotInfo[$CNF['FIELD_MESSAGE_FK']], true);
  872. if ($CNF['MAX_VIEWS_PARTS_NUMBER'] < count($aResult))
  873. return '';
  874. $aUnreadProfiles = $this->_oDb->getForWhomJotIsNew($aJotInfo[$CNF['FIELD_MESSAGE_FK']], $iJotId);
  875. if (!empty($aUnreadProfiles))
  876. $aResult = array_diff($aParticipants, $aUnreadProfiles);
  877. else
  878. $aResult = $aParticipants;
  879. $aIcons = array();
  880. foreach($aResult as &$iProfileId) {
  881. if ($iExcludeProfile && +$iExcludeProfile == +$iProfileId)
  882. continue;
  883. if ($oProfile = BxDolProfile::getInstance($iProfileId))
  884. $aIcons[] = array(
  885. 'id' => $iProfileId,
  886. 'icon' => $oProfile->getIcon(),
  887. 'name' => $oProfile->getDisplayName(),
  888. );
  889. }
  890. return $this -> parseHtmlByName('viewed.html', array(
  891. 'bx_repeat:viewed' => $aIcons
  892. ));
  893. }
  894. /**
  895. * Get jots list by specified criteria
  896. *@param int $iProfileId logged member id
  897. *@param array $aParams options
  898. * - int $iLotId
  899. * - string $sUrl of the lot block
  900. * - int $iStart jot's id from which to load the messages
  901. * - string $sLoad type of the load (new jots or prev from history)
  902. * - int $iLimit number of jots
  903. * - boolean $bDisplay make jots visible before loading
  904. * - string html code
  905. * - boolean load history from defined jot id and to select it
  906. *@return array HTML code
  907. */
  908. public function getJotsOfLot($iProfileId, $aParams){
  909. $CNF = &$this -> _oConfig -> CNF;
  910. $iLotId = isset($aParams['lot_id']) ? (int)$aParams['lot_id'] : BX_IM_EMPTY;
  911. $sUrl = isset($aParams['url']) ? $aParams['url'] : BX_IM_EMPTY_URL;
  912. $iStart = isset($aParams['start']) ? (int)$aParams['start'] : BX_IM_EMPTY;
  913. $sLoad = isset($aParams['load']) ? $aParams['load'] : 'new';
  914. $iLimit = isset($aParams['limit']) ? (int)$aParams['limit'] : BX_IM_EMPTY;
  915. $bDisplay = isset($aParams['display']) ? (bool)$aParams['display'] : false;
  916. $bSelectJot = isset($aParams['select']) ? (bool)$aParams['select'] : false;
  917. $bMarkAsRead = isset($aParams['read']) && $aParams['read'] === true;
  918. $bShowViews = isset($aParams['views']);
  919. $bDynamic = isset($aParams['dynamic']);
  920. $iParent = isset($aParams['parent']) && $aParams['parent'] ? $aParams['parent'] : 0;
  921. $sArea = isset($aParams['area']) ? $aParams['area'] : 0;
  922. $aResult = array('content' => '');
  923. $aLotInfo = $this -> _oDb -> getLotByIdOrUrl($iLotId, $sUrl, $iProfileId);
  924. if (empty($aLotInfo))
  925. return bx_is_api() ? [] : $aResult;
  926. if ($bSelectJot && $iStart){
  927. $aStartMiddleJot = $this -> _oDb -> getJotsByLotId([
  928. 'lot' => $aLotInfo[$CNF['FIELD_ID']],
  929. 'start' => $iStart,
  930. 'mode' => 'prev',
  931. 'area' => $sArea,
  932. 'limit' => (int)$CNF['MAX_JOTS_BY_DEFAULT']/2]);
  933. if (!empty($aStartMiddleJot))
  934. $iStart = current($aStartMiddleJot)[$CNF['FIELD_MESSAGE_ID']];
  935. }
  936. $aJots = $this->_oDb->getJotsByLotId(['lot' => $aLotInfo[$CNF['FIELD_ID']],
  937. 'start' => $iStart,
  938. 'mode' => $sLoad,
  939. 'area' => $sArea,
  940. 'limit' => $iLimit,
  941. 'include' => $bSelectJot && $iStart,
  942. 'parent' => $iParent]);
  943. if (bx_is_api())
  944. return $aJots;
  945. if (empty($aJots))
  946. return $aResult;
  947. $iJotCount = count($aJots);
  948. $aVars['bx_repeat:jots'] = array();
  949. $iFirstUnreadJot = $this->_oDb->getFirstUnreadJot($iProfileId, $iLotId);
  950. $iTimeFromToShift = $iPrevAuthor = 0;
  951. foreach($aJots as $iKey => $aJot) {
  952. $oProfile = $this->getObjectUser($aJot[$CNF['FIELD_MESSAGE_AUTHOR']]);
  953. $iJot = $aJot[$CNF['FIELD_MESSAGE_ID']];
  954. $bShowDateSeparator = false;
  955. if (!$iTimeFromToShift || (($iTimeFromToShift + $CNF['DATE-SHIFT']) < $aJot[$CNF['FIELD_MESSAGE_ADDED']])){
  956. $bShowDateSeparator = true;
  957. $iTimeFromToShift = $aJot[$CNF['FIELD_MESSAGE_ADDED']];
  958. }
  959. if ($oProfile) {
  960. $sReply = $sAttachment = $sMessage = '';
  961. $bIsTrash = (int)$aJot[$CNF['FIELD_MESSAGE_TRASH']];
  962. $iIsVC = (int)$aJot[$CNF['FIELD_MESSAGE_VIDEOC']];
  963. $bIsLotAuthor = $this->_oDb->isAuthor($iLotId, $iProfileId);
  964. $isAllowedDelete = $this->_oDb->isAllowedToDeleteJot($aJot[$CNF['FIELD_MESSAGE_ID']], $iProfileId, $aJot[$CNF['FIELD_MESSAGE_AUTHOR']], $aJot[$CNF['FIELD_MESSAGE_FK']]);
  965. if ($bIsTrash || ($iIsVC && !$aJot[$CNF['FIELD_MESSAGE']]))
  966. $sMessage = $this->getMessageIcons($aJot[$CNF['FIELD_MESSAGE_ID']], $bIsTrash ? 'delete' : 'vc', isAdmin() || $bIsLotAuthor);
  967. else
  968. {
  969. if ($aLotInfo[$CNF['FIELD_TYPE']] != BX_IM_TYPE_BROADCAST || ($aLotInfo[$CNF['FIELD_TYPE']] == BX_IM_TYPE_BROADCAST && empty($aJot[$CNF['FIELD_MESSAGE_AT']])))
  970. $sMessage = $this->_oConfig->bx_linkify($aJot[$CNF['FIELD_MESSAGE']]);
  971. if (!empty($aJot[$CNF['FIELD_MESSAGE_AT']])) {
  972. $aAttachments = $this->getAttachment($aJot);
  973. if (!empty($aAttachments[BX_ATT_GROUPS_ATTACH])) {
  974. $sAttachment = $aAttachments[BX_ATT_GROUPS_ATTACH];
  975. $bIsEmpty = false;
  976. bx_alert($this->_oConfig->getObject('alert'), 'attachment_before', $iJot, $iLotId, [
  977. 'is_empty' => &$bIsEmpty,
  978. 'attachment' => &$sAttachment
  979. ]);
  980. if ($bIsEmpty) {
  981. $aVars['bx_repeat:jots'][] = $this->getEmptyMessageTemplate(['attachment' => $sAttachment, 'id' => $iJot]);
  982. if ($bMarkAsRead)
  983. $this->_oDb->readMessage($iJot, $iProfileId);
  984. continue;
  985. }
  986. }
  987. }
  988. if (($iReplyId = (int)$aJot[$CNF['FIELD_MESSAGE_REPLY']]) && ($aReplyJot = $this->_oDb->getJotById($iReplyId))) {
  989. $sReply = $this->parseHtmlByName('reply.html', [
  990. 'id' => $iReplyId,
  991. 'message' => $this->getReplyPreview($iReplyId),
  992. ]);
  993. }
  994. }
  995. $sDisplayName = $oProfile->getDisplayName();
  996. $sThumb = $oProfile->getThumb();
  997. $bThumb = stripos($sThumb, 'no-picture') === FALSE;
  998. $sReactions = $this->getJotReactions($iJot);
  999. $aVars['bx_repeat:jots'][] = [
  1000. 'new' => (int)($iFirstUnreadJot && $iJot >= $iFirstUnreadJot),
  1001. 'immediately' => +$this->_oConfig->CNF['REMOVE_MESSAGE_IMMEDIATELY'],
  1002. 'bx_if:show_author' => array(
  1003. 'condition' => $iPrevAuthor !== $oProfile->id(),
  1004. 'content' => array(
  1005. 'url' => $oProfile->getUrl(),
  1006. 'bx_if:avatars' => array(
  1007. 'condition' => $bThumb,
  1008. 'content' => array(
  1009. 'thumb' => $sThumb,
  1010. 'title' => $sDisplayName,
  1011. )
  1012. ),
  1013. 'bx_if:letters' => array(
  1014. 'condition' => !$bThumb,
  1015. 'content' => array(
  1016. 'color' => implode(', ', BxDolTemplate::getColorCode($aJot[$CNF['FIELD_MESSAGE_AUTHOR']], 1.0)),
  1017. 'letter' => mb_substr($sDisplayName, 0, 1)
  1018. )
  1019. ),
  1020. )
  1021. ),
  1022. 'bx_if:show_title' => array(
  1023. 'condition' => $iPrevAuthor !== $oProfile->id(),
  1024. 'content' => array(
  1025. 'title' => $sDisplayName,
  1026. )
  1027. ),
  1028. 'bx_if:time-separator' => array(
  1029. 'condition' => $bShowDateSeparator,
  1030. 'content' => [
  1031. 'date' => $this-> getDateSeparator($aJot[$CNF['FIELD_MESSAGE_ADDED']]),
  1032. ]
  1033. ),
  1034. 'bx_if:new' => array(
  1035. 'condition' => $iPrevAuthor !== $oProfile->id(),
  1036. 'content' => array()
  1037. ),
  1038. 'id' => $aJot[$CNF['FIELD_MESSAGE_ID']],
  1039. 'message' => preg_replace('/(?:\s*<br *\/?>\s*)+$/', "", $sMessage),
  1040. 'attachment' => $sAttachment,
  1041. 'reply' => $sReply,
  1042. 'my' => (int)$iProfileId === (int)$aJot[$CNF['FIELD_MESSAGE_AUTHOR']] ? 1 : 0,
  1043. 'bx_if:jot_menu' => array(
  1044. 'condition' => $iProfileId && !$bIsTrash,
  1045. 'content' => array(
  1046. 'jot_menu' => $this->getJotMenuCode($iJot)
  1047. )
  1048. ),
  1049. 'icons' => $sMessage ? $this->parseHtmlByName('jot-icons.html', array(
  1050. 'edit_icon' => $aJot[$CNF['FIELD_MESSAGE_EDIT_BY']] && !$bIsTrash ?
  1051. $this->parseHtmlByName('edit-icon.html',
  1052. array(
  1053. 'edit' => _t('_bx_messenger_edit_by',
  1054. bx_process_output($aJot[$CNF['FIELD_MESSAGE_LAST_EDIT']], BX_DATA_DATETIME_TS),
  1055. $this->getObjectUser($aJot[$CNF['FIELD_MESSAGE_EDIT_BY']])->getDisplayName()),
  1056. )
  1057. ) : '',
  1058. 'views' => $bShowViews && ($iJotCount - 1 == $iKey) ? $this->getViewedJotProfiles($iJot, $iProfileId) : '',
  1059. )) : '',
  1060. 'bx_if:show_reactions_area' => array(
  1061. 'condition' => !$bIsTrash,
  1062. 'content' => array(
  1063. 'bx_if:reactions' => array(
  1064. 'condition' => true,
  1065. 'content' => array(
  1066. 'reactions' => $sReactions,
  1067. 'bx_if:reactions_menu' => array(
  1068. 'condition' => $iProfileId,
  1069. 'content' => array(
  1070. 'display' => $sReactions ? 'block' : 'none',
  1071. )
  1072. ),
  1073. )
  1074. ),
  1075. 'bx_if:edit' => array(
  1076. 'condition' => $isAllowedDelete,
  1077. 'content' => array()
  1078. ),
  1079. )
  1080. ),
  1081. 'thread_replies' => $this->getThreadReply($iJot),
  1082. 'display' => !$bDisplay ? 'style="display:none;"' : '',
  1083. 'bx_if:blink-jot' => array(
  1084. 'condition' => $bSelectJot && $aParams['start'] == $iJot,
  1085. 'content' => array()
  1086. ),
  1087. 'display_message' => '',
  1088. 'view_in_chat' => in_array($sArea, $CNF['VIEW-IN-TALKS']) ?
  1089. $this->parseHtmlByName('view-in-chat.html', array('lot' => $iLotId, 'jot' => $iJot)) : "",
  1090. 'message_class' => !$sMessage ? 'hidden' : '',
  1091. ];
  1092. if ($bMarkAsRead)
  1093. $this->_oDb->readMessage($aJot[$CNF['FIELD_MESSAGE_ID']], $iProfileId);
  1094. $iPrevAuthor = $oProfile->id();
  1095. }
  1096. }
  1097. if ($bMarkAsRead)
  1098. $this->_oDb->markNotificationAsRead($iProfileId, $iLotId);
  1099. return ['content' => $this -> parseHtmlByName('jots.html', $aVars),
  1100. 'first_jot' => $sLoad == 'prev' ? $aJots[count($aJots) - 1] : $aJots[0]];
  1101. }
  1102. function getDateSeparator($iDate){
  1103. return $this->parseHtmlByName('date-separator.html', array('date' => $this->_oConfig->getSeparatorTime($iDate)));
  1104. }
  1105. /**
  1106. * Builds left column with content
  1107. *@param int $iProfileId logged member id
  1108. *@return string html code
  1109. */
  1110. public function getLotsList($iProfileId, $iSelectedLotId = 0){
  1111. $CNF = &$this->_oConfig->CNF;
  1112. $aMyLots = $this->_oDb->getMyLots($iProfileId);
  1113. $sContent = MsgBox(_t('_Empty'));
  1114. if (!empty($aMyLots)) {
  1115. if ($iSelectedLotId && array_search($iSelectedLotId, array_column($aMyLots, $CNF['FIELD_ID'])) === false) {
  1116. $aPrependConvo = $this->_oDb->getLotInfoById($iSelectedLotId);
  1117. $aMyLots = array_merge([$aPrependConvo], $aMyLots);
  1118. }
  1119. $sContent = $this->getLotsPreview($iProfileId, $aMyLots);
  1120. }
  1121. $bSimpleMode = $this->_oConfig->CNF['SHOW-SEARCH-BOX'];
  1122. $oMenu = BxTemplMenu::getObjectInstance($CNF['OBJECT_MENU_ACTIONS_TALK_MENU']);
  1123. $aVars = [
  1124. 'items' => $sContent,
  1125. 'custom_class_title' => $bSimpleMode ? 'hidden' : 'block',
  1126. 'custom_class_search' => $bSimpleMode ? 'block' : 'hidden',
  1127. 'search_for_title' => bx_js_string(_t('_bx_messenger_search_for_lost_title')),
  1128. 'bx_repeat:menu' => [['menu_title' => _t("_bx_messenger_lots_type_all"), 'type' => 0, 'count' => '']],
  1129. 'star_icon' => $CNF['STAR_ICON'],
  1130. 'star_color' => $CNF['STAR_BACKGROUND_COLOR'],
  1131. 'bx_if:create' => array(
  1132. 'condition' => $this->_oConfig->isAllowedAction(BX_MSG_ACTION_CREATE_TALKS, $iProfileId) === true,
  1133. 'content' => array(
  1134. 'create_lot_title' => bx_js_string(_t('_bx_messenger_lots_menu_create_lot_title')),
  1135. )
  1136. ),
  1137. 'bx_if:featured' => array(
  1138. 'condition' => $oMenu->isActive('star'),
  1139. 'content' => array(
  1140. 'star_title' => bx_js_string(_t('_bx_messenger_lots_menu_star_title')),
  1141. )
  1142. )
  1143. ];
  1144. return bx_is_api() ? $aVars : $this -> parseHtmlByName('lots-list.html', $aVars);
  1145. }
  1146. /**
  1147. * Create js configuration for the messenger depends on administration settings
  1148. * @param int $iProfileId logged member id
  1149. * @param bool $bBlockVersion
  1150. * @param int $iLotId
  1151. * @param int $iJotId
  1152. * @param int $iPersonToTalk
  1153. * @param int $iType
  1154. * @return string html code
  1155. */
  1156. public function loadConfig($iProfileId, $aParams){
  1157. $CNF = &$this->_oConfig->CNF;
  1158. $aUrlInfo = parse_url(BX_DOL_URL_ROOT);
  1159. $bBlockVersion = isset($aParams['is_block_version']) ? (bool)$aParams['is_block_version'] : true;
  1160. $iLotId = isset($aParams['lot']) ? (int)$aParams['lot'] : BX_IM_EMPTY;
  1161. $iJotId = isset($aParams['jot']) ? (int)$aParams['jot'] : BX_IM_EMPTY;
  1162. $iPersonToTalk = isset($aParams['selected_profile']) ? (int)$aParams['selected_profile'] : BX_IM_EMPTY;
  1163. $iType = isset($aParams['type']) ? (int)$aParams['type'] : BX_IM_TYPE_PRIVATE;
  1164. $sWelcomeMessage = isset($aParams['welcome']) ? strval($aParams['welcome']) : '';
  1165. $oEmbed = BxDolEmbed::getObjectInstance();
  1166. $sEmbedTemplate = '';
  1167. if($oEmbed && $CNF['USE_EMBEDLY'])
  1168. $sEmbedTemplate = $oEmbed->getLinkHTML('__url__');
  1169. $this->addJsTranslation(array(
  1170. '_bx_messenger_online',
  1171. '_bx_messenger_offline',
  1172. '_bx_messenger_away',
  1173. '_bx_messenger_repost_message',
  1174. '_bx_messenger_close_video_confirm',
  1175. '_bx_messenger_video_recorder_is_not_available',
  1176. '_bx_messenger_video_recorder_is_blocked',
  1177. '_bx_messenger_max_video_file_exceeds',
  1178. '_bx_messenger_video_record_is_not_supported',
  1179. '_bx_messenger_search_no_results',
  1180. '_bx_messenger_search_query_issue',
  1181. '_bx_messenger_wait_for_uploading',
  1182. '_bx_messenger_are_you_sure_close_jisti',
  1183. '_bx_messenger_jisti_connection_error',
  1184. '_bx_messenger_post_area_message',
  1185. '_bx_messenger_jitsi_mobile_warning',
  1186. '_bx_messenger_loading',
  1187. '_bx_messenger_share_jot',
  1188. '_bx_messenger_notification_request',
  1189. '_bx_messenger_notification_request_yes',
  1190. '_bx_messenger_notification_request_no',
  1191. '_bx_messenger_remove_jot_confirm',
  1192. '_bx_messenger_post_confirm_delete_file',
  1193. '_bx_messenger_delete_lot',
  1194. '_bx_messenger_clear_lot',
  1195. '_bx_messenger_are_you_sure_leave',
  1196. '_bx_messenger_lot_parts_empty',
  1197. '_bx_messenger_jot_menu_remove_save',
  1198. '_bx_messenger_jot_menu_save',
  1199. '_bx_messenger_reply_audio_file'
  1200. ));
  1201. $sUsername = '';
  1202. $oProfile = $this -> getObjectUser($iProfileId);
  1203. if($oProfile)
  1204. $sUsername = bx_js_string($oProfile -> getDisplayName());
  1205. $sUrl = $this->_oConfig->getPageIdent();
  1206. if ($iPersonToTalk && ($oModuleProfile = BxDolProfile::getInstance($iPersonToTalk))) {
  1207. $sModule = $oModuleProfile->getModule();
  1208. $bIsProfile = BxDolRequest::serviceExists($sModule, 'act_as_profile') && BxDolService::call($sModule, 'act_as_profile');
  1209. if (BxDolRequest::serviceExists($sModule, 'is_group_profile') && BxDolService::call($sModule, 'is_group_profile') && !$bIsProfile) {
  1210. $aOwnerInfo = BxDolService::call($sModule, 'get_info', array($oModuleProfile->getContentId(), false));
  1211. if (!empty($aOwnerInfo) && is_array($aOwnerInfo) && BxDolService::call($sModule, 'check_allowed_view_for_profile', array($aOwnerInfo)) === CHECK_ACTION_RESULT_ALLOWED) {
  1212. $oModule = BxDolModule::getInstance($sModule);
  1213. if ($oModule->_oConfig) {
  1214. $oMCNF = $oModule->_oConfig->CNF;
  1215. $sUrl = "i={$oMCNF['URI_VIEW_ENTRY']}&id=" . $oModuleProfile->getContentId();
  1216. if ($sUrl && $aTalk = $this->_oDb->getLotByUrl($sUrl))
  1217. $iLotId = $aTalk[$CNF['FIELD_ID']];
  1218. else
  1219. {
  1220. $sTalkTitle = $oModuleProfile->getDisplayName();
  1221. $iType = $this->_oConfig->getTalkType($sModule);
  1222. $iLotId = $this->_oDb->createLot($iProfileId, array('url' => $sUrl, 'title' => $sTalkTitle, 'type' => $iType, 'participants' => array($iProfileId)));
  1223. }
  1224. }
  1225. }
  1226. }
  1227. }
  1228. $iGroupId = 0;
  1229. if ($iLotId && ($aLotInfo = $this->_oDb->getLotInfoById($iLotId))){
  1230. if ($aLotInfo[$CNF['FIELD_TYPE']] != BX_IM_TYPE_PRIVATE && isset($aLotInfo[$CNF['FIELD_URL']]))
  1231. $sUrl = $aLotInfo[$CNF['FIELD_URL']];
  1232. $iType = $aLotInfo[$CNF['FIELD_TYPE']];
  1233. $iGroupId = (int)$aLotInfo[$CNF['FMGL_GROUP_ID']] ? (int)$aLotInfo[$CNF['FMGL_GROUP_ID']] : 0;
  1234. };
  1235. $aUnreadJotsInfo = $this->_oDb->getNewJots($iProfileId, $iLotId);
  1236. $iUnreadJotsNumber = $iLastUnreadJot = 0;
  1237. $iStartJot = (int)$iJotId;
  1238. if (!empty($aUnreadJotsInfo)){
  1239. $iStartJot = $iStartJot ? $iStartJot : (int)$aUnreadJotsInfo[$CNF['FIELD_NEW_JOT']];
  1240. $iUnreadJotsNumber = (int)$aUnreadJotsInfo[$CNF['FIELD_NEW_UNREAD']];
  1241. $iLastUnreadJot = (int)$aUnreadJotsInfo[$CNF['FIELD_NEW_JOT']];
  1242. }
  1243. $bAttach = true;
  1244. if ($iStartJot)
  1245. $bAttach = $this->_oDb->getJotsNumber($iLotId, $iStartJot) < (int)$CNF['MAX_JOTS_BY_DEFAULT']/2;
  1246. $sJotJWT = $CNF['JOT-JWT'];
  1247. $aUnreadJotsStat = $this->_oDb->getUnreadMessagesStat($iProfileId);
  1248. $aVars = [
  1249. 'profile_id' => (int)$iProfileId,
  1250. 'group_id' => $iGroupId,
  1251. 'username' => $sUsername,
  1252. 'lot' => (int)$iLotId,
  1253. 'url' => $sUrl,
  1254. 'type' => $iType,
  1255. 'direction' => BxDolLanguages::getInstance()->getLangDirection(),
  1256. 'selected_profile' => (int)$iPersonToTalk,
  1257. 'jot_id' => $iStartJot,
  1258. 'by_url' => (int)($iJotId != BX_IM_EMPTY),
  1259. 'block_version' => +$bBlockVersion,
  1260. 'server_url' => $this->_oConfig-> CNF['SERVER_URL'],
  1261. 'message_length' => (int)$CNF['MAX_SEND_SYMBOLS'],
  1262. 'jot_jwt' => $sJotJWT ? $this->_oConfig->generateJWTToken($iProfileId, array('profile' => $iProfileId)) : '',
  1263. 'ident' => md5(BX_DOL_URL_ROOT . BX_DOL_SECRET),
  1264. 'ip' => gethostbyname($aUrlInfo['host']),
  1265. 'embed_template' => $sEmbedTemplate,
  1266. 'thumb_icon' => $this->parseHtmlByName('thumb-icon.html', []),
  1267. 'thumb_letter' => $this->parseHtmlByName('thumb-letter.html', []),
  1268. 'add_user_item' => $this->parseHtmlByName('add-user-item.html', []),
  1269. 'max_history' => (int)$CNF['MAX_JOTS_BY_DEFAULT'],
  1270. 'quill_toolbar' => json_encode($this->_oConfig->CNF['QUILL_TOOLBAR'] ?? ''),
  1271. 'jitsi_server' => $this->_oConfig->getValidUrl($CNF['JITSI-SERVER'], 'url'),
  1272. 'last_unread_jot' => $iLastUnreadJot,
  1273. 'unread_jots' => $iUnreadJotsNumber,
  1274. 'unqiue_mode' => (int)$CNF['USE-UNIQUE-MODE'],
  1275. 'allow_attach' => +$bAttach,
  1276. 'messages' => count($aUnreadJotsStat) ? json_encode($aUnreadJotsStat) : 0,
  1277. 'muted' => ($iLotId && $iProfileId ? (int)$this->_oDb->isMuted($iLotId, $iProfileId) : 0),
  1278. 'dates_intervals_template' => $this->parseHtmlByName('date-separator.html', array('date' => '__date__')),
  1279. 'emoji_set' => $CNF['EMOJI_SET'],
  1280. 'emoji_prev' => +$CNF['EMOJI_PREVIEW'],
  1281. 'welcome_message' => $sWelcomeMessage,
  1282. 'reaction_template' => $this->parseHtmlByName('reaction.html', array(
  1283. 'emoji_id' => '__emoji_id__',
  1284. 'on_click' => 'oMessenger.onRemoveReaction(this);',
  1285. 'parts' => '__parts__',
  1286. 'title' => _t('_bx_messenger_reaction_title_author'),
  1287. 'number' => 1,
  1288. 'count' => 1,
  1289. 'value' => '__value__',
  1290. 'params' => json_encode(array(
  1291. 'id' => '__emoji_id__',
  1292. 'size' => $CNF['REACTIONS_SIZE'],
  1293. 'native' => $CNF['EMOJI_SET'] === 'native',
  1294. 'set' => $CNF['EMOJI_SET']
  1295. ))
  1296. )),
  1297. 'jot_template' => $this->getMembersJotTemplate($iProfileId),
  1298. 'jot_url' => $this->_oConfig->getRepostUrl()
  1299. ];
  1300. // init files Uploader
  1301. $oStorage = new BxMessengerStorage($this->_oConfig-> CNF['OBJECT_STORAGE']);
  1302. if ($oStorage) {
  1303. $sBaseUrl = $this->_oConfig->getBaseUri();
  1304. $aVars['files_uploader'] = json_encode(array(
  1305. 'input_name' => $CNF['FILES_UPLOADER'],
  1306. 'restricted_extensions' => json_encode($oStorage->getRestrictedExt()),
  1307. 'uploader_url' => $sBaseUrl . 'upload_temp_file',
  1308. 'remove_temp_file_url' => $sBaseUrl . 'upload_temp_file',
  1309. 'file_size' => (int)$oStorage->getMaxUploadFileSize($iProfileId)/(1024*1024),// in bytes
  1310. 'number_of_files' => (int)$this->_oConfig->CNF['MAX_FILES_TO_UPLOAD'],
  1311. 'is_block_version' => +$bBlockVersion
  1312. ));
  1313. }
  1314. return $this -> parseHtmlByName('config.html', $aVars);
  1315. }
  1316. public function getJotReactions($iJotId){
  1317. $CNF = &$this->_oConfig->CNF;
  1318. $aReactions = $this->_oDb->getJotReactions($iJotId);
  1319. if (empty($aReactions))
  1320. return '';
  1321. $aJotReactions = array();
  1322. $iViewer = bx_get_logged_profile_id();
  1323. foreach($aReactions as &$aReaction) {
  1324. $aJotReactions[$aReaction[$CNF['FIELD_REACT_EMOJI_ID']]]['profiles'][$aReaction[$CNF['FIELD_REACT_PROFILE_ID']]] =
  1325. $aReaction[$CNF['FIELD_REACT_PROFILE_ID']] == $iViewer
  1326. ? _t('_bx_messenger_reaction_title_author') : $this->getObjectUser($aReaction[$CNF['FIELD_REACT_PROFILE_ID']])->getDisplayName();
  1327. $aJotReactions[$aReaction[$CNF['FIELD_REACT_EMOJI_ID']]][$CNF['FIELD_REACT_NATIVE']] = $aReaction[$CNF['FIELD_REACT_NATIVE']];
  1328. }
  1329. $sReactions = '';
  1330. foreach($aJotReactions as $sEmojiId => $aItems) {
  1331. $aProfiles = $aItems['profiles'];
  1332. $iCount = count($aProfiles);
  1333. $sReactions .= $this->parseHtmlByName('reaction.html', [
  1334. 'title' => _t('_bx_messenger_reaction_title', implode(', ', $aProfiles), $sEmojiId),
  1335. 'emoji_id' => $sEmojiId,
  1336. 'number' => $iCount,
  1337. 'parts' => implode(',', array_keys($aProfiles)),
  1338. 'count' => $iCount,
  1339. 'on_click' => $iViewer ? 'oMessenger.onRemoveReaction(this);' : 'javascript:void(0);',
  1340. 'value' => $aItems[$CNF['FIELD_REACT_NATIVE']]
  1341. ]);
  1342. }
  1343. return $sReactions;
  1344. }
  1345. public function getMessageIcons($iJotId, $sType = 'edit', $isAdmin = false)
  1346. {
  1347. $CNF = &$this->_oConfig->CNF;
  1348. $sContent = '';
  1349. if (!($aJotInfo = $this -> _oDb -> getJotById($iJotId)))
  1350. return $sContent;
  1351. $sDate = bx_process_output($aJotInfo[$CNF['FIELD_MESSAGE_LAST_EDIT']], BX_DATA_DATETIME_TS);
  1352. $sEditorName = $aJotInfo[$CNF['FIELD_MESSAGE_EDIT_BY']] ? $this -> getObjectUser($aJotInfo[$CNF['FIELD_MESSAGE_EDIT_BY']]) -> getDisplayName() : '';
  1353. switch($sType)
  1354. {
  1355. case 'edit':
  1356. $sContent = $aJotInfo[$CNF['FIELD_MESSAGE_EDIT_BY']] ?
  1357. $this -> parseHtmlByName('edit-icon.html',
  1358. array(
  1359. 'edit' => _t('_bx_messenger_edit_by', $sDate, $sEditorName)
  1360. )
  1361. ) : '';
  1362. break;
  1363. case 'delete':
  1364. $sContent = $this -> parseHtmlByName('deleted_jot.html',
  1365. array(
  1366. 'bx_if:allow_to_delete' => array(
  1367. 'condition' => $isAdmin,
  1368. 'content' =>
  1369. array(
  1370. 'message' => bx_js_string(_t('_bx_messenger_confirm_delete_completely')),
  1371. 'id' => $iJotId
  1372. ),
  1373. ),
  1374. 'info' => $sEditorName ? _t('_bx_messenger_deleted_by', $sDate, $sEditorName) : ''
  1375. )
  1376. );
  1377. break;
  1378. case 'vc':
  1379. $iVC = $aJotInfo[$CNF['FIELD_MESSAGE_VIDEOC']];
  1380. $sContent = _t('_bx_messenger_jitsi_err_vc_was_not_found');
  1381. $sParticipants = '';
  1382. if ($iVC && ($aJVCItem = $this->_oDb->getJVCItem($iVC)))
  1383. {
  1384. $aParticipants = explode(',', $aJVCItem[$CNF['FJVCT_PART']]);
  1385. if (!$aJVCItem[$CNF['FJVCT_END']])
  1386. $sInfo = _t('_bx_messenger_jitsi_has_started', bx_time_js($aJVCItem[$CNF['FJVCT_START']]));
  1387. else
  1388. {
  1389. $iDiff = $aJVCItem[$CNF['FJVCT_END']] - $aJVCItem[$CNF['FJVCT_START']];
  1390. $iH = floor( $iDiff / 3600 );
  1391. $iM = floor( (int)( $iDiff / 60 ) % 60 );
  1392. $iS = $iDiff % 60;
  1393. $sDate = _t('_bx_messenger_jitsi_vc_duration_s', $iS);
  1394. if ($iH)
  1395. $sDate = _t('_bx_messenger_jitsi_vc_duration_h', $iH, $iM, $iS);
  1396. else
  1397. if ($iM)
  1398. $sDate = _t('_bx_messenger_jitsi_vc_duration_m', $iM, $iS);
  1399. $aIcons = array();
  1400. foreach($aParticipants as &$iProfileId) {
  1401. if ($oProfile = BxDolProfile::getInstance($iProfileId))
  1402. $aIcons[] = array(
  1403. 'id' => $iProfileId,
  1404. 'icon' => $oProfile->getIcon(),
  1405. 'name' => $oProfile->getDisplayName(),
  1406. );
  1407. }
  1408. $sParticipants = !empty($aIcons) ? $this -> parseHtmlByName('viewed.html', array(
  1409. 'bx_repeat:viewed' => $aIcons
  1410. )) : '';
  1411. $sInfo = _t('_bx_messenger_jitsi_conference', $sDate);
  1412. }
  1413. $aLotInfo = $this->_oDb->getLotByJotId($iJotId, false);
  1414. $aJVC = $this->_oDb->getJVC($aLotInfo[$CNF['FIELD_ID']]);
  1415. $sRoom = empty($aJVC) && !empty($aLotInfo) ? $this->_oConfig->getRoomId($aLotInfo[$CNF['FIELD_ID']], $aLotInfo[$CNF['FIELD_AUTHOR']]) : $aJVC[$CNF['FJVC_ROOM']];
  1416. $sContent = $this -> parseHtmlByName('vc-message.html',
  1417. array(
  1418. 'info' => $sInfo,
  1419. 'bx_if:join' => array(
  1420. 'condition' => !$aJVCItem[$CNF['FJVCT_END']] && ($isAdmin || $this->_oConfig->isAllowedAction(BX_MSG_ACTION_JOIN_TALK_VC) === true),
  1421. 'content' => array(
  1422. 'id' => $aLotInfo[$CNF['FIELD_ID']],
  1423. 'room' => $sRoom
  1424. )
  1425. ),
  1426. 'bx_if:part' => array(
  1427. 'condition' => $sParticipants,
  1428. 'content' => array(
  1429. 'participants' => $sParticipants
  1430. )
  1431. )
  1432. ));
  1433. }
  1434. break;
  1435. }
  1436. return $sContent;
  1437. }
  1438. /**
  1439. * Create profile html template for jot which is used when member posts a message
  1440. *@param int $iProfileId logget member id
  1441. *@return string html code
  1442. */
  1443. public function getMembersJotTemplate($iProfileId){
  1444. if (!$iProfileId)
  1445. return '';
  1446. $CNF = &$this->_oConfig->CNF;
  1447. $oProfile = $this -> getObjectUser($iProfileId);
  1448. $isAllowedDelete = $CNF['ALLOW_TO_REMOVE_MESSAGE'] || isAdmin();
  1449. if ($oProfile)
  1450. {
  1451. $aJot = [];
  1452. $sDisplayName = $oProfile->getDisplayName();
  1453. $sThumb = $oProfile->getThumb();
  1454. $bThumb = stripos($sThumb, 'no-picture') === FALSE;
  1455. $aVars['bx_repeat:jots'][] = array
  1456. (
  1457. 'title' => $oProfile->getDisplayName(),
  1458. 'url' => $oProfile->getUrl(),
  1459. 'thumb' => $oProfile->getThumb(),
  1460. 'display' => 'style="display:flex;"',
  1461. 'display_message' => 'style="display:none;"',
  1462. 'id' => 0,
  1463. 'new' => '',
  1464. 'my' => 1,
  1465. 'message' => '{message}',
  1466. 'attachment' => '',
  1467. 'reply' => $this -> parseHtmlByName('reply.html', array(
  1468. 'id' => '{reply_parent_id}',
  1469. 'message' => '{reply_message}'
  1470. )),
  1471. 'bx_if:show_author' => array(
  1472. 'condition' => true,
  1473. 'content' => array(
  1474. 'url' => $oProfile->getUrl(),
  1475. 'bx_if:avatars' => array(
  1476. 'condition' => $bThumb,
  1477. 'content' => array(
  1478. 'thumb' => $sThumb,
  1479. 'title' => $sDisplayName,
  1480. )
  1481. ),
  1482. 'bx_if:letters' => array(
  1483. 'condition' => !$bThumb,
  1484. 'content' => array(
  1485. 'color' => implode(', ', BxDolTemplate::getColorCode($oProfile->id(), 1.0)),
  1486. 'letter' => mb_substr($sDisplayName, 0, 1)
  1487. )
  1488. ),
  1489. )
  1490. ),
  1491. 'bx_if:show_title' => array(
  1492. 'condition' => true,
  1493. 'content' => array(
  1494. 'title' => $sDisplayName,
  1495. )
  1496. ),
  1497. 'bx_if:jot_menu' => array(
  1498. 'condition' => true,
  1499. 'content' => array(
  1500. 'jot_menu' => $this->getJotMenuCode(BX_IM_EMPTY)
  1501. )
  1502. ),
  1503. 'bx_if:time-separator' => array(
  1504. 'condition' => false,
  1505. 'content' => array(
  1506. 'date' => '',
  1507. )
  1508. ),
  1509. 'thread_replies' => '',
  1510. 'bx_if:show_reactions_area' => array(
  1511. 'condition' => true,
  1512. 'content' => array(
  1513. 'bx_if:reactions' => array(
  1514. 'condition' => true,
  1515. 'content' => array(
  1516. 'reactions' => '',
  1517. 'bx_if:reactions_menu' => array(
  1518. 'condition' => true,
  1519. 'content' => array(
  1520. 'display' => 'none',
  1521. )
  1522. ),
  1523. )
  1524. ),
  1525. 'bx_if:edit' => array(
  1526. 'condition' => $isAllowedDelete,
  1527. 'content' => array()
  1528. ),
  1529. )
  1530. ),
  1531. 'bx_if:blink-jot' => array(
  1532. 'condition' => false,
  1533. 'content' => array()
  1534. ),
  1535. 'bx_if:new' => array(
  1536. 'condition' => true,
  1537. 'content' => array()
  1538. ),
  1539. 'icons' => $this->parseHtmlByName('jot-icons.html', array(
  1540. 'edit_icon' => '',
  1541. 'time' => bx_time_js(time(), BX_FORMAT_TIME, true),
  1542. 'views' => '',
  1543. )),
  1544. 'edit_icon' => '',
  1545. 'reactions' => '',
  1546. 'action_icon' => '',
  1547. 'view_in_chat' => '',
  1548. 'message_class' => 'hidden'
  1549. );
  1550. return $this -> parseHtmlByName('jots.html', $aVars);
  1551. }
  1552. return '';
  1553. }
  1554. function videoPlayer ($sUrlPoster, $sUrlMP4, $sUrlWebM = '', $sUrlMP4Hd = '', $aAttrs = false, $bDynamic = true)
  1555. {
  1556. $oPlayer = BxDolPlayer::getObjectInstance();
  1557. if (!$oPlayer)
  1558. return '';
  1559. return $oPlayer->getCodeVideo (BX_PLAYER_STANDARD, array(
  1560. 'poster' => $sUrlPoster,
  1561. 'mp4' => array('sd' => $sUrlMP4, 'hd' => $sUrlMP4Hd),
  1562. 'webm' => array('sd' => $sUrlWebM ),
  1563. 'attrs' => $aAttrs,
  1564. 'styles' => 'width:90%; max-width:480px; height:auto;',
  1565. ), $bDynamic);
  1566. }
  1567. function getAttachmentsVideoTranscoders($sStorage = ''){
  1568. $aTranscoders = parent::getAttachmentsVideoTranscoders($sStorage);
  1569. if (!$aTranscoders)
  1570. return array();
  1571. $aTranscoders['webm'] = BxDolTranscoderImage::getObjectInstance($this -> _oConfig -> CNF['OBJECT_VIDEOS_TRANSCODERS']['webm']);
  1572. return $aTranscoders;
  1573. }
  1574. function getVideoFilesToPlay($aFile){
  1575. $CNF = &$this -> _oConfig -> CNF;
  1576. $sFileUrl = BxDolStorage::getObjectInstance($CNF['OBJECT_STORAGE'])->getFileUrlById((int)$aFile[$CNF['FIELD_ST_ID']]);
  1577. $aTranscodersVideo = $this -> getAttachmentsVideoTranscoders();
  1578. if (empty($aTranscodersVideo))
  1579. return '';
  1580. $sMp4File = $aTranscodersVideo['mp4']->getFileUrl((int)$aFile[$CNF['FIELD_ST_ID']]);
  1581. $sMp4HDFile = $aTranscodersVideo['mp4_hd']->getFileUrl((int)$aFile[$CNF['FIELD_ST_ID']]);
  1582. $sWebMFile = $aTranscodersVideo['webm']->getFileUrl((int)$aFile[$CNF['FIELD_ST_ID']]);
  1583. $sPoster = $aTranscodersVideo['poster']->getFileUrl($aFile[$CNF['FIELD_ST_ID']]);
  1584. if (!$sMp4File && !$sWebMFile){
  1585. if ($aFile[$CNF['FIELD_ST_EXT']] == 'webm') {
  1586. $sWebMFile = $sFileUrl;
  1587. $sPoster = '';
  1588. }
  1589. if ($aFile[$CNF['FIELD_ST_EXT']] == 'mp4' || $aFile[$CNF['FIELD_ST_EXT']] == 'mov') {
  1590. $sMp4File = $sMp4HDFile = $sFileUrl;
  1591. $sPoster = '';
  1592. }
  1593. }
  1594. return ($sMp4File || $sWebMFile) ? $this -> videoPlayer(
  1595. $sPoster,
  1596. $sMp4File,
  1597. $sWebMFile,
  1598. $sMp4HDFile,
  1599. array('preload' => 'metadata'),
  1600. true
  1601. ) : $this->parseHtmlByName('tmp_video.html', array('img' => $sPoster));
  1602. }
  1603. function getReplyPreview($iJotId){
  1604. if (!$iJotId || !($aJot = $this->_oDb->getJotById($iJotId)))
  1605. return '';
  1606. $CNF = &$this -> _oConfig -> CNF;
  1607. if (!empty($aJot))
  1608. {
  1609. $aAttachType = [];
  1610. if ($aJot[$CNF['FIELD_MESSAGE_AT_TYPE']])
  1611. $aAttachType = array($aJot[$CNF['FIELD_MESSAGE_AT_TYPE']] => $aJot[$CNF['FIELD_MESSAGE_AT']]);
  1612. else if ($aJot[$CNF['FIELD_MESSAGE_AT']])
  1613. $aAttachType = @unserialize($aJot[$CNF['FIELD_MESSAGE_AT']]);
  1614. $sAttachmentType = '';
  1615. foreach($aAttachType as $sType => $sValue){
  1616. if ($sType == BX_ATT_TYPE_REPLY && !$aJot[$CNF['FIELD_MESSAGE']])
  1617. continue;
  1618. $sAttachmentType = $sType;
  1619. break;
  1620. }
  1621. if ((int)$aJot[$CNF['FIELD_MESSAGE_REPLY']])
  1622. $sAttachmentType = BX_ATT_TYPE_REPLY;
  1623. switch($sAttachmentType)
  1624. {
  1625. case BX_ATT_TYPE_GIPHY:
  1626. return '<img src="//media1.giphy.com/media/' . $aAttachType[$sAttachmentType] . '/giphy_s.gif" />';
  1627. case BX_ATT_TYPE_REPLY:
  1628. return get_mb_substr(html2txt($aJot[$CNF['FIELD_MESSAGE']]), 0, $CNF['JOT-PREVIEW-TEXT-LENGTH']);
  1629. case BX_ATT_TYPE_FILES_UPLOADING:
  1630. case BX_ATT_TYPE_FILES:
  1631. $aFiles = $this -> _oDb -> getJotFiles($aJot[$CNF['FIELD_MESSAGE_ID']]);
  1632. $aTranscodersVideo = $this -> getAttachmentsVideoTranscoders();
  1633. $oStorage = new BxMessengerStorage($CNF['OBJECT_STORAGE']);
  1634. $oTranscoderMp3 = BxDolTranscoderAudio::getObjectInstance($CNF['OBJECT_MP3_TRANSCODER']);
  1635. $aFile = current($aFiles);
  1636. $isVideo = $aTranscodersVideo && (0 == strncmp('video/', $aFile['mime_type'], 6)) && $aTranscodersVideo['poster']->isMimeTypeSupported($aFile['mime_type']);
  1637. if ($oStorage -> isImageFile($aFile[$CNF['FIELD_ST_TYPE']])) {
  1638. $sPhotoThumb = "";
  1639. if ($oImagesTranscoder = BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_IMAGES_TRANSCODER_PREVIEW']))
  1640. $sPhotoThumb = $oImagesTranscoder->getFileUrl((int)$aFile[$CNF['FIELD_ST_ID']]);
  1641. $sFileUrl = BxDolStorage::getObjectInstance($CNF['OBJECT_STORAGE'])->getFileUrlById((int)$aFile[$CNF['FIELD_ST_ID']]);
  1642. return '<img src="' . ( $sPhotoThumb ?: $sFileUrl ) . '" />';
  1643. }
  1644. if ($isVideo)
  1645. return '<img src="' . $aTranscodersVideo['poster']->getFileUrl($aFile[$CNF['FIELD_ST_ID']]) . '" />';
  1646. if ($oTranscoderMp3 -> isMimeTypeSupported($aFile[$CNF['FIELD_ST_TYPE']])) {
  1647. $sAudioFileName = !empty($aFile[$CNF['FIELD_ST_NAME']]) ? $aFile[$CNF['FIELD_ST_NAME']] : '...';
  1648. return _t('_bx_messenger_reply_audio_file', $sAudioFileName);
  1649. }
  1650. return $this -> parseHtmlByName('file.html', array(
  1651. 'type' => $oStorage -> getFontIconNameByFileName($aFile[$CNF['FIELD_ST_NAME']]),
  1652. 'name' => $aFile[$CNF['FIELD_ST_NAME']],
  1653. 'file_type' => $aFile[$CNF['FIELD_ST_TYPE']],
  1654. ));
  1655. default:
  1656. if ($sAttachmentType && ($aService = $this->_oDb->getLotAttachmentType($sAttachmentType))){
  1657. if (!empty($aService['module']) && !empty($aService['method']) && BxDolRequest::serviceExists($aService['module'], $aService['method'])) {
  1658. return BxDolService::call($aService['module'], $aService['method'], [$aAttachType[$sAttachmentType] ?? '', $aJot[$CNF['FIELD_MESSAGE_ID']], 'reply']);
  1659. }
  1660. }
  1661. return html2txt($aJot[$CNF['FIELD_MESSAGE']]);
  1662. }
  1663. }
  1664. }
  1665. /**
  1666. * Returns attachment according jot's attachment type
  1667. * @param array $aJot jot info
  1668. * @param bool $bIsDynamicallyLoad true when message is dynamically loaded to the history
  1669. * @param bool $bImplode implode attachments types to the groups to show in history
  1670. * @return array/bool html code
  1671. */
  1672. function getAttachment($aJot, $bIsDynamicallyLoad = false, $bImplode = true){
  1673. $iViewer = bx_get_logged_profile_id();
  1674. $CNF = &$this -> _oConfig -> CNF;
  1675. if (empty($aJot) || (empty($aJot[$CNF['FIELD_MESSAGE_AT']]) && !(int)$aJot[$CNF['FIELD_MESSAGE_REPLY']]))
  1676. return false;
  1677. $bIsLotAuthor = $this -> _oDb -> isAuthor($aJot[$CNF['FIELD_MESSAGE_FK']], $iViewer);
  1678. if ($aJot[$CNF['FIELD_MESSAGE_AT_TYPE']])
  1679. $mixedValues = array($aJot[$CNF['FIELD_MESSAGE_AT_TYPE']] => $aJot[$CNF['FIELD_MESSAGE_AT']]);
  1680. else
  1681. $mixedValues = @unserialize($aJot[$CNF['FIELD_MESSAGE_AT']]);
  1682. $aResult = array();
  1683. foreach($mixedValues as $sType => $sValue) {
  1684. switch($sType)
  1685. {
  1686. case BX_ATT_TYPE_REPOST:
  1687. $aResult[BX_ATT_TYPE_REPOST][] = $this -> getJotAsAttachment($sValue);
  1688. break;
  1689. case BX_ATT_TYPE_GIPHY:
  1690. $aResult[BX_ATT_TYPE_GIPHY][] = $this -> parseHtmlByName('giphy.html', array(
  1691. 'gif' => $sValue,
  1692. 'time' => time(),
  1693. 'static' => $bIsDynamicallyLoad ? 'none' : 'flex',
  1694. 'dynamic' => $bIsDynamicallyLoad ? 'block' : 'none',
  1695. ));
  1696. break;
  1697. case BX_ATT_TYPE_FILES_UPLOADING:
  1698. case BX_ATT_TYPE_FILES:
  1699. if (is_string($sValue))
  1700. $aUploadingFilesList = explode(',', $sValue);
  1701. else if (is_array($sValue))
  1702. $aUploadingFilesList = $sValue;
  1703. else
  1704. $aUploadingFilesList = [];
  1705. $aFiles = $this -> _oDb -> getJotFiles($aJot[$CNF['FIELD_MESSAGE_ID']]);
  1706. $aItems = array(
  1707. 'bx_repeat:images' => [],
  1708. 'bx_repeat:files' => [],
  1709. 'bx_repeat:videos' => [],
  1710. 'bx_repeat:audios' => [],
  1711. 'bx_repeat:loading_placeholder' => []
  1712. );
  1713. $aTranscodersVideo = $this -> getAttachmentsVideoTranscoders();
  1714. $oStorage = new BxMessengerStorage($this->_oConfig-> CNF['OBJECT_STORAGE']);
  1715. $oTranscoderMp3 = BxDolTranscoderAudio::getObjectInstance($this -> _oConfig -> CNF['OBJECT_MP3_TRANSCODER']);
  1716. foreach($aFiles as &$aFile)
  1717. {
  1718. if (($iKey = array_search($aFile[$CNF['FIELD_ST_NAME']], $aUploadingFilesList)) !== FALSE)
  1719. unset($aUploadingFilesList[$iKey]);
  1720. $bCollapsed = (bool)$aFile[$CNF['FJMT_COLLAPSED']];
  1721. $isAllowedDelete = $this->_oDb->isAllowedToDeleteJot($aJot[$CNF['FIELD_MESSAGE_ID']], $iViewer, $aJot[$CNF['FIELD_MESSAGE_AUTHOR']], $bIsLotAuthor);
  1722. $isVideo = $aTranscodersVideo && (0 == strncmp('video/', $aFile['mime_type'], 6)) && $aTranscodersVideo['poster']->isMimeTypeSupported($aFile['mime_type']);
  1723. if ($oStorage -> isImageFile($aFile[$CNF['FIELD_ST_TYPE']]))
  1724. {
  1725. $sPhotoThumb = '';
  1726. if ($aFile[$CNF['FIELD_ST_TYPE']] != 'image/gif' && $oImagesTranscoder = BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_IMAGES_TRANSCODER_PREVIEW']))
  1727. $sPhotoThumb = $oImagesTranscoder->getFileUrl((int)$aFile[$CNF['FIELD_ST_ID']]);
  1728. $sFileUrl = BxDolStorage::getObjectInstance($CNF['OBJECT_STORAGE'])->getFileUrlById((int)$aFile[$CNF['FIELD_ST_ID']]);
  1729. $aItems['bx_repeat:images'][] = array(
  1730. 'media_accordion' => $this->parseHtmlByName('media-accordion.html',[
  1731. 'file_name' => $aFile[$CNF['FIELD_ST_NAME']],
  1732. 'icon' => $oStorage -> getFontIconNameByFileName($aFile[$CNF['FIELD_ST_NAME']]),
  1733. 'hidden' => +$bCollapsed,
  1734. 'up_class' => $bCollapsed ? '' : 'hidden',
  1735. 'down_class' => !$bCollapsed ? '' : 'hidden',
  1736. ]),
  1737. 'hidden' => $bCollapsed ? 'hidden' : '',
  1738. 'url' => $sPhotoThumb ? $sPhotoThumb : $sFileUrl,
  1739. 'id' => $aFile[$CNF['FIELD_ST_ID']],
  1740. 'name' => $aFile[$CNF['FIELD_ST_NAME']],
  1741. 'file_menu' => $this -> getFileMenu($aFile[$CNF['FIELD_ST_ID']], $isAllowedDelete)
  1742. );
  1743. }
  1744. elseif ($isVideo)
  1745. {
  1746. $aItems['bx_repeat:videos'][] = array(
  1747. 'media_accordion' => $this->parseHtmlByName('media-accordion.html',[
  1748. 'file_name' => $aFile[$CNF['FIELD_ST_NAME']],
  1749. 'icon' => $oStorage -> getFontIconNameByFileName($aFile[$CNF['FIELD_ST_NAME']]),
  1750. 'hidden' => +$bCollapsed,
  1751. 'up_class' => $bCollapsed ? '' : 'hidden',
  1752. 'down_class' => !$bCollapsed ? '' : 'hidden',
  1753. ]),
  1754. 'hidden' => $bCollapsed ? 'hidden' : '',
  1755. 'file_name' => $aFile[$CNF['FIELD_ST_NAME']],
  1756. 'id' => $aFile[$CNF['FIELD_ST_ID']],
  1757. 'video' => $this -> getVideoFilesToPlay($aFile),
  1758. 'file_menu' => $this -> getFileMenu($aFile[$CNF['FIELD_ST_ID']], $isAllowedDelete)
  1759. );
  1760. }
  1761. elseif ($oTranscoderMp3 -> isMimeTypeSupported($aFile[$CNF['FIELD_ST_TYPE']]))
  1762. {
  1763. $sFileUrl = BxDolStorage::getObjectInstance($CNF['OBJECT_STORAGE'])->getFileUrlById((int)$aFile[$CNF['FIELD_ST_ID']]);
  1764. $sMp3File = $aFile[$CNF['FIELD_ST_EXT']] == 'mp3' ? $sFileUrl : $oTranscoderMp3->getFileUrl((int)$aFile[$CNF['FIELD_ST_ID']]);
  1765. $aItems['bx_repeat:audios'][] = array(
  1766. 'media_accordion' => $this->parseHtmlByName('media-accordion.html',[
  1767. 'file_name' => $aFile[$CNF['FIELD_ST_NAME']],
  1768. 'icon' => $oStorage -> getFontIconNameByFileName($aFile[$CNF['FIELD_ST_NAME']]),
  1769. 'hidden' => +$bCollapsed,
  1770. 'up_class' => $bCollapsed ? '' : 'hidden',
  1771. 'down_class' => !$bCollapsed ? '' : 'hidden',
  1772. ]),
  1773. 'hidden' => $bCollapsed ? 'hidden' : '',
  1774. 'id' => $aFile[$CNF['FIELD_ST_ID']],
  1775. 'title' => $aFile[$CNF['FIELD_ST_NAME']],
  1776. 'mp3' => $this -> audioPlayer($sMp3File, true),
  1777. 'bx_if:loading' => array(
  1778. 'condition' => !$sMp3File,
  1779. 'content' => array(
  1780. 'loading_img' => BxDolTemplate::getInstance()->getImageUrl('video-na.png')
  1781. )
  1782. ),
  1783. 'file_menu' => $this -> getFileMenu($aFile[$CNF['FIELD_ST_ID']], $isAllowedDelete)
  1784. );
  1785. }
  1786. else
  1787. $aItems['bx_repeat:files'][] = array(
  1788. 'file' => $this -> parseHtmlByName('a-file.html',
  1789. [
  1790. 'file' => $this -> parseHtmlByName('file.html',
  1791. [
  1792. 'type' => $oStorage -> getFontIconNameByFileName($aFile[$CNF['FIELD_ST_NAME']]),
  1793. 'name' => $aFile[$CNF['FIELD_ST_NAME']],
  1794. 'file_type' => $aFile[$CNF['FIELD_ST_TYPE']],
  1795. 'bx_if:time' => [
  1796. 'condition' => !$aJot[$CNF['FIELD_MESSAGE']],
  1797. 'content' => [
  1798. 'time' => bx_time_js($aFile[$CNF['FIELD_ST_ADDED']], BX_FORMAT_TIME, !$CNF['TIME-FROM-NOW']),
  1799. ]
  1800. ]
  1801. ]),
  1802. 'id' => $aFile[$CNF['FIELD_MESSAGE_ID']],
  1803. 'name' => $aFile[$CNF['FIELD_ST_NAME']],
  1804. 'url' => BX_DOL_URL_ROOT
  1805. ]),
  1806. 'file_menu' => $this -> getFileMenu($aFile[$CNF['FIELD_MESSAGE_ID']], $isAllowedDelete)
  1807. );
  1808. }
  1809. foreach($aUploadingFilesList as $sFileName)
  1810. $aItems['bx_repeat:loading_placeholder'][] = array(
  1811. 'url' => $this->getImageUrl('audio-na.png'),
  1812. 'name' => $sFileName,
  1813. );
  1814. $aResult[BX_ATT_TYPE_FILES][] = $this -> parseHtmlByName('files.html', $aItems);
  1815. break;
  1816. default:
  1817. if ($sType && $sValue && ($aService = $this->_oDb->getLotAttachmentType($sType))){
  1818. if (!empty($aService['module']) && !empty($aService['method']) && BxDolRequest::serviceExists($aService['module'], $aService['method'])) {
  1819. $mixedContent = BxDolService::call($aService['module'], $aService['method'], [$sValue, $aJot[$CNF['FIELD_MESSAGE_ID']]]);
  1820. if (is_array($mixedContent) && !empty($mixedContent['content']))
  1821. $aContent = $mixedContent;
  1822. else
  1823. $aContent = ['content' => $mixedContent];
  1824. $aResult[BX_ATT_TYPE_CUSTOM][] = $this -> parseHtmlByName('custom-attachment.html', $aContent);
  1825. }
  1826. }
  1827. }
  1828. }
  1829. $aAttachments = [];
  1830. if ($bImplode) {
  1831. foreach ($CNF['IMPLODE_GROUPS'] as $sGroup => $aItems) {
  1832. foreach ($aResult as $sKey => $sValue) {
  1833. if (in_array($sKey, $aItems)) {
  1834. if (!isset($aAttachments[$sGroup]))
  1835. $aAttachments[$sGroup] = '';
  1836. $aAttachments[$sGroup] .= implode('', $sValue);
  1837. } else
  1838. $aAttachments[$sKey] = implode('', $sValue);
  1839. }
  1840. }
  1841. }
  1842. return $aAttachments;
  1843. }
  1844. public function getFileContent($aFile){
  1845. $CNF = &$this -> _oConfig -> CNF;
  1846. $oStorage = new BxMessengerStorage($this->_oConfig-> CNF['OBJECT_STORAGE']);
  1847. if ($oStorage -> isImageFile($aFile[$CNF['FIELD_ST_TYPE']]))
  1848. {
  1849. $sPhotoThumb = '';
  1850. if ($aFile[$CNF['FIELD_ST_TYPE']] != 'image/gif' && $oImagesTranscoder = BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_IMAGES_TRANSCODER_PREVIEW']))
  1851. $sPhotoThumb = $oImagesTranscoder->getFileUrl((int)$aFile[$CNF['FIELD_ST_ID']]);
  1852. $sFileUrl = BxDolStorage::getObjectInstance($this->_oConfig-> CNF['OBJECT_STORAGE'])->getFileUrlById((int)$aFile[$CNF['FIELD_ST_ID']]);
  1853. return $this -> parseHtmlByName('img.html', array(
  1854. 'url' => $sPhotoThumb ? $sPhotoThumb : $sFileUrl,
  1855. 'name' => $aFile[$CNF['FIELD_ST_NAME']],
  1856. 'id' => $aFile[$CNF['FIELD_ST_ID']]
  1857. ));
  1858. }
  1859. $aTranscodersVideo = $this -> getAttachmentsVideoTranscoders();
  1860. $isVideo = $aTranscodersVideo && (0 == strncmp('video/', $aFile['mime_type'], 6)) && $aTranscodersVideo['poster']->isMimeTypeSupported($aFile['mime_type']);
  1861. if ($isVideo)
  1862. return $this -> parseHtmlByName('video.html', array(
  1863. 'id' => $aFile[$CNF['FIELD_ST_ID']],
  1864. 'video' => $this->getVideoFilesToPlay($aFile),
  1865. ));
  1866. $oTranscoderMp3 = BxDolTranscoderAudio::getObjectInstance($this -> _oConfig -> CNF['OBJECT_MP3_TRANSCODER']);
  1867. if ($oTranscoderMp3 -> isMimeTypeSupported($aFile[$CNF['FIELD_ST_TYPE']]))
  1868. {
  1869. $sFileUrl = BxDolStorage::getObjectInstance($CNF['OBJECT_STORAGE'])->getFileUrlById((int)$aFile[$CNF['FIELD_ST_ID']]);
  1870. $sMp3File = $aFile[$CNF['FIELD_ST_EXT']] == 'mp3' ? $sFileUrl : $oTranscoderMp3->getFileUrl((int)$aFile[$CNF['FIELD_ST_ID']]);
  1871. return $this -> parseHtmlByName('audio.html', array(
  1872. 'id' => $aFile[$CNF['FIELD_ST_ID']],
  1873. 'title' => $aFile[$CNF['FIELD_ST_NAME']],
  1874. 'mp3' => $this -> audioPlayer($sMp3File, true)
  1875. ));
  1876. }
  1877. return $this -> parseHtmlByName('a-file.html', [
  1878. 'file' => $this -> parseHtmlByName('file.html', [
  1879. 'type' => $oStorage -> getFontIconNameByFileName($aFile[$CNF['FIELD_ST_NAME']]),
  1880. 'name' => $aFile[$CNF['FIELD_ST_NAME']],
  1881. 'file_type' => $aFile[$CNF['FIELD_ST_TYPE']],
  1882. ]),
  1883. 'id' => $aFile[$CNF['FIELD_MESSAGE_ID']],
  1884. 'url' => BX_DOL_URL_ROOT,
  1885. 'name' => $aFile[$CNF['FIELD_ST_NAME']],
  1886. ]);
  1887. }
  1888. /**
  1889. * Returns Jot content as attachment(repost) for a message
  1890. *@param int $iJotId jot id
  1891. *@return string html code
  1892. */
  1893. function getJotAsAttachment($iJotId){
  1894. $CNF = &$this->_oConfig->CNF;
  1895. $sHTML = '';
  1896. $aJot = $this -> _oDb -> getJotById($iJotId);
  1897. if (empty($aJot))
  1898. return $sHTML;
  1899. $iAttachedJotId = $this -> _oDb -> hasAttachment($iJotId);
  1900. if ($iAttachedJotId !== false)
  1901. {
  1902. $sOriginalMessage = $this->_oConfig->cleanRepostLinks($aJot[$CNF['FIELD_MESSAGE']], $iAttachedJotId);
  1903. if (!$sOriginalMessage)
  1904. $aJot = $this -> _oDb -> getJotById($iAttachedJotId);
  1905. }
  1906. $sMessage = '';
  1907. if (isset($aJot[$CNF['FIELD_MESSAGE_AT']]) && $aJot[$CNF['FIELD_MESSAGE_AT']]) {
  1908. $aAttachment = $this->getAttachment($aJot);
  1909. if (isset($aAttachment[BX_ATT_GROUPS_ATTACH]))
  1910. $sMessage = $aJot[$CNF['FIELD_MESSAGE']] . $aAttachment[BX_ATT_GROUPS_ATTACH];
  1911. }
  1912. else
  1913. $sMessage = $this -> _oConfig -> bx_linkify($aJot[$CNF['FIELD_MESSAGE']]);
  1914. if (!empty($aJot))
  1915. {
  1916. $aLotsTypes = $this -> _oDb -> getLotsTypesPairs();
  1917. $oProfile = $this -> getObjectUser($aJot[$CNF['FIELD_MESSAGE_AUTHOR']]);
  1918. $aLotInfo = $this -> _oDb -> getLotByJotId($iJotId, false);
  1919. $sHTML = $this -> parseHtmlByName('repost.html', array(
  1920. 'icon' => $oProfile -> getThumb(),
  1921. 'message' => $sMessage,
  1922. 'username' => $oProfile -> getDisplayName(),
  1923. 'message_type' => !empty($aLotInfo) && isset($aLotInfo[$CNF['FIELD_TYPE']])? _t('_bx_messenger_lots_message_type_' . $aLotsTypes[$aLotInfo[$CNF['FIELD_TYPE']]]) : '',
  1924. 'date' => bx_process_output($aJot[$CNF['FIELD_MESSAGE_ADDED']], BX_DATA_DATETIME_TS),
  1925. ));
  1926. }
  1927. return $sHTML;
  1928. }
  1929. /**
  1930. * Returns user profile even if it was removed from the site
  1931. *@param int $iProfileId profile id
  1932. *@return object instance of Profile
  1933. */
  1934. public function getObjectUser($iProfileId)
  1935. {
  1936. bx_import('BxDolProfile');
  1937. $oProfile = BxDolProfile::getInstance($iProfileId);
  1938. if (!$oProfile)
  1939. {
  1940. bx_import('BxDolProfileUndefined');
  1941. $oProfile = BxDolProfileUndefined::getInstance();
  1942. }
  1943. return $oProfile;
  1944. }
  1945. /**
  1946. * Returns files uploading form
  1947. *@param int $iJotId message id
  1948. *@return string html form
  1949. */
  1950. public function getEditJotArea($iJotId)
  1951. {
  1952. $aJot = $this -> _oDb -> getJotById($iJotId);
  1953. return $this -> parseHtmlByName('edit-jot.html', array(
  1954. 'place_holder' => _t('_bx_messenger_post_area_message'),
  1955. 'content' => $aJot[$this->_oConfig->CNF['FIELD_MESSAGE']]
  1956. ));
  1957. }
  1958. /**
  1959. * Returns body of the jot
  1960. *@param int $iJotId id of the jot
  1961. *@return string html form
  1962. */
  1963. public function getJotsBody($iJotId)
  1964. {
  1965. $aJot = $this -> _oDb -> getJotById($iJotId);
  1966. if (empty($aJot))
  1967. return '';
  1968. $sMessage = $this->_oConfig->bx_linkify($aJot[$this -> _oConfig -> CNF['FIELD_MESSAGE']]);
  1969. $aAttachment = $this -> getAttachment($aJot);
  1970. $aVars = array(
  1971. 'message' => $sMessage,
  1972. 'attachment' => isset($aAttachment[BX_ATT_GROUPS_ATTACH]) ? $aAttachment[BX_ATT_GROUPS_ATTACH] : ''
  1973. );
  1974. return $this -> parseHtmlByName('hidden-jot.html', $aVars);
  1975. }
  1976. /**
  1977. * Returns Video Recording form
  1978. *@param int $iProfile viewer profile id
  1979. *@return string html form
  1980. */
  1981. public function getVideoRecordingForm(){
  1982. return $this -> parseHtmlByName('video-record-form.html', array('max_video_length' => (int)$this->_oConfig->CNF['MAX_VIDEO_LENGTH'] * 60 * 1000));
  1983. }
  1984. function audioPlayer($sUrlMP3, $bReturnBothIfEmpty = false, $aAttrs = false, $sStyles = '')
  1985. {
  1986. $aAttrsDefaults = array(
  1987. 'controls' => '',
  1988. 'loop' => '',
  1989. 'preload' => 'metadata',
  1990. 'download' => true
  1991. );
  1992. if ($bReturnBothIfEmpty && !$sUrlMP3)
  1993. unset($aAttrsDefaults['controls']);
  1994. $aAttrs = array_merge($aAttrsDefaults, is_array($aAttrs) ? $aAttrs : array());
  1995. $sAttrs = bx_convert_array2attrs($aAttrs, '', $sStyles);
  1996. $sLoading = '<img style="max-height:3rem;" src="' . $this->getImageUrl('audio-na.png') . '" />';
  1997. $sAudio = "<audio {$sAttrs}>
  1998. " . ($sUrlMP3 ? '<source type="audio/mp3" src="' . $sUrlMP3 .'" />' : '') . "
  1999. </audio>";
  2000. if ($bReturnBothIfEmpty && !$sUrlMP3)
  2001. return $sLoading . $sAudio;
  2002. return $sUrlMP3 ? $sAudio : $sLoading;
  2003. }
  2004. public function getGiphyPanel(){
  2005. return $this -> parseHtmlByName('giphy-panel.html', [
  2006. 'bx_if:powered_by' => [
  2007. 'condition' => $this->_oConfig->CNF['GIPHY-POWERED-BY'],
  2008. 'content' => []
  2009. ]
  2010. ]);
  2011. }
  2012. public function getGiphyItems($sAction, $sQuery, $fHeight = 0, $iStart = 0){
  2013. $oResult = $this->_oConfig->getGiphyGifs($sAction, $sQuery, $iStart);
  2014. $fGifHeight = $fHeight/200;
  2015. $iTime = time();
  2016. $aResult = array('pagination' => array(), 'content' => '');
  2017. if ($oResult && ($aResult = json_decode($oResult, true))){
  2018. if (!empty($aResult['data'])){
  2019. $aVars['bx_repeat:gifs'] = array();
  2020. foreach($aResult['data'] as &$aGif) {
  2021. $aImage = $aGif['images']['fixed_height'];
  2022. $aVars['bx_repeat:gifs'][] = array(
  2023. 'id' => $aGif['id'],
  2024. 'width' => $aImage['width'] * $fGifHeight,
  2025. 'height' => $fHeight,
  2026. 'gif' => $aGif['id'],
  2027. 'time' => $iTime,
  2028. 'title' => $aGif['title']
  2029. );
  2030. }
  2031. if (!empty($aVars['bx_repeat:gifs']))
  2032. $aResult = array('pagination' => $aResult['pagination'], 'content' => $this->parseHtmlByName('giphy-items.html', $aVars));
  2033. }
  2034. }
  2035. return $aResult;
  2036. }
  2037. public function getJitsi($iLotId, $iProfileId, $aOptions){
  2038. $CNF = &$this->_oConfig->CNF;
  2039. $JITSI = &$CNF['JITSI'];
  2040. $sError = '';
  2041. $aLotInfo = $this->_oDb->getLotInfoById($iLotId);
  2042. if (empty($aLotInfo))
  2043. $sError = MsgBox(_t('_bx_messenger_not_found'));
  2044. if (!$this->_oDb->isParticipant($iLotId, $iProfileId))
  2045. $sError = MsgBox(_t('_bx_messenger_not_participant'));
  2046. if ($sError)
  2047. return BxBaseFunctions::getInstance()->msgBox($sError, 2.5);
  2048. $sTitle = isset($aLotInfo[$CNF['FIELD_TITLE']]) && $aLotInfo[$CNF['FIELD_TITLE']]
  2049. ? $aLotInfo[$CNF['FIELD_TITLE']]
  2050. : $this -> getParticipantsNames($iProfileId, $iLotId);
  2051. $sTitle = _t($sTitle);
  2052. $oProfileInfo = BxDolProfile::getInstance($iProfileId);
  2053. $oLanguage = BxDolStudioLanguagesUtils::getInstance();
  2054. $sLanguage = $oLanguage->getCurrentLangName(false);
  2055. $aJVC = $this->_oDb->getJVC($iLotId);
  2056. $sRoom = empty($aJVC) ? $this->_oConfig->getRoomId($aLotInfo[$CNF['FIELD_ID']], $aLotInfo[$CNF['FIELD_AUTHOR']]) : $aJVC[$CNF['FJVC_ROOM']];
  2057. $mixedJWT = $this->getJWTToken($sRoom, $iProfileId);
  2058. $sCode = $this -> parseHtmlByName('jitsi_video_form.html', array(
  2059. 'id' => $iLotId,
  2060. 'domain' => $this->_oConfig->getValidUrl($CNF['JITSI-SERVER']),
  2061. 'lang' => $sLanguage,
  2062. 'site_title' => bx_js_string(getParam('site_title')),
  2063. 'lib_link' => $this->_oConfig->getValidUrl($CNF['JITSI-SERVER'], 'url') . '/' . $JITSI['LIB-LINK'],
  2064. 'info_enabled' => +$CNF['JITSI-HIDDEN-INFO'],
  2065. 'chat_enabled' => +$CNF['JITSI-CHAT'],
  2066. 'chat_sync' => +$CNF['JITSI-CHAT-SYNC'],
  2067. 'audio_only' => +isset($aOptions['audio_only']),
  2068. 'show_watermark' => +$CNF['JITSI-ENABLE-WATERMARK'],
  2069. 'watermark_url' => $CNF['JITSI-WATERMARK-URL'],
  2070. 'support_link' => $CNF['JITSI-SUPPORT-LINK'],
  2071. 'jitsi_meet_title' => bx_js_string(_t('_bx_messenger_jitsi_meet_app_title', getParam('site_title'))),
  2072. 'user_name' => $oProfileInfo->getDisplayName(),
  2073. 'me' => _t('_bx_messenger_jitsi_meet_me'),
  2074. 'avatar' => $oProfileInfo->getAvatar(),
  2075. 'name' => $sRoom,
  2076. 'title' => bx_js_string(strmaxtextlen($sTitle)),
  2077. 'jwt_token' => $mixedJWT !== false ? $mixedJWT : ''
  2078. ));
  2079. return $sCode;
  2080. }
  2081. public function getPublicJitsi($iProfileId, $sIdent, $sTitle = '', $sId = 'bx-messenger-jitsi', $aInterfaceConfig = array()){
  2082. $CNF = &$this->_oConfig->CNF;
  2083. $JITSI = &$CNF['JITSI'];
  2084. $oProfile = BxDolProfile::getInstance($iProfileId);
  2085. if (empty($oProfile))
  2086. return false;
  2087. $sTitle = $sTitle ? $sTitle : $oProfile->getDisplayName();
  2088. $oLanguage = BxDolStudioLanguagesUtils::getInstance();
  2089. $sLanguage = $oLanguage->getCurrentLangName(false);
  2090. $sRoom = $this->_oConfig->getRoomId($sIdent ? $sIdent : $iProfileId);
  2091. $mixedJWT = $this->getJWTToken($sRoom, $iProfileId);
  2092. return $this -> parseHtmlByName('jitsi_public_video_form.html', array(
  2093. 'domain' => $this->_oConfig->getValidUrl($CNF['JITSI-SERVER']),
  2094. 'lang' => $sLanguage,
  2095. 'site_title' => getParam('site_title'),
  2096. 'lib_link' => $this->_oConfig->getValidUrl($CNF['JITSI-SERVER'], 'url') . '/' . $JITSI['LIB-LINK'],
  2097. 'info_enabled' => +$CNF['JITSI-HIDDEN-INFO'],
  2098. 'chat_enabled' => +$CNF['JITSI-CHAT'],
  2099. 'chat_sync' => +$CNF['JITSI-CHAT-SYNC'],
  2100. 'audio_only' => 0,
  2101. 'show_watermark' => +$CNF['JITSI-ENABLE-WATERMARK'],
  2102. 'watermark_url' => $CNF['JITSI-WATERMARK-URL'],
  2103. 'support_link' => $CNF['JITSI-SUPPORT-LINK'],
  2104. 'jitsi_meet_title' => bx_js_string(_t('_bx_messenger_jitsi_meet_app_title', getParam('site_title'))),
  2105. 'user_name' => $oProfile->getDisplayName(),
  2106. 'me' => _t('_bx_messenger_jitsi_meet_me'),
  2107. 'avatar' => $oProfile->getAvatar(),
  2108. 'name' => $sRoom,
  2109. 'id' => $sId,
  2110. 'title' => bx_js_string(strmaxtextlen($sTitle)),
  2111. 'interface_config' => json_encode($aInterfaceConfig),
  2112. 'jwt_token' => $mixedJWT !== false ? $mixedJWT : ''
  2113. ));
  2114. }
  2115. function getJWTToken($sRoom, $iProfileId){
  2116. $oProfileInfo = BxDolProfile::getInstance( $iProfileId );
  2117. if (empty($oProfileInfo) || !$sRoom)
  2118. return false;
  2119. $CNF = $this->_oConfig->CNF;
  2120. if (empty($CNF['JWT']['app_id']) || empty($CNF['JWT']['secret']))
  2121. return false;
  2122. // Encode Header to Base64Url String
  2123. $sHeader = json_encode(['alg' => 'HS256', 'typ' => 'JWT']);
  2124. $sHeader = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($sHeader));
  2125. // Create token payload as a JSON string
  2126. $sPayload = json_encode(['context' =>
  2127. [
  2128. 'user' => [
  2129. 'avatar' => $oProfileInfo->getThumb(),
  2130. 'name' => $oProfileInfo->getDisplayName(),
  2131. 'email' => $oProfileInfo->getAccountObject()->getEmail()
  2132. ],
  2133. ],
  2134. "aud" => $this->_oConfig->CNF['JITSI-SERVER'],
  2135. "iss" => $CNF['JWT']['app_id'],
  2136. "sub" => $this->_oConfig->CNF['JITSI-SERVER'],
  2137. "room" => $sRoom
  2138. ]);
  2139. $sPayload = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($sPayload));
  2140. // Create Signature Hash
  2141. $sSignature = hash_hmac('sha256', $sHeader . "." . $sPayload, $CNF['JWT']['secret'], true);
  2142. $sSignature = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($sSignature));
  2143. return "{$sHeader}.{$sPayload}.{$sSignature}";
  2144. }
  2145. public function getTalkFiles($iProfileId, $iLotId, $iStart = 0){
  2146. $CNF = &$this->_oConfig->CNF;
  2147. if (!$iLotId || !$iProfileId || !$this->_oDb->isParticipant($iLotId, $iProfileId))
  2148. return MsgBox(_t('_bx_messenger_no_permissions'));
  2149. $sContent = MsgBox(_t('_bx_messenger_txt_msg_no_results'));
  2150. $aFiles = $this -> _oDb -> getLotFiles($iLotId, $iStart, $CNF['PARAM_DEFAULT_TALK_FILES_NUM']);
  2151. if (!empty($aFiles)) {
  2152. $aFilesItems = array();
  2153. foreach ($aFiles as &$aValue) {
  2154. $oOwner = $this->getObjectUser($aValue[$CNF['FIELD_ST_AUTHOR']]);
  2155. $sThumb = $oOwner->getThumb();
  2156. $bThumb = stripos($sThumb, 'no-picture') === FALSE;
  2157. $sDisplayName = $oOwner->getDisplayName();
  2158. $aFilesItems[] = array(
  2159. 'time' => bx_time_js($aValue[$CNF['FIELD_ST_ADDED']], BX_FORMAT_TIME, !$CNF['TIME-FROM-NOW']),
  2160. 'file' => $this->getFileContent($aValue),
  2161. 'url' => $oOwner->getUrl(),
  2162. 'id' => $aValue[$CNF['FIELD_ST_ID']],
  2163. 'username' => $sDisplayName,
  2164. 'bx_if:avatars' => array(
  2165. 'condition' => $bThumb,
  2166. 'content' => array(
  2167. 'thumb' => $sThumb,
  2168. 'title' => $sDisplayName,
  2169. )
  2170. ),
  2171. 'bx_if:letters' => array(
  2172. 'condition' => !$bThumb,
  2173. 'content' => array(
  2174. 'color' => implode(', ', BxDolTemplate::getColorCode($aValue[$CNF['FIELD_ST_AUTHOR']], 1.0)),
  2175. 'letter' => mb_substr($sDisplayName, 0, 1),
  2176. 'title' => $sDisplayName
  2177. )
  2178. ),
  2179. );
  2180. }
  2181. if (!empty($aFilesItems))
  2182. $sContent = $this->parseHtmlByName('files-feeds.html', array('bx_repeat:files' => $aFilesItems));
  2183. }
  2184. return $iStart && !$sContent ? '' : $sContent;
  2185. }
  2186. public function getCallPopup($iLotId, $iProfileId){
  2187. $CNF = &$this->_oConfig->CNF;
  2188. $aLotInfo = $this->_oDb->getLotInfoById($iLotId);
  2189. $aActiveVC = $this->_oDb->getActiveJVCItem($iLotId);
  2190. $oProfile = $this -> getObjectUser($aActiveVC[$CNF['FJVCT_AUTHOR_ID']]);
  2191. if (empty($aLotInfo) || !$this->_oDb->isParticipant($iLotId, $iProfileId) || empty($aActiveVC) || (int)$iProfileId == (int)$aActiveVC[$CNF['FJVCT_AUTHOR_ID']] || !$oProfile)
  2192. return false;
  2193. $sTitle = isset($aLotInfo[$CNF['FIELD_TITLE']]) && $aLotInfo[$CNF['FIELD_TITLE']]
  2194. ? _t($aLotInfo[$CNF['FIELD_TITLE']])
  2195. : $this -> getParticipantsNames($iProfileId, $iLotId);
  2196. $aJVC = $this->_oDb->getJVC($iLotId);
  2197. if (empty($aJVC))
  2198. return MsgBox(_t('_bx_messenger_jitsi_err_vc_was_not_found'));
  2199. $aVars = array(
  2200. 'title' => $sTitle,
  2201. 'thumb' => $oProfile -> getThumb(),
  2202. 'id' => $iLotId,
  2203. 'room' => $aJVC[$CNF['FJVC_ROOM']]
  2204. );
  2205. $sContent = $this->parseHtmlByName('conference_call.html', $aVars);
  2206. return BxTemplFunctions::getInstance()->transBox('bx-messenger-vc-call', $sContent);
  2207. }
  2208. /**
  2209. * Talk settings: available options and the selected ones (all of them when nothing is saved yet).
  2210. * @param int $iLotId
  2211. * @return array ['options' => [['key' => ..., 'value' => ...], ...], 'values' => [...]]
  2212. */
  2213. public function getLotSettingsOptions($iLotId)
  2214. {
  2215. $CNF = &$this->_oConfig->CNF;
  2216. $aSettingsOptions = [];
  2217. $aSelectedValues = [];
  2218. $aLotSettings = $this->_oDb->getLotSettings($iLotId);
  2219. foreach ($CNF['LOT_OPTIONS'] as $sValue) {
  2220. $aSettingsOptions[] = ['key' => $sValue, 'value' => _t("_bx_messenger_lot_options_item_{$sValue}")];
  2221. if ($aLotSettings === false || in_array($sValue, $aLotSettings)) {
  2222. $aSelectedValues[] = $sValue;
  2223. }
  2224. }
  2225. bx_alert($this->_oConfig->getObject('alert'), 'talk_settings_before', $iLotId, $iLotId, [
  2226. 'options' => &$aSettingsOptions,
  2227. 'values' => &$aSelectedValues
  2228. ]);
  2229. return ['options' => $aSettingsOptions, 'values' => $aSelectedValues];
  2230. }
  2231. public function getLotSettingsForm($iLotId){
  2232. $CNF = &$this->_oConfig->CNF;
  2233. $aLotInfo = $this->_oDb->getLotInfoById($iLotId);
  2234. if (empty($aLotInfo) || empty($CNF['LOT_OPTIONS']))
  2235. $sContent = MsgBox(_t('_Empty'));
  2236. else
  2237. {
  2238. ['options' => $aSettingsOptions, 'values' => $aSelectedValues] = $this->getLotSettingsOptions($iLotId);
  2239. $aForm = [
  2240. 'form_attrs' => [
  2241. 'name' => 'lot_options',
  2242. 'method' => 'post',
  2243. 'enctype' => 'multipart/form-data'
  2244. ],
  2245. 'inputs' => [
  2246. 'options' => [
  2247. 'type' => 'checkbox_set',
  2248. 'name' => 'options',
  2249. 'value' => $aSelectedValues,
  2250. 'values' => $aSettingsOptions
  2251. ],
  2252. 'buttons' => [
  2253. 'type' => 'input_set',
  2254. 'attrs_wrapper' => ['class' => 'bx-messenger-options-buttons'],
  2255. [
  2256. 'type' => 'button',
  2257. 'name' => 'save',
  2258. 'value' => _t("_bx_messenger_save_button"),
  2259. 'attrs' => array('onclick' => "javascript:{$CNF['JSMain']}.onSaveLotSettings(this);")
  2260. ],
  2261. [
  2262. 'type' => 'button',
  2263. 'name' => 'close',
  2264. 'value' => _t("_bx_messenger_cancel_button"),
  2265. 'attrs' => array('onclick' => "javascript:$(this).closest('.bx-popup-applied:visible').dolPopupHide();")
  2266. ],
  2267. ]
  2268. ]
  2269. ];
  2270. $oForm = new BxTemplFormView($aForm);
  2271. $sContent = $oForm -> getCode();
  2272. }
  2273. return BxTemplFunctions::getInstance()->popupBox('lot-settings', _t('_bx_messenger_lot_options_title'), $sContent);
  2274. }
  2275. public function getNavGroupsMenu($iProfileId){
  2276. $CNF = $this->_oConfig->CNF;
  2277. $aGroupsList = $this->_oDb->getMyLotsByGroups($iProfileId);
  2278. $aResultGroups = array();
  2279. $i = 0;
  2280. foreach($aGroupsList as $sModule => $aGroups){
  2281. $aResultGroups['bx_repeat:groups'][$i] = array(
  2282. 'module' => _t('_' . $sModule),
  2283. 'module_type' => $sModule,
  2284. );
  2285. foreach($aGroups as &$aGroup){
  2286. $aResultGroups['bx_repeat:groups'][$i]['bx_repeat:module_items'][] = array(
  2287. 'title' => $aGroup[$CNF['FMG_NAME']],
  2288. 'id' => $aGroup[$CNF['FMG_ID']],
  2289. );
  2290. }
  2291. $i++;
  2292. }
  2293. if (empty($aResultGroups))
  2294. return '';
  2295. return $this -> parseHtmlByName('nav-groups-menu.html', $aResultGroups);
  2296. }
  2297. public function getLeftMainMenu(){
  2298. $CNF = &$this->_oConfig->CNF;
  2299. $oLeftMainMenu = BxTemplMenu::getObjectInstance($CNF['OBJECT_MENU_NAV_LEFT_MENU']);
  2300. $oLeftGroupsMenu = BxTemplMenu::getObjectInstance($CNF['OBJECT_MENU_GROUPS_MENU']);
  2301. $bSimpleMode = $this->_oConfig->CNF['USE-UNIQUE-MODE'];
  2302. return bx_is_api() ? [
  2303. 'menu' => $oLeftMainMenu->getMenuItems(),
  2304. 'nav_groups_menu' => $oLeftGroupsMenu->getMenuItems()
  2305. ] :
  2306. $this -> parseHtmlByName('left-nav-menu.html', array(
  2307. 'menu' => $oLeftMainMenu -> getCode(),
  2308. 'nav_groups_menu' => $oLeftGroupsMenu -> getCode(),
  2309. 'js_code' => $CNF['JSMain'],
  2310. 'menu_width' => !$bSimpleMode ? 'xl:block xl:col-span-2': ''
  2311. ));
  2312. }
  2313. public function getInfoSection($sType = 'info', $iProfileId = 0){
  2314. $CNF = &$this->_oConfig->CNF;
  2315. return $this -> parseHtmlByName('info-section.html', array(
  2316. 'info' => ''
  2317. ));
  2318. }
  2319. public function getCreateGroupsForm($iProfileId, $iGroupId = 0){
  2320. $CNF = &$this->_oConfig->CNF;
  2321. $oPrivacy = BxDolPrivacy::getObjectInstance($CNF['OBJECT_PRIVACY_GROUPS']);
  2322. $aPrivacy = $oPrivacy->getGroupChooser($CNF['OBJECT_PRIVACY_GROUPS'], $iProfileId);
  2323. $aForm = array(
  2324. 'form_attrs' => array(
  2325. 'name' => 'create_groups',
  2326. 'method' => 'post',
  2327. 'enctype' => 'multipart/form-data'
  2328. ),
  2329. 'inputs' => array(
  2330. 'id' => array(
  2331. 'type' => 'hidden',
  2332. 'name' => 'id',
  2333. 'value' => $iGroupId,
  2334. ),
  2335. 'name' => array(
  2336. 'type' => 'text',
  2337. 'name' => 'name',
  2338. 'caption' => _t('_bx_messenger_groups_name'),
  2339. 'info' => _t('_bx_messenger_groups_name_info'),
  2340. ),
  2341. 'desc' => array(
  2342. 'type' => 'text',
  2343. 'name' => 'desc',
  2344. 'caption' => _t('_bx_messenger_groups_desc'),
  2345. 'info' => _t('_bx_messenger_groups_desc_info'),
  2346. ),
  2347. 'privacy' => $aPrivacy,
  2348. 'options' => array(
  2349. 'type' => 'input_set',
  2350. 'dv' => '<br/>'
  2351. ),
  2352. 'buttons' => array(
  2353. 'type' => 'input_set',
  2354. 'attrs_wrapper' => array('class' => 'bx-messenger-options-buttons'),
  2355. array(
  2356. 'type' => 'button',
  2357. 'name' => 'save',
  2358. 'value' => _t("_bx_messenger_save_button"),
  2359. 'attrs' => array('onclick' => "javascript:{$CNF['JSMessengerLib']}.onSaveGroup(this);")
  2360. ),
  2361. array(
  2362. 'type' => 'button',
  2363. 'name' => 'close',
  2364. 'value' => _t("_bx_messenger_cancel_button"),
  2365. 'attrs' => array('onclick' => "javascript:$(this).closest('.bx-popup-applied:visible').dolPopupHide();")
  2366. ),
  2367. )
  2368. )
  2369. );
  2370. $oForm = new BxTemplFormView($aForm);
  2371. $sContent = $oForm -> getCode();
  2372. return BxTemplFunctions::getInstance()->popupBox('groups-form', _t('_bx_messenger_groups_create_form_title'), $sContent);
  2373. }
  2374. function getTalksList($iLotId){
  2375. $CNF = &$this->_oConfig->CNF;
  2376. $sList = _t('_Empty');
  2377. $iProfileId = bx_get_logged_profile_id();
  2378. if ($iGroupId = $this->_oDb->getGroupIdByLotId($iLotId)){
  2379. $aGroupsList = $this->_oDb->getTalksByGroupId($iGroupId);
  2380. if (!empty($aGroupsList)){
  2381. unset($aGroupsList[$iLotId]);
  2382. foreach($aGroupsList as $iKey => $aItem) {
  2383. if (!$this->_oDb->isParticipant($aGroupsList[$iKey][$CNF['FIELD_ID']], $iProfileId) && (int)$aGroupsList[$iKey][$CNF['FIELD_TYPE']] !== BX_IM_TYPE_PUBLIC)
  2384. continue;
  2385. $aGroupsList[$iKey][$CNF['FIELD_TITLE']] = _t($aItem[$CNF['FIELD_TITLE']]);
  2386. }
  2387. $sList = $this->parseHtmlByName('groups-list-item.html', array(
  2388. 'bx_repeat:list' => $aGroupsList
  2389. ));
  2390. }
  2391. }
  2392. return $this->parseHtmlByName('groups-list.html', array(
  2393. 'list' => $sList
  2394. ));
  2395. }
  2396. function getThreadReply($iJotId){
  2397. $CNF = &$this->_oConfig->CNF;
  2398. $aParentLotInfo = $this->_oDb->getLotByParentId($iJotId);
  2399. $iReplies = !empty($aParentLotInfo) ? $this->_oDb->getJotReplies($aParentLotInfo[$CNF['FIELD_ID']], true) : 0;
  2400. return $iReplies ? $this->parseHtmlByName('thread-reply.html', array(
  2401. 'replies' => $iReplies
  2402. )) : '';
  2403. }
  2404. function getContacts($iProfileId, $aParams = []){
  2405. $aLotsList = $this->_oDb->getMyLots($iProfileId, ['type' => BX_IM_TYPE_PRIVATE]);
  2406. if (empty($aLotsList))
  2407. return [];
  2408. $CNF = &$this->_oConfig->CNF;
  2409. $aVars = $aResult = $aContacts = [];
  2410. foreach($aLotsList as &$aItem){
  2411. $aList = explode(',', $aItem[$CNF['FIELD_PARTICIPANTS']]);
  2412. if (!empty($aList)) {
  2413. foreach ($aList as &$iPart) {
  2414. if ($iPart === $iProfileId || array_key_exists($iPart, $aContacts))
  2415. continue;
  2416. $aContacts[$iPart] = BxDolProfile::getInstance($iPart)->isOnline();
  2417. }
  2418. }
  2419. if (count($aContacts) >= $CNF['PARAM_CONTACTS_NUM_BY_DEFAULT'])
  2420. break;
  2421. }
  2422. foreach($aContacts as $iProfileId => $iStatus) {
  2423. $oProfile = BxDolProfile::getInstance($iProfileId);
  2424. if (bx_is_api())
  2425. $aResult[] = $oProfile->getData($iProfileId);
  2426. else
  2427. {
  2428. $sThumb = $oProfile->getThumb();
  2429. $bThumb = stripos($sThumb, 'no-picture') === FALSE;
  2430. $sTitle = $oProfile->getDisplayName();
  2431. $aVars['bx_repeat:contacts'][] = [
  2432. 'status' => $this->getOnlineStatus($iProfileId, $iStatus),
  2433. 'url' => $oProfile->getUrl(),
  2434. 'displyname' => $oProfile->getDisplayName(),
  2435. 'bx_if:avatars' => [
  2436. 'condition' => $bThumb,
  2437. 'content' => [
  2438. 'title' => $sTitle,
  2439. 'thumb' => $sThumb,
  2440. ]
  2441. ],
  2442. 'bx_if:letters' => [
  2443. 'condition' => !$bThumb,
  2444. 'content' => [
  2445. 'color' => implode(', ', BxDolTemplate::getColorCode($iProfileId, 1.0)),
  2446. 'letter' => mb_substr($sTitle, 0, 1)
  2447. ]
  2448. ],
  2449. ];
  2450. }
  2451. }
  2452. return bx_is_api() ? $aResult : $this->parseHtmlByName('contacts-block.html', $aVars);
  2453. }
  2454. function getConnectionsForm($sType, $iProfileId){
  2455. $sText = MsgBox(_t("_bx_messenger_filter_criteria_on_$sType"));
  2456. if ($oConnection = $this->_oConfig->getConnectionByType($sType)) {
  2457. $sText = MsgBox(_t("_bx_messenger_filter_criteria_on_$sType"));
  2458. if ($iCount = $oConnection->getConnectedContentCount($iProfileId, $sType === 'friends'))
  2459. $sText = MsgBox(_t("_bx_messenger_filter_criteria_{$sType}_message", $iCount));
  2460. }
  2461. $CNF = &$this->_oConfig->CNF;
  2462. $aNotifFields = $this->getNotificationFormData();
  2463. $aForm = [
  2464. 'form_attrs' => [
  2465. 'method' => 'post',
  2466. 'id' => $CNF['OBJECT_FORM_ENTRY'],
  2467. 'class' => 'space-y-4 max-h-60 overflow-y-auto'
  2468. ],
  2469. 'inputs' => array_merge([
  2470. 'type' => [
  2471. 'type' => 'hidden',
  2472. 'name' => 'connection_type',
  2473. 'value' => $sType
  2474. ],
  2475. 'action' => [
  2476. 'type' => 'custom',
  2477. 'content' => $sText,
  2478. ]
  2479. ], $aNotifFields)
  2480. ];
  2481. $oForm = new BxTemplFormView($aForm);
  2482. return $oForm -> getCode();
  2483. }
  2484. function getInfoBlockContent($iLotId){
  2485. if (!($aLotInfo = $this->_oDb->getLotInfoById($iLotId)))
  2486. return '';
  2487. $CNF = $this->_oConfig->CNF;
  2488. if (!($oProfile = $this->getObjectUser($aLotInfo[$CNF['FIELD_AUTHOR']])))
  2489. return '';
  2490. $sThumb = $oProfile->getAvatar();
  2491. $bThumb = stripos($sThumb, 'no-picture') === FALSE;
  2492. $sDisplayName = $oProfile->getDisplayName();
  2493. $aPartList = $this->_oDb->getParticipantsList($iLotId);
  2494. if ((int)$aLotInfo[$CNF['FIELD_TYPE']] === BX_IM_TYPE_BROADCAST)
  2495. $aPartList = $this->_oDb->getBroadcastParticipants($iLotId);
  2496. $iPartCount = count($aPartList);
  2497. $iFilesCount = $this->_oDb->getLotFilesCount($iLotId);
  2498. $iMessagesCount = $this->_oDb->getJotsNumber($iLotId, 0);
  2499. $aItem = [
  2500. 'parts' => $iPartCount,
  2501. 'files' => $iFilesCount,
  2502. 'messages' => $iMessagesCount,
  2503. 'profile_url' => $oProfile->getUrl()
  2504. ];
  2505. $aItem = array_merge($aItem,[
  2506. 'name' => $sDisplayName,
  2507. 'id' => $oProfile -> id(),
  2508. 'bx_if:avatars' => array(
  2509. 'condition' => $bThumb,
  2510. 'content' => array(
  2511. 'thumb' => $sThumb,
  2512. 'title' => $sDisplayName,
  2513. )
  2514. ),
  2515. 'bx_if:letters' => array(
  2516. 'condition' => !$bThumb,
  2517. 'content' => array(
  2518. 'color' => implode(', ', BxDolTemplate::getColorCode($aLotInfo[$CNF['FIELD_AUTHOR']], 1.0)),
  2519. 'title' => $sDisplayName,
  2520. 'letter' => mb_substr($sDisplayName, 0, 1)
  2521. )
  2522. )
  2523. ]);
  2524. $sContent = '';
  2525. bx_alert($this->_oConfig->getObject('alert'), 'talk_info_before', $iLotId, $iLotId, [
  2526. 'content' => &$sContent
  2527. ]);
  2528. $aItem['content'] = $sContent;
  2529. return $this->parseHtmlByName('talk-info.html', $aItem);
  2530. }
  2531. private function getEmptyMessageTemplate($aData){
  2532. $aVars = [
  2533. 'title' => '',
  2534. 'url' => '',
  2535. 'thumb' => '',
  2536. 'display' => '',
  2537. 'display_message' => '',
  2538. 'id' => 0,
  2539. 'new' => '',
  2540. 'my' => 1,
  2541. 'message' => '',
  2542. 'attachment' => '',
  2543. 'reply' => '',
  2544. 'bx_if:show_author' => [
  2545. 'condition' => false,
  2546. 'content' => [
  2547. 'url' => '',
  2548. 'bx_if:avatars' => [
  2549. 'condition' => false,
  2550. 'content' => [
  2551. 'thumb' => '',
  2552. 'title' => '',
  2553. ]
  2554. ],
  2555. 'bx_if:letters' => array(
  2556. 'condition' => false,
  2557. 'content' => array(
  2558. 'color' => '',
  2559. 'letter' => ''
  2560. )
  2561. ),
  2562. ]
  2563. ],
  2564. 'bx_if:show_title' => array(
  2565. 'condition' => false,
  2566. 'content' => array(
  2567. 'title' => '',
  2568. )
  2569. ),
  2570. 'bx_if:jot_menu' => array(
  2571. 'condition' => false,
  2572. 'content' => array(
  2573. 'jot_menu' => ''
  2574. )
  2575. ),
  2576. 'bx_if:time-separator' => array(
  2577. 'condition' => false,
  2578. 'content' => array(
  2579. 'date' => '',
  2580. )
  2581. ),
  2582. 'thread_replies' => '',
  2583. 'bx_if:show_reactions_area' => array(
  2584. 'condition' => false,
  2585. 'content' => array(
  2586. 'bx_if:reactions' => array(
  2587. 'condition' => false,
  2588. 'content' => array(
  2589. 'reactions' => '',
  2590. 'bx_if:reactions_menu' => array(
  2591. 'condition' => false,
  2592. 'content' => array(
  2593. 'display' => 'none',
  2594. )
  2595. ),
  2596. )
  2597. ),
  2598. 'bx_if:edit' => array(
  2599. 'condition' => false,
  2600. 'content' => array()
  2601. ),
  2602. )
  2603. ),
  2604. 'bx_if:blink-jot' => array(
  2605. 'condition' => false,
  2606. 'content' => array()
  2607. ),
  2608. 'bx_if:new' => array(
  2609. 'condition' => false,
  2610. 'content' => []
  2611. ),
  2612. 'icons' => '',
  2613. 'edit_icon' => '',
  2614. 'reactions' => '',
  2615. 'action_icon' => '',
  2616. 'view_in_chat' => '',
  2617. 'message_class' => 'hidden'
  2618. ];
  2619. return array_merge($aVars, $aData);
  2620. }
  2621. }
  2622. /** @} */