BxEventsModule.php 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634
  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 Events Events
  7. * @ingroup UnaModules
  8. *
  9. * @{
  10. */
  11. use Spatie\CalendarLinks\Link;
  12. /**
  13. * Events profiles module.
  14. */
  15. class BxEventsModule extends BxBaseModGroupsModule implements iBxDolCalendarService
  16. {
  17. function __construct(&$aModule)
  18. {
  19. parent::__construct($aModule);
  20. $CNF = &$this->_oConfig->CNF;
  21. $this->_aSearchableNamesExcept = array_merge($this->_aSearchableNamesExcept, array(
  22. $CNF['FIELD_TIMEZONE'],
  23. $CNF['FIELD_JOIN_CONFIRMATION'],
  24. $CNF['FIELD_REMINDER']
  25. ));
  26. }
  27. public function actionCalendarSync($iContentId = 0)
  28. {
  29. $aContentInfo = (int)$iContentId ? $this->_oDb->getContentInfoById((int)$iContentId) : null;
  30. if (!$aContentInfo) {
  31. $this->_oTemplate->displayPageNotFound();
  32. exit;
  33. }
  34. if (CHECK_ACTION_RESULT_ALLOWED !== $this->checkAllowedView($aContentInfo)) {
  35. $this->_oTemplate->displayAccessDenied();
  36. exit;
  37. }
  38. $CNF = $this->_oConfig->CNF;
  39. if (!isset($aContentInfo['date_start']) || !$aContentInfo['date_start'] || !isset($aContentInfo['date_end']) || !$aContentInfo['date_end'] || !$aContentInfo[$CNF['FIELD_TIMEZONE']] || empty($CNF['OBJECT_METATAGS'])) {
  40. $this->_oTemplate->displayPageNotFound();
  41. exit;
  42. }
  43. $oMetatags = BxDolMetatags::getObjectInstance($CNF['OBJECT_METATAGS']);
  44. $sLocation = $oMetatags && $oMetatags->locationsIsEnabled() ? $oMetatags->locationsString($aContentInfo[$CNF['FIELD_ID']], false) : '';
  45. $oDateStart = new DateTime('@' . $aContentInfo['date_start']);
  46. $oDateEnd = new DateTime('@' . ($aContentInfo['date_end'] > $aContentInfo['repeat_stop'] ? $aContentInfo['date_end'] : $aContentInfo['repeat_stop']));
  47. $oTz = new DateTimeZone($aContentInfo[$CNF['FIELD_TIMEZONE']]);
  48. $oDateStart->setTimezone($oTz);
  49. $oDateEnd->setTimezone($oTz);
  50. $oICalLink = $oDateStart && $oDateEnd ? Link::create(
  51. $aContentInfo[$CNF['FIELD_TITLE']],
  52. $oDateStart,
  53. $oDateEnd
  54. ) : null;
  55. if ($sLocation)
  56. $oICalLink->address($sLocation);
  57. $s = $oICalLink->ics();
  58. if (!preg_match('/^data:([a-zA-Z0-9\/]+);charset=[a-zA-Z0-9]+;base64,(.*)$/', $s, $m)) {
  59. $this->_oTemplate->displayErrorOccured();
  60. exit;
  61. }
  62. header('Content-type: ' . $m[1] . '; charset=utf-8');
  63. header('Content-Disposition: inline; filename="event.ics"');
  64. echo base64_decode($m[2]);
  65. }
  66. public function actionCalendarData()
  67. {
  68. // check permissions
  69. $aSQLPart = array();
  70. $iContentId = (int)bx_get('event');
  71. $iContextId = (int)bx_get('context_id');
  72. if ($iContentId) {
  73. $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
  74. if (CHECK_ACTION_RESULT_ALLOWED !== $this->checkAllowedView($aContentInfo)) {
  75. $this->_oTemplate->displayAccessDenied();
  76. exit;
  77. }
  78. $aSQLPart = array();
  79. }
  80. else {
  81. $oPrivacy = BxDolPrivacy::getObjectInstance($this->_oConfig->CNF['OBJECT_PRIVACY_VIEW']);
  82. if($iContextId){
  83. if (!$this->serviceIsEnableForContext($iContextId)){
  84. exit;
  85. }
  86. else{
  87. $aSQLPart = $oPrivacy ? $oPrivacy->getContentByGroupAsSQLPart(- $iContextId) : array();
  88. }
  89. }
  90. else{
  91. $aSQLPart = $oPrivacy ? $oPrivacy->getContentPublicAsSQLPart(0, $oPrivacy->getPartiallyVisiblePrivacyGroups()) : array();
  92. }
  93. }
  94. // get entries
  95. $aEntries = $this->_oDb->getEntriesByDate(bx_get('start'), bx_get('end'), bx_get('event'), $aSQLPart);
  96. bx_alert($this->getName(), 'calendar_data', 0, false, array(
  97. 'event' => $iContentId,
  98. 'context_id' => $iContextId,
  99. 'start' => bx_get('start'),
  100. 'end' => bx_get('end'),
  101. 'sql_part' => &$aSQLPart,
  102. 'data' => &$aEntries,
  103. ));
  104. header('Content-Type: application/json; charset=utf-8');
  105. echo json_encode($aEntries);
  106. }
  107. public function serviceIsIcalExportAvaliable($iContentId)
  108. {
  109. return true;
  110. $aContentInfo = $iContentId ? $this->_oDb->getContentInfoById($iContentId) : false;
  111. if ($aContentInfo)
  112. return false;
  113. return $aContentInfo['date_start'] && $aContentInfo['date_end'];
  114. }
  115. public function decodeDataAPI($aData, $aParams = [])
  116. {
  117. $CNF = $this->_oConfig->CNF;
  118. $aResult = parent::decodeDataAPI($aData, $aParams);
  119. $aResult = array_merge($aResult, [
  120. 'date_start' => $aData[$CNF['FIELD_DATE_START']],
  121. 'date_end' => $aData[$CNF['FIELD_DATE_END']]
  122. ]);
  123. return $aResult;
  124. }
  125. public function serviceGetCalendarEntries($iProfileId)
  126. {
  127. $CNF = &$this->_oConfig->CNF;
  128. $oConn = BxDolConnection::getObjectInstance($CNF['OBJECT_CONNECTIONS']);
  129. $aData = $oConn->getConnectedContent($iProfileId);
  130. $aData2 = array(0);
  131. foreach($aData as $iProfileId2){
  132. $oProfile = BxDolProfile::getInstance($iProfileId2);
  133. array_push($aData2, $oProfile->getContentId());
  134. }
  135. $aSQLPart['where'] = " AND `bx_events_data`.`id` IN(" . implode(',', $aData2) . ")";
  136. return $this->_oDb->getEntriesByDate(bx_get('start'), bx_get('end'), null, $aSQLPart);
  137. }
  138. public function serviceGetSafeServices()
  139. {
  140. $a = parent::serviceGetSafeServices();
  141. return array_merge($a, array (
  142. 'BrowsePastProfiles' => '',
  143. 'Calendar' => '',
  144. ));
  145. }
  146. /**
  147. * @page service Service Calls
  148. * @section bx_events Events
  149. * @subsection bx_events-browse Browse
  150. * @subsubsection bx_events-browse_upcoming_profiles browse_upcoming_profiles
  151. *
  152. * @code bx_srv('bx_events', 'browse_upcoming_profiles', [...]); @endcode
  153. *
  154. * Browse upcoming events
  155. *
  156. * @param $bDisplayEmptyMsg show "empty" message or not if nothing found
  157. * @param $bAjaxPaginate use AJAX paginate or not
  158. *
  159. * @see BxEventsModule::serviceBrowseUpcomingProfiles
  160. */
  161. /**
  162. * @ref bx_events-browse_upcoming_profiles "browse_upcoming_profiles"
  163. */
  164. public function serviceBrowseUpcomingProfiles ($aParams = false)
  165. {
  166. $bDisplayEmptyMsg = false;
  167. if(isset($aParams['empty_message'])) {
  168. $bDisplayEmptyMsg = (bool)$aParams['empty_message'];
  169. unset($aParams['empty_message']);
  170. }
  171. $bAjaxPaginate = true;
  172. if(isset($aParams['ajax_paginate'])) {
  173. $bAjaxPaginate = (bool)$aParams['ajax_paginate'];
  174. unset($aParams['ajax_paginate']);
  175. }
  176. return $this->_serviceBrowse ('upcoming', $aParams, BX_DB_PADDING_DEF, $bDisplayEmptyMsg, $bAjaxPaginate);
  177. }
  178. /**
  179. * @page service Service Calls
  180. * @section bx_events Events
  181. * @subsection bx_events-browse Browse
  182. * @subsubsection bx_events-browse_upcoming_connected_profiles browse_upcoming_connected_profiles
  183. *
  184. * @code bx_srv('bx_events', 'browse_upcoming_connected_profiles', [...]); @endcode
  185. *
  186. * Browse upcoming connected (followed) events
  187. *
  188. * @param $bDisplayEmptyMsg show "empty" message or not if nothing found
  189. * @param $bAjaxPaginate use AJAX paginate or not
  190. *
  191. * @see BxEventsModule::serviceBrowseUpcomingConnectedProfiles
  192. */
  193. /**
  194. * @ref bx_events-browse_upcoming_connected_profiles "browse_upcoming_connected_profiles"
  195. */
  196. public function serviceBrowseUpcomingConnectedProfiles ($aParams = false)
  197. {
  198. if(!is_array($aParams) || empty($aParams['object']) || empty($aParams['profile']))
  199. return '';
  200. $bDisplayEmptyMsg = false;
  201. if(isset($aParams['empty_message'])) {
  202. $bDisplayEmptyMsg = (bool)$aParams['empty_message'];
  203. unset($aParams['empty_message']);
  204. }
  205. $bAjaxPaginate = true;
  206. if(isset($aParams['ajax_paginate'])) {
  207. $bAjaxPaginate = (bool)$aParams['ajax_paginate'];
  208. unset($aParams['ajax_paginate']);
  209. }
  210. $aDefaults = array(
  211. 'type' => 'content',
  212. 'mutual' => false,
  213. 'profile2' => 0
  214. );
  215. return $this->_serviceBrowse ('upcoming_connected', array_merge($aDefaults, $aParams), BX_DB_PADDING_DEF, $bDisplayEmptyMsg, $bAjaxPaginate);
  216. }
  217. /**
  218. * @page service Service Calls
  219. * @section bx_events Events
  220. * @subsection bx_events-browse Browse
  221. * @subsubsection bx_events-browse_past_profiles browse_past_profiles
  222. *
  223. * @code bx_srv('bx_events', 'browse_past_profiles', [...]); @endcode
  224. *
  225. * Browse past events
  226. *
  227. * @param $bDisplayEmptyMsg show "empty" message or not if nothing found
  228. * @param $bAjaxPaginate use AJAX paginate or not
  229. *
  230. * @see BxEventsModule::serviceBrowsePastProfiles
  231. */
  232. /**
  233. * @ref bx_events-browse_past_profiles "browse_past_profiles"
  234. */
  235. public function serviceBrowsePastProfiles ($bDisplayEmptyMsg = false, $bAjaxPaginate = true)
  236. {
  237. return $this->_serviceBrowse ('past', false, BX_DB_PADDING_DEF, $bDisplayEmptyMsg, $bAjaxPaginate);
  238. }
  239. /**
  240. * @page service Service Calls
  241. * @section bx_events Events
  242. * @subsection bx_events-browse Browse
  243. * @subsubsection bx_events-browse_past_profiles browse_past_profiles_by_params
  244. *
  245. * @code bx_srv('bx_events', 'browse_past_profiles_by_params', [...]); @endcode
  246. *
  247. * Browse past events
  248. *
  249. * @param $aParams array with all parameters
  250. *
  251. * @see BxEventsModule::serviceBrowsePastProfilesByParams
  252. */
  253. /**
  254. * @ref bx_events-browse_past_profiles_by_params "browse_past_profiles_by_params"
  255. */
  256. public function serviceBrowsePastProfilesByParams ($aParams)
  257. {
  258. $bDisplayEmptyMsg = false;
  259. if(isset($aParams['empty_message'])) {
  260. $bDisplayEmptyMsg = (bool)$aParams['empty_message'];
  261. unset($aParams['empty_message']);
  262. }
  263. $bAjaxPaginate = true;
  264. if(isset($aParams['ajax_paginate'])) {
  265. $bAjaxPaginate = (bool)$aParams['ajax_paginate'];
  266. unset($aParams['ajax_paginate']);
  267. }
  268. return $this->_serviceBrowse ('past', $aParams, BX_DB_PADDING_DEF, $bDisplayEmptyMsg, $bAjaxPaginate);
  269. }
  270. /**
  271. * @page service Service Calls
  272. * @section bx_events Events
  273. * @subsection bx_events-page_blocks Page Blocks
  274. * @subsubsection bx_events-calendar calendar
  275. *
  276. * @code bx_srv('bx_events', 'calendar', [...]); @endcode
  277. *
  278. * Shows event or events calendar
  279. *
  280. * @param $aData additional data to point which events to show, leave empty to show all events, specify event's ID in 'event' array key to show calendar for one event only, specify context's ID in 'context_id' array key to show calendar for one context events only. If only one event is specified then it will show calendar only if it's repeating event.
  281. * @param $sTemplate template to use to show calendar, or leave empty for default template, possible options: calendar.html, calendar_compact.html
  282. * @return HTML string with calendar to display on the site, all necessary CSS and JS files are automatically added to the HEAD section of the site HTML. On error empty string is returned.
  283. *
  284. * @see BxEventsModule::serviceCalendar
  285. */
  286. /**
  287. * @ref bx_events-calendar "calendar"
  288. */
  289. public function serviceCalendar($aData = array(), $sTemplate = 'calendar.html')
  290. {
  291. if(isset($aData['context_id']) && !$this->serviceIsEnableForContext($aData['context_id']))
  292. return '';
  293. $oCalendar = new BxTemplCalendar([
  294. 'eventSources' => [
  295. bx_append_url_params(BX_DOL_URL_ROOT . $this->_oConfig->getBaseUri() . 'calendar_data', $aData),
  296. ],
  297. ], $this->_oTemplate);
  298. $this->_oTemplate->addCss(['main.css']);
  299. return $oCalendar->display($sTemplate);
  300. }
  301. /**
  302. * @page service Service Calls
  303. * @section bx_events Events
  304. * @subsection bx_events-other Other
  305. * @subsubsection bx_events-process_reminders process_reminders
  306. *
  307. * @code bx_srv('bx_events', 'process_reminders'); @endcode
  308. *
  309. * Send remiders to event's participants.
  310. *
  311. * It must be processed once every hour for the proper processing.
  312. * @return nothing
  313. *
  314. * @see BxEventsModule::serviceProcessReminders
  315. */
  316. /**
  317. * @ref bx_events-process_reminders "process_reminders"
  318. */
  319. public function serviceProcessReminders()
  320. {
  321. $CNF = &$this->_oConfig->CNF;
  322. $iNow = time();
  323. $bUseIn = $this->_oConfig->isInternalNotifications();
  324. $sModule = $this->getName();
  325. // get all events for today and tomorrow, since the max reminder is 24 hours
  326. $aEntries = $this->_oDb->getEntriesByDate('@' . time(), '@' . (time() + 3600 * getParam('bx_events_reminder_interval')));
  327. foreach($aEntries as $aEntry) {
  328. $aReminders = $bUseIn ? [$aEntry['reminder']] : [24, 1];
  329. if(!$aReminders)
  330. continue;
  331. $oEventProfile = BxDolProfile::getInstanceByContentAndType($aEntry[$CNF['FIELD_ID']], $sModule);
  332. if(!$oEventProfile)
  333. continue;
  334. $iEventProfileId = $oEventProfile->id();
  335. foreach($aReminders as $iReminder) {
  336. $iTimestamp = $aEntry['start_utc'] - (3600 * $iReminder);
  337. if($iNow <= ($iTimestamp - 3600) || $iNow >= $iTimestamp)
  338. continue;
  339. if($bUseIn)
  340. $this->sendReminders($aEntry);
  341. bx_alert($sModule, 'reminder', $aEntry[$CNF['FIELD_ID']], $iEventProfileId, array(
  342. 'object_author_id' => $iEventProfileId,
  343. 'reminder' => $iReminder
  344. ));
  345. }
  346. }
  347. }
  348. public function serviceGetNotificationsData()
  349. {
  350. $CNF = &$this->_oConfig->CNF;
  351. $aResults = parent::serviceGetNotificationsData();
  352. $sModule = $this->_aModule['name'];
  353. $aSettingsTypes = ['follow_context'];
  354. $aResults['handlers'] = array_merge($aResults['handlers'], [
  355. ['group' => $sModule . '_reminder', 'type' => 'insert', 'alert_unit' => $sModule, 'alert_action' => 'reminder', 'module_name' => $sModule, 'module_method' => 'get_notifications_reminder', 'module_class' => 'Module', 'module_event_privacy' => $CNF['OBJECT_PRIVACY_VIEW_NOTIFICATION_EVENT']],
  356. ]);
  357. $aResults['settings'] = array_merge($aResults['settings'], [
  358. ['group' => 'reminder', 'unit' => $sModule, 'action' => 'reminder', 'types' => $aSettingsTypes],
  359. ]);
  360. $aResults['alerts'] = array_merge($aResults['alerts'], [
  361. ['unit' => $sModule, 'action' => 'reminder'],
  362. ]);
  363. return $aResults;
  364. }
  365. public function serviceGetNotificationsInsertData($oAlert, $aHandler, $aDataItems)
  366. {
  367. if($oAlert->sAction != 'reminder' || empty($aDataItems) || !is_array($aDataItems) || empty($oAlert->aExtras['reminder']))
  368. return $aDataItems;
  369. foreach($aDataItems as $iIndex => $aDataItem) {
  370. $aContent = [];
  371. if(!empty($aDataItem['content']))
  372. $aContent = unserialize($aDataItem['content']);
  373. $aContent['reminder'] = (int)$oAlert->aExtras['reminder'];
  374. $aDataItems[$iIndex]['content'] = serialize($aContent);
  375. }
  376. return $aDataItems;
  377. }
  378. public function serviceGetNotificationsReminder($aEvent)
  379. {
  380. $CNF = &$this->_oConfig->CNF;
  381. if(!isset($aEvent['content']['reminder']))
  382. return [];
  383. $iContentId = (int)$aEvent['object_id'];
  384. $oEventProfile = BxDolProfile::getInstanceByContentAndType((int)$iContentId, $this->getName());
  385. if(!$oEventProfile)
  386. return [];
  387. $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
  388. if(empty($aContentInfo) || !is_array($aContentInfo))
  389. return [];
  390. return [
  391. 'entry_sample' => $CNF['T']['txt_sample_single'],
  392. 'entry_url' => bx_absolute_url(str_replace(BX_DOL_URL_ROOT, '', $oEventProfile->getUrl()), '{bx_url_root}'),
  393. 'entry_caption' => $oEventProfile->getDisplayName(),
  394. 'entry_author' => $oEventProfile->id(),
  395. 'lang_key' => '_bx_events_txt_ntfs_reminder_' . $aEvent['content']['reminder']
  396. ];
  397. }
  398. /**
  399. * @page service Service Calls
  400. * @section bx_events Events
  401. * @subsection bx_events-internal Internal
  402. * @subsubsection bx_events-get_timeline_post get_timeline_post
  403. *
  404. * @code bx_srv('bx_events', 'get_timeline_post', [...]); @endcode
  405. *
  406. * Get Timeline post. It's needed for Timeline module.
  407. *
  408. * @param $aEvent timeline event array from Timeline module
  409. * @return array in special format which is needed specifically for Timeline module to display the data.
  410. *
  411. * @see BxEventsModule::serviceGetTimelinePost
  412. */
  413. /**
  414. * @ref bx_events-get_timeline_post "get_timeline_post"
  415. */
  416. public function serviceGetTimelinePost($aEvent, $aBrowseParams = array())
  417. {
  418. $a = parent::serviceGetTimelinePost($aEvent, $aBrowseParams);
  419. if($a === false)
  420. return false;
  421. $aContentInfo = $this->_oDb->getContentInfoById($aEvent['object_id']);
  422. if(empty($aContentInfo) || !is_array($aContentInfo))
  423. return $a;
  424. $CNF = $this->_oConfig->CNF;
  425. $oDateStart = date_create('@' . $aContentInfo['date_start']);
  426. if ($oDateStart)
  427. $oDateStart->setTimezone(new DateTimeZone($aContentInfo['timezone'] ? $aContentInfo['timezone'] : 'UTC'));
  428. $oMetatags = BxDolMetatags::getObjectInstance($CNF['OBJECT_METATAGS']);
  429. $sLocationString = $oMetatags ? $oMetatags->locationsString($aContentInfo[$CNF['FIELD_ID']], false) : false;
  430. $a['content']['raw'] = $this->_oTemplate->parseHtmlByName('timeline_post.html', [
  431. 'title' => $a['content']['title'],
  432. 'title_attr' => bx_html_attribute($a['content']['title']),
  433. 'url' => $a['content']['url'],
  434. 'bx_if:date' => [
  435. 'condition' => $oDateStart,
  436. 'content' => [
  437. 'date' => $oDateStart ? bx_time_js($aContentInfo['date_start'], BX_FORMAT_DATE_TIME, true) : '',
  438. 'date_c' => $oDateStart->format('c'),
  439. ]],
  440. 'bx_if:location' => array(
  441. 'condition' => !!$sLocationString,
  442. 'content' => array('location' => $sLocationString),
  443. ),
  444. ]);
  445. return $a;
  446. }
  447. public function actionIntervals()
  448. {
  449. $sAction = bx_get('a');
  450. $sMethodName = 'subaction' . ucfirst($sAction);
  451. if (!method_exists($this, $sMethodName)) {
  452. $this->_oTemplate->pageNotFound();
  453. return;
  454. }
  455. $this->$sMethodName();
  456. }
  457. public function subactionRestore($iContentId = 0)
  458. {
  459. if (!$iContentId)
  460. $iContentId = (int)bx_get('c');
  461. $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
  462. if (
  463. ($aContentInfo && CHECK_ACTION_RESULT_ALLOWED !== $this->checkAllowedEdit ($aContentInfo))
  464. ||
  465. (!$aContentInfo && CHECK_ACTION_RESULT_ALLOWED !== $this->checkAllowedAdd ())
  466. ) {
  467. $this->_oTemplate->displayAccessDenied();
  468. exit;
  469. }
  470. $a = $this->_oDb->getIntervals($iContentId);
  471. foreach ($a as $iIntervalId => $r) {
  472. $a[$iIntervalId]['file_id'] = $r['interval_id'];
  473. $a[$iIntervalId]['repeat_stop'] = bx_process_output ($r['repeat_stop'], BX_DATA_DATE_TS);
  474. }
  475. if ('json' == bx_get('f')) {
  476. header('Content-type: text/html; charset=utf-8');
  477. echo json_encode($a);
  478. }
  479. }
  480. public function subactionDelete()
  481. {
  482. header('Content-type: text/html; charset=utf-8');
  483. $iIntervalId = (int)bx_get('id');
  484. if (!($aContentInfo = $this->_oDb->getContentInfoByIntervalId($iIntervalId))) {
  485. echo _t('_sys_request_page_not_found_cpt');
  486. }
  487. elseif (CHECK_ACTION_RESULT_ALLOWED !== ($sMsg = $this->checkAllowedEdit ($aContentInfo))) {
  488. echo $sMsg;
  489. }
  490. elseif (!$this->_oDb->deleteIntervalById($iIntervalId)) {
  491. echo _t('_sys_txt_error_occured');
  492. }
  493. else {
  494. echo 'ok';
  495. }
  496. }
  497. public function checkAllowedIcalExport ($aDataEntry, $isPerformAction = false)
  498. {
  499. return $aDataEntry['date_start'] && $aDataEntry['date_end'] ? CHECK_ACTION_RESULT_ALLOWED : _t('_sys_txt_access_denied');
  500. }
  501. /**
  502. * Send reminder to event's paritcipants
  503. * @param $aContentInfo content info
  504. * @return number of sent reminders
  505. */
  506. protected function sendReminders($aContentInfo)
  507. {
  508. $CNF = $this->_oConfig->CNF;
  509. $oConnection = BxDolConnection::getObjectInstance($CNF['OBJECT_CONNECTIONS']);
  510. if (!$oConnection)
  511. return false;
  512. $oGroupProfile = BxDolProfile::getInstanceByContentAndType($aContentInfo[$CNF['FIELD_ID']], $this->getName());
  513. if (!$oGroupProfile)
  514. return false;
  515. $aParticipants = $oConnection->getConnectedInitiators($oGroupProfile->id(), true);
  516. if (!$aParticipants)
  517. return true;
  518. $oDateBegin = new DateTime();
  519. $oDateBegin->setTimestamp($aContentInfo['start_utc']);
  520. $oDateBegin->setTimezone(new DateTimeZone($aContentInfo['timezone'] ? $aContentInfo['timezone'] : 'UTC'));
  521. $sEntryBegin = $oDateBegin->format('r');
  522. $sEntryBeginShort = date(getParam('bx_events_short_date_format'), $oDateBegin->getTimestamp());
  523. $oDateBegin->setTimezone(new DateTimeZone('UTC'));
  524. $sEntryBeginUTC = $oDateBegin->format('c');
  525. $oMetatags = BxDolMetatags::getObjectInstance($CNF['OBJECT_METATAGS']);
  526. $sLocationString = $oMetatags->locationsString($aContentInfo[$CNF['FIELD_ID']], false);
  527. $iCounter = 0;
  528. foreach ($aParticipants as $iProfileId) {
  529. $b = sendMailTemplate($CNF['EMAIL_REMINDER'], 0, $iProfileId, array(
  530. 'EntryUrl' => bx_absolute_url(BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $aContentInfo[$CNF['FIELD_ID']])),
  531. 'EntryTitle' => $aContentInfo['title'],
  532. 'EntryBegin' => $sEntryBegin,
  533. 'EntryBeginShort' => $sEntryBeginShort,
  534. 'EntryBeginUTC' => $sEntryBeginUTC,
  535. 'EntryLocation' => $sLocationString ? _t('_bx_events_email_reminder_location', $sLocationString) : '',
  536. ), BX_EMAIL_NOTIFY);
  537. $iCounter += $b ? 1 : 0;
  538. }
  539. return $iCounter;
  540. }
  541. }
  542. /** @} */