public static function getUniqueHostsByPids(array $arrPids = array(), $currentOnly = true, $arrOptions = array())
 {
     if (!is_array($arrPids) || empty($arrPids)) {
         return null;
     }
     $t = static::$strTable;
     $time = time();
     $arrColumns[] = "({$t}.pid IN (" . implode(',', $arrPids) . "))";
     $arrColumns[] = "({$t}.hosts != '')";
     if ($currentOnly) {
         $arrColumns[] = "({$t}.startDate >= {$time})";
     }
     $arrOptions['group'] = 'hosts';
     if (!BE_USER_LOGGED_IN) {
         $arrColumns[] = "({$t}.start='' OR {$t}.start<{$time}) AND ({$t}.stop='' OR {$t}.stop>{$time}) AND {$t}.published=1";
     }
     $objEvents = static::findBy($arrColumns, null, $arrOptions);
     if ($objEvents === null) {
         return null;
     }
     $arrHosts = array();
     while ($objEvents->next()) {
         $arrHosts = array_merge($arrHosts, deserialize($objEvents->hosts, true));
     }
     $arrHosts = array_unique($arrHosts);
     return CalendarDocentsModel::findMultipleByIds($arrHosts, array('order' => 'title'));
 }
 protected function getEventDetails($objEvent, $intStart, $intEnd, $strUrl, $intBegin, $intCalendar)
 {
     global $objPage;
     $span = \Calendar::calculateSpan($intStart, $intEnd);
     // Adjust the start time of a multi-day event (see #6802)
     if ($this->cal_noSpan && $span > 0 && $intStart < $intBegin && $intBegin < $intEnd) {
         $intStart = $intBegin;
     }
     $strDate = \Date::parse($objPage->dateFormat, $intStart);
     $strDay = $GLOBALS['TL_LANG']['DAYS'][date('w', $intStart)];
     $strMonth = $GLOBALS['TL_LANG']['MONTHS'][date('n', $intStart) - 1];
     $strMemberTemplate = $this->mlTemplate;
     if ($span > 0) {
         $strDate = \Date::parse($objPage->dateFormat, $intStart) . ' - ' . \Date::parse($objPage->dateFormat, $intEnd);
         $strDay = '';
     }
     $strTime = '';
     if ($objEvent->addTime) {
         if ($span > 0) {
             $strDate = \Date::parse($objPage->datimFormat, $intStart) . ' - ' . \Date::parse($objPage->datimFormat, $intEnd);
         } elseif ($intStart == $intEnd) {
             $strTime = \Date::parse($objPage->timeFormat, $intStart);
         } else {
             $strTime = \Date::parse($objPage->timeFormat, $intStart) . ' - ' . \Date::parse($objPage->timeFormat, $intEnd);
         }
     }
     // Store raw data
     $arrEvent = $objEvent->row();
     // Overwrite some settings
     $arrEvent['time'] = $strTime;
     $arrEvent['date'] = $strDate;
     $arrEvent['day'] = $strDay;
     $arrEvent['month'] = $strMonth;
     $arrEvent['parent'] = $intCalendar;
     $arrEvent['link'] = $objEvent->title;
     $arrEvent['target'] = '';
     $arrEvent['title'] = specialchars($objEvent->title, true);
     $arrEvent['href'] = $this->generateEventUrl($objEvent, $strUrl);
     if (($intParentEvent = $objEvent->parentEvent) > 0) {
         if (($objParentEvent = CalendarPlusEventsModel::findPublishedByParentAndIdOrAlias($intParentEvent, array($objEvent->pid))) !== null) {
             $arrEvent['parentHref'] = $this->generateEventUrl($objParentEvent, $strUrl);
             $arrEvent['isSubEvent'] = true;
         }
     }
     $arrEvent['class'] = $objEvent->cssClass != '' ? ' ' . $objEvent->cssClass : '';
     $arrEvent['begin'] = $intStart;
     $arrEvent['end'] = $intEnd;
     $arrEvent['details'] = '';
     $arrEvent['startTimeFormated'] = $objEvent->startTime > 0 ? \Date::parse($objPage->timeFormat, $objEvent->startTime) : null;
     $arrEvent['endTimeFormated'] = $objEvent->endTime > 0 ? \Date::parse($objPage->timeFormat, $objEvent->endTime) : null;
     // modal
     if ($this->cal_showInModal && $objEvent->source == 'default' && $this->cal_readerModule) {
         $arrEvent['modal'] = true;
         $arrEvent['modalTarget'] = '#' . EventsPlusHelper::getCSSModalID($this->cal_readerModule);
     }
     $arrPromoters = deserialize($objEvent->promoter, true);
     if (!empty($arrPromoters)) {
         $objPromoters = CalendarPromotersModel::findMultipleByIds($arrPromoters);
         if ($objPromoters !== null) {
             while ($objPromoters->next()) {
                 $objPromoter = $objPromoters->current();
                 if ($objPromoter->website != '') {
                     $strWebsiteLink = $objPromoter->website;
                     // Add http:// to the website
                     if ($strWebsiteLink != '' && !preg_match('@^(https?://|ftp://|mailto:|#)@i', $strWebsiteLink)) {
                         $objPromoter->website = 'http://' . $strWebsiteLink;
                     }
                 }
                 $arrEvent['promoterList'][] = $objPromoter;
             }
         }
     }
     $objEvent->docents = deserialize($objEvent->docents, true);
     if (is_array($objEvent->docents) && !empty($objEvent->docents)) {
         $objDocents = CalendarDocentsModel::findMultipleByIds($objEvent->docents);
         if ($objDocents !== null) {
             while ($objDocents->next()) {
                 $arrEvent['docentList'][] = $objDocents->current();
             }
         }
     }
     $objEvent->memberDocents = deserialize($objEvent->memberDocents, true);
     if (is_array($objEvent->memberDocents) && !empty($objEvent->memberDocents)) {
         $objMembers = MemberPlusMemberModel::findMultipleByIds($objEvent->memberDocents);
         if ($objMembers !== null) {
             while ($objMembers->next()) {
                 $objMemberPlus = new \HeimrichHannot\MemberPlus\MemberPlus($this->objModel);
                 // custom subevent memberlist template
                 $objMemberPlus->mlTemplate = $arrEvent['isSubEvent'] && $this->cal_subeventDocentTemplate != '' ? $this->cal_subeventDocentTemplate : $objMemberPlus->mlTemplate;
                 $arrEvent['memberDocentList'][] = $objMemberPlus->parseMember($objMembers);
             }
         }
     }
     $objEvent->hosts = deserialize($objEvent->hosts, true);
     if (is_array($objEvent->hosts) && !empty($objEvent->hosts)) {
         $objDocents = CalendarDocentsModel::findMultipleByIds($objEvent->hosts);
         if ($objDocents !== null) {
             while ($objDocents->next()) {
                 $arrEvent['hostList'][] = $objDocents->current();
             }
         }
     }
     $objEvent->memberHosts = deserialize($objEvent->memberHosts, true);
     if (is_array($objEvent->memberHosts) && !empty($objEvent->memberHosts)) {
         $objMembers = MemberPlusMemberModel::findMultipleByIds($objEvent->memberHosts);
         if ($objMembers !== null) {
             while ($objMembers->next()) {
                 $objMemberPlus = new \HeimrichHannot\MemberPlus\MemberPlus($this->objModel);
                 // custom subevent memberlist template
                 $objMemberPlus->mlTemplate = $arrEvent['isSubEvent'] && $this->cal_subeventHostTemplate != '' ? $this->cal_subeventHostTemplate : $objMemberPlus->mlTemplate;
                 $arrEvent['memberHostList'][] = $objMemberPlus->parseMember($objMembers);
             }
         }
     }
     $objEvent->eventtypes = deserialize($objEvent->eventtypes, true);
     if (is_array($objEvent->eventtypes) && !empty($objEvent->eventtypes)) {
         $objEventTypes = CalendarEventtypesModel::findMultipleByIds($objEvent->eventtypes);
         if ($objEventTypes !== null) {
             while ($objEventTypes->next()) {
                 $objEventtypesArchive = $objEventTypes->getRelated('pid');
                 if ($objEventtypesArchive === null) {
                     continue;
                 }
                 $strClass = $objEventTypes->cssClass != '' ? ' ' . $objEventTypes->cssClass : '';
                 $strClass .= $objEventtypesArchive->cssClass != '' ? ' ' . $objEventtypesArchive->cssClass : '';
                 $objEventTypes->class = $strClass;
                 $arrEvent['eventtypeList'][] = $objEventTypes->current();
             }
         }
     }
     // time diff
     if ($objEvent->endTime > $objEvent->startTime) {
         $objDateStartTime = new \DateTime();
         $objDateStartTime->setTimestamp($objEvent->startTime);
         $objDateEndTime = new \DateTime();
         $objDateEndTime->setTimestamp($objEvent->endTime);
         $arrEvent['timeDiff'] = $objDateStartTime->diff($objDateEndTime);
     }
     if ($objEvent->website != '') {
         $arrEvent['websiteLink'] = $objEvent->website;
         // Add http:// to the website
         if ($objEvent->website != '' && !preg_match('@^(https?://|ftp://|mailto:|#)@i', $objEvent->website)) {
             $arrEvent['websiteLink'] = 'http://' . $objEvent->website;
         }
     }
     // Override the link target
     if ($objEvent->source == 'external' && $objEvent->target) {
         $arrEvent['target'] = $objPage->outputFormat == 'xhtml' ? ' onclick="return !window.open(this.href)"' : ' target="_blank"';
     }
     // Clean the RTE output
     if ($arrEvent['teaser'] != '') {
         if ($objPage->outputFormat == 'xhtml') {
             $arrEvent['teaser'] = \String::toXhtml($arrEvent['teaser']);
         } else {
             $arrEvent['teaser'] = \String::toHtml5($arrEvent['teaser']);
         }
     }
     // Display the "read more" button for external/article links
     if ($objEvent->source != 'default') {
         $arrEvent['details'] = true;
     } else {
         $objElement = \ContentModel::findPublishedByPidAndTable($objEvent->id, 'tl_calendar_events');
         if ($objElement !== null) {
             while ($objElement->next()) {
                 $arrEvent['details'] .= $this->getContentElement($objElement->current());
             }
         }
     }
     // Get todays start and end timestamp
     if ($this->intTodayBegin === null) {
         $this->intTodayBegin = strtotime('00:00:00');
     }
     if ($this->intTodayEnd === null) {
         $this->intTodayEnd = strtotime('23:59:59');
     }
     // Mark past and upcoming events (see #3692)
     if ($intEnd < $this->intTodayBegin) {
         $arrEvent['class'] .= ' bygone';
     } elseif ($intStart > $this->intTodayEnd) {
         $arrEvent['class'] .= ' upcoming';
     } else {
         $arrEvent['class'] .= ' current';
     }
     return $arrEvent;
 }