BxEventsModule.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  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. /**
  12. * Events profiles module.
  13. */
  14. class BxEventsModule extends BxBaseModGroupsModule
  15. {
  16. function __construct(&$aModule)
  17. {
  18. parent::__construct($aModule);
  19. $CNF = &$this->_oConfig->CNF;
  20. $this->_aSearchableNamesExcept = array_merge($this->_aSearchableNamesExcept, array(
  21. $CNF['FIELD_TIMEZONE'],
  22. $CNF['FIELD_JOIN_CONFIRMATION'],
  23. $CNF['FIELD_REMINDER']
  24. ));
  25. }
  26. public function actionCalendarData()
  27. {
  28. // check permissions
  29. $aSQLPart = array();
  30. $iContentId = (int)bx_get('event');
  31. $iContextId = (int)bx_get('context_id');
  32. if ($iContentId) {
  33. $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
  34. if (CHECK_ACTION_RESULT_ALLOWED !== $this->checkAllowedView($aContentInfo)) {
  35. $this->_oTemplate->displayAccessDenied();
  36. exit;
  37. }
  38. $aSQLPart = array();
  39. }
  40. else {
  41. $oPrivacy = BxDolPrivacy::getObjectInstance($this->_oConfig->CNF['OBJECT_PRIVACY_VIEW']);
  42. if($iContextId){
  43. if (!$this->serviceIsEnableForContext($iContextId)){
  44. exit;
  45. }
  46. else{
  47. $aSQLPart = $oPrivacy ? $oPrivacy->getContentByGroupAsSQLPart(- $iContextId) : array();
  48. }
  49. }
  50. else{
  51. $aSQLPart = $oPrivacy ? $oPrivacy->getContentPublicAsSQLPart(0, $oPrivacy->getPartiallyVisiblePrivacyGroups()) : array();
  52. }
  53. }
  54. // get entries
  55. $aEntries = $this->_oDb->getEntriesByDate(bx_get('start'), bx_get('end'), bx_get('event'), $aSQLPart);
  56. header('Content-Type: application/json; charset=utf-8');
  57. echo json_encode($aEntries);
  58. }
  59. public function serviceGetSafeServices()
  60. {
  61. $a = parent::serviceGetSafeServices();
  62. return array_merge($a, array (
  63. 'BrowsePastProfiles' => '',
  64. 'Calendar' => '',
  65. ));
  66. }
  67. /**
  68. * @page service Service Calls
  69. * @section bx_events Events
  70. * @subsection bx_events-browse Browse
  71. * @subsubsection bx_events-browse_past_profiles browse_past_profiles
  72. *
  73. * @code bx_srv('bx_events', 'browse_past_profiles', [...]); @endcode
  74. *
  75. * Browse past events
  76. *
  77. * @param $bDisplayEmptyMsg show "empty" message or not if nothing found
  78. * @param $bAjaxPaginate use AJAX paginate or not
  79. *
  80. * @see BxEventsModule::serviceBrowsePastProfiles
  81. */
  82. /**
  83. * @ref bx_events-browse_past_profiles "browse_past_profiles"
  84. */
  85. public function serviceBrowsePastProfiles ($bDisplayEmptyMsg = false, $bAjaxPaginate = true)
  86. {
  87. return $this->_serviceBrowse ('past', false, BX_DB_PADDING_DEF, $bDisplayEmptyMsg, $bAjaxPaginate);
  88. }
  89. public function serviceIsEnableForContext($iProfileId = 0)
  90. {
  91. if ($iProfileId == 0)
  92. return false;
  93. $CNF = &$this->_oConfig->CNF;
  94. if (in_array(BxDolProfile::getInstance($iProfileId)->getModule(), $CNF['ENABLE_FOR_CONTEXT_IN_MODULES']))
  95. return true;
  96. return false;
  97. }
  98. /**
  99. * @page service Service Calls
  100. * @section bx_events Events
  101. * @subsection bx_events-page_blocks Page Blocks
  102. * @subsubsection bx_events-calendar calendar
  103. *
  104. * @code bx_srv('bx_events', 'calendar', [...]); @endcode
  105. *
  106. * Shows event or events calendar
  107. *
  108. * @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.
  109. * @param $sTemplate template to use to show calendar, or leave empty for default template, possible options: calendar.html, calendar_compact.html
  110. * @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.
  111. *
  112. * @see BxEventsModule::serviceCalendar
  113. */
  114. /**
  115. * @ref bx_events-calendar "calendar"
  116. */
  117. public function serviceCalendar($aData = array(), $sTemplate = 'calendar.html')
  118. {
  119. if (isset($aData['event'])) {
  120. $aContentInfo = $this->_oDb->getContentInfoById ((int)$aData['event']);
  121. if ('' == $aContentInfo['repeat_stop']) // don't display calendar for non repeating events
  122. return '';
  123. }
  124. if (isset($aData['context_id'])) {
  125. if (!$this->serviceIsEnableForContext($aData['context_id'])){
  126. return '';
  127. }
  128. }
  129. $o = new BxTemplCalendar(array(
  130. 'eventSources' => array (
  131. bx_append_url_params(BX_DOL_URL_ROOT . $this->_oConfig->getBaseUri() . 'calendar_data', $aData),
  132. ),
  133. ), $this->_oTemplate);
  134. return $o->display($sTemplate);
  135. }
  136. /**
  137. * @page service Service Calls
  138. * @section bx_events Events
  139. * @subsection bx_events-other Other
  140. * @subsubsection bx_events-process_reminders process_reminders
  141. *
  142. * @code bx_srv('bx_events', 'process_reminders'); @endcode
  143. *
  144. * Send remiders to event's participants.
  145. *
  146. * It must be processed once every hour for the proper processing.
  147. * @return nothing
  148. *
  149. * @see BxEventsModule::serviceProcessReminders
  150. */
  151. /**
  152. * @ref bx_events-process_reminders "process_reminders"
  153. */
  154. public function serviceProcessReminders()
  155. {
  156. $iNow = time();
  157. // get all events for today and tomorrow, since the max reminder is 24 hours
  158. $aEntries = $this->_oDb->getEntriesByDate('@' . time(), '@' . (time() + 86400));
  159. foreach ($aEntries as $a) {
  160. if (!$a['reminder'])
  161. continue;
  162. $iTimestamp = $a['start_utc'] - (3600 * $a['reminder']);
  163. if ($iNow > ($iTimestamp - 3600) && $iNow < $iTimestamp)
  164. $this->sendReminders($a);
  165. }
  166. }
  167. /**
  168. * @page service Service Calls
  169. * @section bx_events Events
  170. * @subsection bx_events-internal Internal
  171. * @subsubsection bx_events-get_timeline_post get_timeline_post
  172. *
  173. * @code bx_srv('bx_events', 'get_timeline_post', [...]); @endcode
  174. *
  175. * Get Timeline post. It's needed for Timeline module.
  176. *
  177. * @param $aEvent timeline event array from Timeline module
  178. * @return array in special format which is needed specifically for Timeline module to display the data.
  179. *
  180. * @see BxEventsModule::serviceGetTimelinePost
  181. */
  182. /**
  183. * @ref bx_events-get_timeline_post "get_timeline_post"
  184. */
  185. public function serviceGetTimelinePost($aEvent, $aBrowseParams = array())
  186. {
  187. $a = parent::serviceGetTimelinePost($aEvent, $aBrowseParams);
  188. if($a === false)
  189. return false;
  190. $aContentInfo = $this->_oDb->getContentInfoById($aEvent['object_id']);
  191. if(empty($aContentInfo) || !is_array($aContentInfo))
  192. return $a;
  193. $CNF = $this->_oConfig->CNF;
  194. $oDateStart = date_create('@' . $aContentInfo['date_start'], new DateTimeZone($aContentInfo['timezone'] ? $aContentInfo['timezone'] : 'UTC'));
  195. $oDateEnd = date_create('@' . ($aContentInfo['date_start'] > $aContentInfo['repeat_stop'] ? $aContentInfo['date_start'] : $aContentInfo['repeat_stop']), new DateTimeZone($aContentInfo['timezone'] ? $aContentInfo['timezone'] : 'UTC'));
  196. $oMetatags = BxDolMetatags::getObjectInstance($CNF['OBJECT_METATAGS']);
  197. $sLocationString = $oMetatags ? $oMetatags->locationsString($aContentInfo[$CNF['FIELD_ID']], false) : false;
  198. $a['content']['raw'] = $this->_oTemplate->parseHtmlByName('timeline_post.html', array(
  199. 'title' => $a['content']['title'],
  200. 'title_attr' => bx_html_attribute($a['content']['title']),
  201. 'url' => $a['content']['url'],
  202. 'date' => $oDateStart->format(getParam('bx_events_short_date_format')) . ($oDateStart->format('ymd') == $oDateEnd->format('ymd') ? '' : ' - ' . $oDateEnd->format(getParam('bx_events_short_date_format'))),
  203. 'date_c' => $oDateStart->format('c'),
  204. 'bx_if:location' => array(
  205. 'condition' => !!$sLocationString,
  206. 'content' => array('location' => $sLocationString),
  207. ),
  208. ));
  209. $a['content']['title'] = '';
  210. $a['content']['text'] = '';
  211. return $a;
  212. }
  213. public function actionIntervals()
  214. {
  215. $sAction = bx_get('a');
  216. $sMethodName = 'subaction' . ucfirst($sAction);
  217. if (!method_exists($this, $sMethodName)) {
  218. $this->_oTemplate->pageNotFound();
  219. return;
  220. }
  221. $this->$sMethodName();
  222. }
  223. public function subactionRestore($iContentId = 0)
  224. {
  225. if (!$iContentId)
  226. $iContentId = (int)bx_get('c');
  227. $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
  228. if (
  229. ($aContentInfo && CHECK_ACTION_RESULT_ALLOWED !== $this->checkAllowedEdit ($aContentInfo))
  230. ||
  231. (!$aContentInfo && CHECK_ACTION_RESULT_ALLOWED !== $this->checkAllowedAdd ())
  232. ) {
  233. $this->_oTemplate->displayAccessDenied();
  234. exit;
  235. }
  236. $a = $this->_oDb->getIntervals($iContentId);
  237. foreach ($a as $iIntervalId => $r) {
  238. $a[$iIntervalId]['file_id'] = $r['interval_id'];
  239. $a[$iIntervalId]['repeat_stop'] = bx_process_output ($r['repeat_stop'], BX_DATA_DATE_TS);
  240. }
  241. if ('json' == bx_get('f')) {
  242. header('Content-type: text/html; charset=utf-8');
  243. echo json_encode($a);
  244. }
  245. }
  246. public function subactionDelete()
  247. {
  248. header('Content-type: text/html; charset=utf-8');
  249. $iIntervalId = (int)bx_get('id');
  250. if (!($aContentInfo = $this->_oDb->getContentInfoByIntervalId($iIntervalId))) {
  251. echo _t('_sys_request_page_not_found_cpt');
  252. }
  253. elseif (CHECK_ACTION_RESULT_ALLOWED !== ($sMsg = $this->checkAllowedEdit ($aContentInfo))) {
  254. echo $sMsg;
  255. }
  256. elseif (!$this->_oDb->deleteIntervalById($iIntervalId)) {
  257. echo _t('_sys_txt_error_occured');
  258. }
  259. else {
  260. echo 'ok';
  261. }
  262. }
  263. /**
  264. * Send reminder to event's paritcipants
  265. * @param $aContentInfo content info
  266. * @return number of sent reminders
  267. */
  268. protected function sendReminders($aContentInfo)
  269. {
  270. $CNF = $this->_oConfig->CNF;
  271. $oConnection = BxDolConnection::getObjectInstance($CNF['OBJECT_CONNECTIONS']);
  272. if (!$oConnection)
  273. return false;
  274. $oGroupProfile = BxDolProfile::getInstanceByContentAndType($aContentInfo[$CNF['FIELD_ID']], $this->getName());
  275. if (!$oGroupProfile)
  276. return false;
  277. $aParticipants = $oConnection->getConnectedInitiators($oGroupProfile->id(), true);
  278. if (!$aParticipants)
  279. return true;
  280. $oDateBegin = new DateTime();
  281. $oDateBegin->setTimestamp($aContentInfo['start_utc']);
  282. $oDateBegin->setTimezone(new DateTimeZone($aContentInfo['timezone'] ? $aContentInfo['timezone'] : 'UTC'));
  283. $sEntryBegin = $oDateBegin->format('r');
  284. $sEntryBeginShort = $oDateBegin->format(getParam('bx_events_short_date_format'));
  285. $oDateBegin->setTimezone(new DateTimeZone('UTC'));
  286. $sEntryBeginUTC = $oDateBegin->format('c');
  287. $oMetatags = BxDolMetatags::getObjectInstance($CNF['OBJECT_METATAGS']);
  288. $sLocationString = $oMetatags->locationsString($aContentInfo[$CNF['FIELD_ID']], false);
  289. $iCounter = 0;
  290. foreach ($aParticipants as $iProfileId) {
  291. $b = sendMailTemplate($CNF['EMAIL_REMINDER'], 0, $iProfileId, array(
  292. 'EntryUrl' => BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $aContentInfo[$CNF['FIELD_ID']]),
  293. 'EntryTitle' => $aContentInfo['title'],
  294. 'EntryBegin' => $sEntryBegin,
  295. 'EntryBeginShort' => $sEntryBeginShort,
  296. 'EntryBeginUTC' => $sEntryBeginUTC,
  297. 'EntryLocation' => $sLocationString,
  298. ), BX_EMAIL_NOTIFY);
  299. $iCounter += $b ? 1 : 0;
  300. }
  301. return $iCounter;
  302. }
  303. }
  304. /** @} */