Your IP : 216.73.216.240
<?php
/**
*----------------------------------------------------------------------------
* iCagenda Events Management Extension for Joomla!
*----------------------------------------------------------------------------
* @version 4.0.7 2026-05-06
*
* @package iCagenda.Admin
* @subpackage src.Utilities.Event
* @link https://www.joomlic.com
*
* @author Cyril Reze
* @copyright (c) 2012-2026 Cyril Reze / JoomliC. All rights reserved.
* @license GNU General Public License version 3 or later; see LICENSE.txt
*
* @since 3.6
*----------------------------------------------------------------------------
*/
namespace iCutilities\Event;
\defined('_JEXEC') or die;
use iClib\Date\Date as iCDate;
use iClib\Date\Period as iCDatePeriod;
use iClib\Filter\Output as iCFilterOutput;
use iClib\Render\Render as iCRender;
use iClib\String\StringHelper as iCString;
use iCutilities\Event\EventData as icagendaEventData;
use iCutilities\Events\Events as icagendaEvents;
use iCutilities\Render\Render as icagendaRender;
use iCutilities\Router\Router as icagendaRouter;
use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Factory;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Multilanguage;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Uri\Uri;
use Joomla\Registry\Registry;
use Joomla\Utilities\ArrayHelper;
/**
* class icagendaEvent
*/
class Event
{
/**
* Get Next Date (or Last Date) from event dates
*
* @since 3.7.15
*/
public static function getNextDate($item, $reset = false)
{
if (is_array($item))
{
$item = ArrayHelper::toObject($item);
}
$eventTimeZone = null;
// If no stored datetime for next, or next date is past, we need to update next date
if ( ! isset($item->next)
|| ($item->next <= HTMLHelper::date('now', 'Y-m-d H:i:s')
|| ! iCDate::isDate($item->next))
)
{
$reset = true;
}
if ($reset)
{
$next_singleDates = $last_singleDates = '';
$next = $next_period = $last_period = '';
// Single Dates Check
$singleDates = iCString::isSerialized($item->dates) ? unserialize($item->dates) : array();
$upcomingSingleDates = array_filter(
$singleDates,
function($date)
{
return $date >= HTMLHelper::date('now', 'Y-m-d H:i:s');
}
);
if (count($upcomingSingleDates) > 0)
{
$next_singleDates = min($upcomingSingleDates);
$next_singleDates = iCDate::isDate($next_singleDates) ? HTMLHelper::date($next_singleDates, 'Y-m-d H:i:s', $eventTimeZone) : '';
}
else
{
$pastSingleDates = array_filter(
$singleDates,
function ($date)
{
return $date < HTMLHelper::date('now', 'Y-m-d H:i:s');
}
);
if (count($pastSingleDates) > 0)
{
$last_singleDates = max($pastSingleDates);
$last_singleDates = iCDate::isDate($last_singleDates) ? HTMLHelper::date($last_singleDates, 'Y-m-d H:i:s', $eventTimeZone) : '';
}
}
// Period Check
$weekdays = array();
if (isset($item->weekdays))
{
$weekdays = ! is_array($item->weekdays) ? explode(",", $item->weekdays) : $item->weekdays;
}
if (count($weekdays) > 0)
{
$period_all_dates_array = iCDatePeriod::listDates($item->startdate, $item->enddate);
$period_array = array();
foreach ($period_all_dates_array AS $date_in_weekdays)
{
$datetime_period_date = HTMLHelper::date($date_in_weekdays, 'Y-m-d H:i', $eventTimeZone);
if (in_array(date('w', strtotime($datetime_period_date)), $weekdays))
{
$period_array[] = $datetime_period_date;
}
}
$upcomingPeriodDates = array_filter(
$period_array,
function($date)
{
return $date >= HTMLHelper::date('now', 'Y-m-d H:i:s');
}
);
if (count($upcomingPeriodDates) > 0)
{
$next_period = min($upcomingPeriodDates);
$next_period = iCDate::isDate($next_period) ? HTMLHelper::date($next_period, 'Y-m-d H:i:s', $eventTimeZone) : '';
}
else
{
$last_period = iCDate::isDate($item->startdate) ? $item->startdate : '';
}
}
else
{
if ($item->startdate >= HTMLHelper::date('now', 'Y-m-d H:i:s'))
{
$next_period = iCDate::isDate($item->startdate) ? $item->startdate : '';
}
elseif ($item->enddate >= HTMLHelper::date('now', 'Y-m-d H:i:s'))
{
$next_period = iCDate::isDate($item->startdate) ? $item->startdate : '';
}
else
{
$last_period = iCDate::isDate($item->startdate) ? $item->startdate : '';
}
}
// Return Next
if ($next_singleDates && $next_period)
{
$next = min($next_singleDates, $next_period);
}
elseif ($next_singleDates)
{
$next = $next_singleDates;
}
elseif ($next_period)
{
$next = $next_period;
}
else
{
$next = max($last_singleDates, $last_period);
}
if ((isset($item->next) && $item->next != $next)
|| (! isset($item->next) && isset($item->id)))
{
$item->next = $next;
$db = Factory::getContainer()->get(\Joomla\Database\DatabaseInterface::class);
$query = (method_exists($db, 'createQuery') ? $db->createQuery() : $db->getQuery(true));
$query->update('#__icagenda_events')
->set($db->qn('next') . ' = ' . $db->q(HTMLHelper::date($next, 'Y-m-d H:i:s', $eventTimeZone)))
->where($db->qn('id') . ' = ' . (int) $item->id);
$db->setQuery($query);
$db->execute($query);
}
else
{
$item->next = $next;
}
}
return $item->next;
}
/**
* Get Current Date of an event.
*
* @param \stdClass[] $item The event object.
* @param string $eventTimeZone The event time zone.
*
* @return Datetime
*
* @since 3.8.10
*/
public static function currentDate($item, $eventTimeZone = null)
{
$currentDate = $singleDate = $pastDate = $period = $pastPeriod ='';
// Single Dates Control
$singleDates = iCString::isSerialized($item->dates) ? unserialize($item->dates) : array();
$upcomingSingleDates = array_filter(
$singleDates,
function($date)
{
return $date >= HTMLHelper::date('now', 'Y-m-d H:i:s');
}
);
if (\count($upcomingSingleDates) > 0)
{
$singleDate = min($upcomingSingleDates);
$singleDate = iCDate::isDate($singleDate) ? HTMLHelper::date($singleDate, 'Y-m-d H:i:s', $eventTimeZone) : '';
}
else
{
$pastSingleDates = array_filter(
$singleDates,
function ($date)
{
return $date < HTMLHelper::date('now', 'Y-m-d H:i:s');
}
);
if (count($pastSingleDates) > 0)
{
$pastDate = max($pastSingleDates);
$pastDate = iCDate::isDate($pastDate) ? HTMLHelper::date($pastDate, 'Y-m-d H:i:s', $eventTimeZone) : '';
}
}
// Period Control
$weekdays = array();
if (isset($item->weekdays) && $item->weekdays)
{
$weekdays = ! \is_array($item->weekdays) ? explode(",", $item->weekdays) : $item->weekdays;
}
if (\count($weekdays) > 0)
{
$period_all_dates_array = iCDatePeriod::listDates($item->startdate, $item->enddate);
$period_array = array();
foreach ($period_all_dates_array AS $date_in_weekdays)
{
$datetime_period_date = HTMLHelper::date($date_in_weekdays, 'Y-m-d H:i', $eventTimeZone);
if (\in_array(date('w', strtotime($datetime_period_date)), $weekdays))
{
$period_array[] = $datetime_period_date;
}
}
$upcomingPeriodDates = array_filter(
$period_array,
function($date)
{
return $date >= HTMLHelper::date('now', 'Y-m-d H:i:s');
}
);
if (\count($upcomingPeriodDates) > 0)
{
$period = min($upcomingPeriodDates);
$period = iCDate::isDate($period) ? HTMLHelper::date($period, 'Y-m-d H:i:s', $eventTimeZone) : '';
}
else
{
$pastPeriod = iCDate::isDate($item->startdate) ? $item->startdate : '';
}
}
else
{
if ($item->startdate >= HTMLHelper::date('now', 'Y-m-d H:i:s'))
{
// Upcoming Period
$period = iCDate::isDate($item->startdate) ? $item->startdate : '';
}
elseif ($item->enddate >= HTMLHelper::date('now', 'Y-m-d H:i:s'))
{
// Current Period
$period = HTMLHelper::date('now', 'Y-m-d H:i:s');
}
else
{
// Past Period
$pastPeriod = iCDate::isDate($item->startdate) ? $item->startdate : '';
}
}
// Return Current Date
if ($singleDate && $period)
{
$currentDate = min($singleDate, $period);
}
elseif ($singleDate)
{
$currentDate = $singleDate;
}
elseif ($period)
{
$currentDate = $period;
}
else
{
$currentDate = max($pastDate, $pastPeriod);
}
return $currentDate;
}
/**
* Function to get Event Params
*
* @return Registry Event Params
*/
public static function evtParams($params)
{
$evtParams = new Registry($params);
return $evtParams;
}
/**
* Function to get Event Params
*
* @param integer $id Event id
*
* @return Registry Event Params
*
* @since 3.6.5
*/
public static function getParams($id = null)
{
$db = Factory::getContainer()->get(\Joomla\Database\DatabaseInterface::class);
$query = (method_exists($db, 'createQuery') ? $db->createQuery() : $db->getQuery(true))
->select('e.params')
->from($db->qn('#__icagenda_events', 'e'))
->where($db->qn('e.id') . ' = ' . (int) $id);
$db->setQuery($query);
$result = $db->loadResult();
$params = json_decode((string) $result, true);
$eventParams = new Registry($params);
return $eventParams;
}
/**
* Function to get Event Params merged with Global
*
* @param integer $id Event id
*
* @return Registry Event Params
*
* @since 3.8.0
*/
public static function getMergedParams($id = null)
{
$db = Factory::getContainer()->get(\Joomla\Database\DatabaseInterface::class);
$query = (method_exists($db, 'createQuery') ? $db->createQuery() : $db->getQuery(true))
->select('e.params')
->from($db->qn('#__icagenda_events', 'e'))
->where($db->qn('e.id') . ' = ' . (int) $id);
$db->setQuery($query);
$result = $db->loadResult();
// Convert parameter fields to objects.
$registry = new Registry;
$registry->loadString($result);
// Merge Event params to app params
$eventMergedParams = clone ComponentHelper::getParams('com_icagenda');
$eventMergedParams->merge($registry);
return $eventMergedParams;
}
/**
* Function to return the back arrow button (No item needed)
*
* @return HTML
*/
public static function backArrow($item = null)
{
$app = Factory::getApplication();
$input = $app->input;
$view = $input->get('view');
// Get Current Itemid
$this_itemid = $input->getInt('Itemid', 0);
// TODO: Remove jlayout control (3.6)
$jlayout = $input->get('layout', '');
$layouts_array = array('event', 'registration');
$layout = in_array($jlayout, $layouts_array) ? $jlayout : '';
$manageraction = $input->get('manageraction', '');
$referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
// RTL css if site language is RTL
$lang = Factory::getLanguage();
$back_icon = ($lang->isRTL()) ? 'iCicon iCicon-nextic' : 'iCicon iCicon-backic';
if ( ($layout != '' || $view == 'event')
&& strpos($referer, icagendaRouter::translateSegment('registration')) === false
&& strpos($referer, icagendaRouter::translateSegment('event_edit')) === false
&& strpos($referer, 'registration') === false
&& strpos($referer, 'event_edit') === false
&& ! $manageraction)
{
if ($referer != "")
{
$BackArrow = '<div class="ic-back"><span class="' . $back_icon . '"></span> <a href="' . str_replace(array('"', '<', '>', "'"), '', $referer) .'"><span class="small">' . Text::_('COM_ICAGENDA_BACK') .'</span></a></div>';
}
else
{
$BackArrow = '';
}
}
// elseif ($manageraction || strpos($referer, icagendaRouter::translateSegment('registration')) !== false || strpos($referer, icagendaRouter::translateSegment('event_edit')) !== false)
elseif ($manageraction
|| strpos($referer, icagendaRouter::translateSegment('registration')) !== false
|| strpos($referer, icagendaRouter::translateSegment('event_edit')) !== false
|| strpos($referer, 'registration') !== false
|| strpos($referer, 'event_edit') !== false
) {
$BackArrow = '<div class="ic-back"><span class="' . $back_icon . '"></span> <a href="' . Route::_('index.php?option=com_icagenda&Itemid=' . (int) $this_itemid) .'"><span class="small">' . Text::_('COM_ICAGENDA_BACK') . '</span></a></div>';
}
else
{
$BackArrow = '';
}
// Header Message if event cancelled
$evtParams = self::getParams($item->id);
$cancellation_info = '';
if ($evtParams->get('event_cancelled'))
{
$text = Text::_('COM_ICAGENDA_EVENT_CANCELLED_TEXT');
$description = $evtParams->get('event_cancelled_desc');
if ($evtParams->get('event_cancelled_customlabel'))
{
$text = Text::_($evtParams->get('event_cancelled_customlabel_text', 'COM_ICAGENDA_EVENT_CANCELLED_TEXT'));
// $class = $evtParams->get('event_cancelled_customlabel_css', $class);
}
$cancellation_info = '<br /><div class="ic-event-cancelled-alert alert alert-danger">'
. '<h2 class="alert-heading">' . $text . '</h2>'
. '<div class="alert-message">' . $description . '</div>'
. '</div>';
}
return $BackArrow . $cancellation_info;
}
/**
* Event View URL
*
* @TODO: to be replace by getLink()
*
* @deprecated 5.0
*/
public static function url($id, $alias = null, $Itemid = null, $vars = [])
{
$app = Factory::getApplication();
$lang = Factory::getLanguage();
$menu = $app->getMenu();
// Set the event slug
$event_slug = $alias ? (int) $id . ':' . $alias : (int) $id;
$extra = '';
if (\is_array($vars)) {
foreach ($vars as $var => $value) {
if ($value) {
$extra.= '&' . $var . '=' . $value;
}
}
}
// Look for the home menu
if (Multilanguage::isEnabled()) {
$home = $menu->getDefault($lang->getTag());
} else {
$home = $menu->getDefault();
}
if ((int) $Itemid === $home->id) {
$ItemidSegment = ($home->link == 'index.php?option=com_icagenda&view=events')
? '&Itemid=' . $Itemid
: '';
} elseif ((int) $Itemid > 0) {
$ItemidSegment = '&Itemid=' . $Itemid;
} else {
$ItemidSegment = '&Itemid=' . $app->input->getInt('Itemid', 0);
}
$url = Route::_('index.php?option=com_icagenda&view=event&id=' . $event_slug . $ItemidSegment . $extra);
// $url = Route::link('site', 'index.php?option=com_icagenda&view=event&id=' . $event_slug . $ItemidSegment . $extra); // New since J3.9
return $url;
}
/**
* Get Event Link
*
* @param object $item The item (event).
* @param int $Itemid The menu item ID.
* @param array $vars An array of safe URL variables.
*
* @since 4.0
*/
public static function getLink($item, $Itemid = null, $vars = [])
{
$app = Factory::getApplication();
$lang = Factory::getLanguage();
$menu = $app->getMenu();
$id = $item->id;
$alias = $item->alias ?: null;
// Set the event slug
$event_slug = $alias ? (int) $id . ':' . $alias : (int) $id;
// Get Current Lang Tag
$langTag = $lang->getTag();
$extra = '';
if (\is_array($vars)) {
// Define the given variables for the URL.
foreach ($vars as $var => $value) {
if ($value) {
$extra.= '&' . $var . '=' . $value;
}
}
// If lang tag is set in extra variables, we use it (Ajax call loses the current language).
if (isset($vars['lang']) && $vars['lang']) {
$langTag = $vars['lang'];
}
}
// Look for the home menu
if (Multilanguage::isEnabled()) {
$home = $menu->getDefault($langTag);
} else {
$home = $menu->getDefault();
}
// Define Itemid segment
if ((int) $Itemid === $home->id) {
$ItemidSegment = ($home->link == 'index.php?option=com_icagenda&view=events')
? '&Itemid=' . $Itemid
: '';
} elseif ((int) $Itemid > 0) {
$ItemidSegment = '&Itemid=' . $Itemid;
} else {
$ItemidSegment = '&Itemid=' . $app->input->getInt('Itemid', 0);
}
$url = Route::link('site', 'index.php?option=com_icagenda&view=event&id=' . $event_slug . $ItemidSegment . $extra);
return $url;
}
/**
* Title + Manager Icons
*
* @todo Review and split into sub-functions
*/
public static function titleBar($i)
{
$input = Factory::getApplication()->input;
$this_itemid = $input->getInt('Itemid');
$list_title_length = (int) ComponentHelper::getParams('com_icagenda')->get('list_title_length', '');
$i_title = icagendaRender::titleToFormat($i->title);
$jlayout = $input->get('layout', '');
$layouts_array = array('event', 'registration');
$layout = in_array($jlayout, $layouts_array) ? $jlayout : '';
$mbString = extension_loaded('mbstring');
$title_length = $mbString ? mb_strlen($i_title, 'UTF-8') : strlen($i_title);
if (empty($layout)
&& ! empty($list_title_length))
{
$title = $mbString
? trim(mb_substr($i_title, 0, $list_title_length, 'UTF-8'))
: trim(substr($i_title, 0, $list_title_length));
$new_title_length = $mbString ? mb_strlen($title, 'UTF-8') : strlen($title);
if ($new_title_length < $title_length)
{
$title.= '...';
}
}
else
{
$title = $i_title;
}
$approval = $i->approval;
$event_slug = empty($i->alias) ? $i->id : $i->id . ':' . $i->alias;
// Set Manager Actions Url
$managerActionsURL = 'index.php?option=com_icagenda&view=event&id=' . $event_slug . '&Itemid=' . $this_itemid;
$unapproved = '<a class="iCtip" href="' . Route::_($managerActionsURL) . '" title="' . Text::_('COM_ICAGENDA_APPROVE_AN_EVENT_LBL') . '"><small><span class="iCicon-open-details"></span></small></a>';
$titleBar = '';
if ($title != NULL && $approval == 1)
{
$titleBar = $title . ' ' . $unapproved;
}
elseif ($title != NULL && $approval != 1)
{
$titleBar.= $title;
}
$eventIsCancelled = self::cancelledButton($i->id, 'btn btn-danger');
if ($eventIsCancelled)
{
$titleBar.= ' ' . $eventIsCancelled;
}
return $titleBar;
}
/**
* Return Event Cancelled button with infotip
*
* @since 3.7.12
*/
public static function cancelledButton($id, $class = 'label label-important')
{
$evtParams = self::getParams($id);
if ($evtParams->get('event_cancelled'))
{
$language = Factory::getLanguage();
$language->load('com_icagenda', JPATH_SITE, 'en-GB', false, true);
$language->load('com_icagenda', JPATH_SITE, null, true);
$text = Text::_('COM_ICAGENDA_EVENT_CANCELLED_TEXT');
$description = $evtParams->get('event_cancelled_desc');
if ($evtParams->get('event_cancelled_customlabel'))
{
$text = Text::_($evtParams->get('event_cancelled_customlabel_text', 'COM_ICAGENDA_EVENT_CANCELLED_TEXT'));
$class = $evtParams->get('event_cancelled_customlabel_css', $class);
}
$title = $tipclass = $position = '';
if (!empty($description))
{
if ($text && $text !== $description)
{
HTMLHelper::_('bootstrap.popover');
$tipclass = ' hasPopover';
$title = ' title="' . htmlspecialchars(trim($text, ':')) . '"'
. ' data-content="'. htmlspecialchars($description) . '"';
if (!$position && Factory::getLanguage()->isRtl())
{
$position = ' data-placement="left" ';
}
}
else
{
HTMLHelper::_('bootstrap.tooltip');
$tipclass = ' hasTooltip';
$title = ' title="' . HTMLHelper::_('tooltipText', trim($text, ':'), Text::_($description), 0) . '"';
$position = 'top';
}
}
$cancelledButton = '<span class="ic-event-cancelled ' . $class . $tipclass . '"' . $title . $position . '>' . $text . '</span>';
return $cancelledButton;
}
return false;
}
/**
* Next Date Text
*/
public static function dateText($i)
{
$eventTimeZone = null;
$dates = iCString::isSerialized($i->dates) ? unserialize($i->dates) : array(); // returns array
$period = iCString::isSerialized($i->period) ? unserialize($i->period) : array(); // returns array
$weekdays = $i->weekdays;
$startdatetime = iCDate::isDate($i->startdate) ? date('Y-m-d H:i', strtotime($i->startdate)) : '';
$site_date = HTMLHelper::date('now', 'Y-m-d');
$site_datetime = HTMLHelper::date('now', 'Y-m-d H:i');
$alldates_array = array_merge($dates, $period);
$alldates = array_filter($alldates_array, function($var) {return $var == iCDate::isDate($var);});
$next_date = date('Y-m-d', strtotime($i->next));
$next_datetime = date('Y-m-d H:i', strtotime($i->next));
$next_is_in_period = in_array($next_datetime, $period) ? true : false;
$totDates = count($alldates);
if ($totDates > 1
&& $next_date > $site_date)
{
rsort($alldates);
$last_date = HTMLHelper::date($alldates[0], 'Y-m-d', $eventTimeZone);
if ( ! $next_is_in_period
&& $last_date == $next_date)
{
$dateText = Text::_('COM_ICAGENDA_EVENT_DATE_LAST');
}
elseif ( ! $next_is_in_period)
{
$dateText = Text::_('COM_ICAGENDA_EVENT_DATE_FUTUR');
}
elseif ($next_is_in_period
&& $weekdays == NULL)
{
$dateText = Text::_('COM_ICAGENDA_LEGEND_DATES');
}
else
{
$dateText = Text::_('COM_ICAGENDA_EVENT_DATE');
}
}
elseif ($totDates > 1
&& $next_date < $site_date)
{
if ($totDates == 2)
{
$dateText = $next_is_in_period
? Text::_('COM_ICAGENDA_EVENT_DATE')
: Text::_('COM_ICAGENDA_EVENT_DATE_PAST');
}
else
{
$dateText = ($next_is_in_period && $weekdays == NULL)
? Text::_('COM_ICAGENDA_LEGEND_DATES')
: Text::_('COM_ICAGENDA_EVENT_DATE_PAST');
}
}
elseif ($next_date == $site_date)
{
$dateText = ($next_is_in_period && ($next_datetime < $site_datetime || $next_datetime != $startdatetime))
? Text::_('COM_ICAGENDA_EVENT_DATE_PERIOD_NOW')
: Text::_('COM_ICAGENDA_EVENT_DATE_TODAY');
}
else
{
$dateText = Text::_( 'COM_ICAGENDA_EVENT_DATE' );
}
return $dateText;
}
/**
* Get Next Date (or Last Date)
*/
public static function nextDate($evt, $i)
{
$eventTimeZone = null;
$singledates = iCString::isSerialized($i->dates) ? unserialize($i->dates) : array(); // returns array
$period = iCString::isSerialized($i->period) ? unserialize($i->period) : array(); // returns array
$startdatetime = $i->startdate;
$enddatetime = $i->enddate;
$weekdays = $i->weekdays;
$site_date = HTMLHelper::date('now', 'Y-m-d');
$UTC_today_date = HTMLHelper::date('now', 'Y-m-d', $eventTimeZone);
$next_date = HTMLHelper::date($evt, 'Y-m-d', $eventTimeZone);
$next_datetime = HTMLHelper::date($evt, 'Y-m-d H:i', $eventTimeZone);
$start_date = HTMLHelper::date($i->startdate, 'Y-m-d', $eventTimeZone);
$end_date = HTMLHelper::date($i->enddate, 'Y-m-d', $eventTimeZone);
// Check if date from a period with weekdays has end time of the period set in next.
// $time_next_datetime = HTMLHelper::date($next_datetime, 'H:i', $eventTimeZone);
$time_next_datetime = date('H:i', strtotime($next_datetime));
$time_startdate = HTMLHelper::date($i->startdate, 'H:i', $eventTimeZone);
$time_enddate = HTMLHelper::date($i->enddate, 'H:i', $eventTimeZone);
$data_next_datetime = date('Y-m-d H:i', strtotime($evt));
if ($next_date == $site_date
&& $time_next_datetime == $time_enddate)
{
$next_datetime = $next_date . ' ' . $time_startdate;
}
if ($period != NULL
&& in_array($data_next_datetime, $period))
{
$next_is_in_period = true;
}
elseif ($i->period == ''
&& ! in_array($data_next_datetime, $singledates))
{
$next_is_in_period = true;
}
else
{
$next_is_in_period = false;
}
// Highlight event in progress
if ($next_date == $site_date)
{
$start_span = '<span class="ic-next-today">';
$end_span = '</span>';
}
else
{
$start_span = $end_span = '';
}
$separator = '<span class="ic-datetime-separator"> - </span>';
// Format Next Date
if ($next_is_in_period
&& ($start_date == $end_date || $weekdays != null))
{
// Next in the period & (same start/end date OR one or more weekday selected)
$nextDate = $start_span;
$nextDate.= '<span class="ic-single-startdate">';
$nextDate.= icagendaRender::dateToFormat($evt);
$nextDate.= '</span>';
if ($i->displaytime == 1) {
$nextDate.= ' <span class="ic-single-starttime">' . icagendaRender::dateToTime($i->startdate) . '</span>';
if (icagendaRender::dateToTime($i->startdate) != icagendaRender::dateToTime($i->enddate)) {
// Special case when period with days of the week, and time for End Date is set for event at 00:00.
// See EventModel WebiC\Component\iCagenda\Site\Model;
if (date('H:i:s.u', strtotime($i->enddate)) == '23:59:59.000000') {
$endTime = icagendaRender::dateToTime(date('Y-m-d', strtotime($i->enddate)) . ' 00:00');
} else {
$endTime = icagendaRender::dateToTime($i->enddate);
}
// Display end time only if after start time.
if (date('H:i', strtotime($i->enddate)) > date('H:i', strtotime($i->startdate))
|| $endTime == '00:00') {
$nextDate.= $separator . '<span class="ic-single-endtime">' . $endTime . '</span>';
}
}
}
$nextDate.= $end_span;
}
elseif ($next_is_in_period
&& ($weekdays == null))
{
// Next in the period & different start/end date & no weekday selected
$start = '<span class="ic-period-startdate">';
$start.= icagendaRender::dateToFormat($i->startdate);
$start.= '</span>';
$end = '<span class="ic-period-enddate">';
$end.= icagendaRender::dateToFormat($i->enddate);
$end.= '</span>';
if ($i->displaytime == 1)
{
$start.= ' <span class="ic-period-starttime">' . icagendaRender::dateToTime($i->startdate) . '</span>';
$end.= ' <span class="ic-period-endtime">' . icagendaRender::dateToTime($i->enddate) . '</span>';
}
$nextDate = $start_span . $start . $separator . $end . $end_span;
}
else
{
// Next is a single date
$nextDate = $start_span;
$nextDate.= '<span class="ic-single-next">';
$nextDate.= icagendaRender::dateToFormat($evt);
$nextDate.= '</span>';
if ($i->displaytime == 1)
{
$nextDate.= ' <span class="ic-single-starttime">' . icagendaRender::dateToTime($evt) . '</span>';
}
$nextDate.= $end_span;
}
return $nextDate;
}
/**
* Get dates and times for specific event, for a specific current date.
*
* @since 4.0.0
*/
public static function getDateArray($evt, $item)
{
$eventTimeZone = null;
$singledates = iCString::isSerialized($item->dates) ? unserialize($item->dates) : [];
$period = iCString::isSerialized($item->period) ? unserialize($item->period) : [];
// $startdatetime = $item->startdate;
// $enddatetime = $item->enddate;
$weekdays = $item->weekdays;
// $site_date = HTMLHelper::date('now', 'Y-m-d');
// $UTC_today_date = HTMLHelper::date('now', 'Y-m-d', $eventTimeZone);
// $next_date = HTMLHelper::date($evt, 'Y-m-d', $eventTimeZone);
$next_datetime = HTMLHelper::date($evt, 'Y-m-d H:i', $eventTimeZone);
$start_date = HTMLHelper::date($item->startdate, 'Y-m-d', $eventTimeZone);
$end_date = HTMLHelper::date($item->enddate, 'Y-m-d', $eventTimeZone);
// Check if date from a period with weekdays has end time of the period set in next.
// $time_next_datetime = HTMLHelper::date($next_datetime, 'H:i', $eventTimeZone);
$time_next_datetime = date('H:i', strtotime($next_datetime));
$time_startdate = HTMLHelper::date($item->startdate, 'H:i', $eventTimeZone);
$time_enddate = HTMLHelper::date($item->enddate, 'H:i', $eventTimeZone);
$data_next_datetime = date('Y-m-d H:i', strtotime($evt));
// if ($next_date == $site_date && $time_next_datetime == $time_enddate) {
// $next_datetime = $next_date . ' ' . $time_startdate;
// }
if ($period != NULL && in_array($data_next_datetime, $period)) {
$next_is_in_period = true;
} elseif ($item->period == '' && ! in_array($data_next_datetime, $singledates)) {
$next_is_in_period = true;
} else {
$next_is_in_period = false;
}
$startDate = '';
$startTime = '';
$endDate = '';
$endTime = '';
if ($next_is_in_period && ($start_date == $end_date || $weekdays != null)) {
// Next in the period & (same start/end date OR one or more weekday selected)
$startDate = icagendaRender::dateToFormat($evt);
if ($item->displaytime == 1) {
$startTime = icagendaRender::dateToTime($item->startdate);
if (icagendaRender::dateToTime($item->startdate) != icagendaRender::dateToTime($item->enddate)) {
$endTime = icagendaRender::dateToTime($item->enddate);
}
}
} elseif ($next_is_in_period && $weekdays == null) {
// Next in the period & different start/end date & no weekday selected
$startDate = icagendaRender::dateToFormat($item->startdate);
$endDate = icagendaRender::dateToFormat($item->enddate);
if ($item->displaytime == 1) {
$startTime = icagendaRender::dateToTime($item->startdate);
$endTime = icagendaRender::dateToTime($item->enddate);
}
} else {
// Next is a single date
$startDate = icagendaRender::dateToFormat($evt);
if ($item->displaytime == 1) {
$startTime = icagendaRender::dateToTime($evt);
}
}
return [
'start_date' => $startDate,
'start_time' => $startTime,
'end_date' => $endDate,
'end_time' => $endTime,
];
}
/*
* Function to detect if info details exist in an event,
* and to hide or show it depending of Options (display and access levels)
*/
public static function infoDetails($item, $CUSTOM_FIELDS)
{
// Hide/Show Option
$infoDetails = ComponentHelper::getParams('com_icagenda')->get('infoDetails', 1);
// Access Levels Option
$accessInfoDetails = ComponentHelper::getParams('com_icagenda')->get('accessInfoDetails', 1);
if ( ($infoDetails == 1 && icagendaEvents::accessLevels($accessInfoDetails))
&& ( ($item->params->get('statutReg', '') == '1' && $item->params->get('maxReg'))
|| $item->phone
|| $item->email
|| $item->website
|| $item->address
|| $item->file
|| $CUSTOM_FIELDS )
)
{
return true;
}
return false;
}
/*
* Function to return a list of all single dates, HTML formatted.
* TO BE REFACTORED
*/
public static function displayListSingleDates($item)
{
$iCparams = ComponentHelper::getParams('com_icagenda');
$timeformat = Factory::getApplication()->getParams()->get('timeformat', 1);
// Hide/Show Option
$SingleDates = $iCparams->get('SingleDates', 1);
// Access Levels Option (to be checked!)
// $accessSingleDates = $iCparams->get('accessSingleDates', 1);
// Order by Dates
$SingleDatesOrder = $iCparams->get('SingleDatesOrder', 1);
// List Model
$SingleDatesListModel = $iCparams->get('SingleDatesListModel', 1);
if ($SingleDates == 1)
{
// if ($this->accessLevels($accessSingleDates))
// {
$days = iCString::isSerialized($item->dates) ? unserialize($item->dates) : array(); // returns array
if ($SingleDatesOrder == 1)
{
rsort($days);
}
elseif ($SingleDatesOrder == 2)
{
sort($days);
}
$totDates = count($days);
if ($timeformat == 1)
{
$lang_time = 'H:i';
}
else
{
$lang_time = 'h:i A';
}
// Detect if Singles Dates, and no single date with null value
$displayDates = false;
$nbDays = count($days);
foreach ($days as $k => $d)
{
if (iCDate::isDate($d) && $nbDays != 0)
{
$displayDates = true;
}
}
$daysUl = '';
if ($displayDates)
{
if ($SingleDatesListModel == '2')
{
$n = 0;
$daysUl.= '<div class="alldates"><i>' . Text::_('COM_ICAGENDA_LEGEND_DATES') . ': </i>';
foreach ($days as $k => $d)
{
$n = $n+1;
$fd = icagendaRender::dateToFormat($d);
$timeDate = ($item->displaytime == 1)
? ' <span class="evttime">' . date($lang_time, strtotime($d)) . '</span>'
: '';
if ($n <= ($totDates-1))
{
$daysUl.= '<span class="alldates">' . $fd . $timeDate . '</span> - ';
}
elseif ($n == $totDates)
{
$daysUl.= '<span class="alldates">' . $fd . $timeDate . '</span>';
}
}
$daysUl.= '</div>';
}
else
{
$daysUl.= '<ul class="alldates">';
foreach ($days as $k => $d)
{
$fd = icagendaRender::dateToFormat($d);
$timeDate = ($item->displaytime == 1)
? ' <span class="evttime">' . date($lang_time, strtotime($d)) . '</span>'
: '';
$daysUl.= '<li class="alldates">' . $fd . $timeDate . '</li>';
}
$daysUl.= '</ul>';
}
}
if ($totDates > '0')
{
return $daysUl;
}
else
{
return false;
}
// }
// else
// {
// return false;
// }
}
else
{
return false;
}
}
/*
* Function to display the period text width formatted dates (eg. from 00-00-0000 to 00-00-0000).
* TO BE REFACTORED
* @TODO remove inline style html tags (check css and add class declarations)
* @TODO (3.7) remove old deprecated class names
*/
public static function displayPeriodDates($item)
{
$iCparams = ComponentHelper::getParams('com_icagenda');
// Hide/Show Option
$PeriodDates = $iCparams->get('PeriodDates', 1);
// List Model
$SingleDatesListModel = $iCparams->get('SingleDatesListModel', 1);
// First day of the week
$firstday_week_global = $iCparams->get('firstday_week_global', 1);
// Predefined variables
$wdays = $showDays = $timeOneDay = $end = '';
// WeekDays
$weekdays = $item->weekdays;
$weekdaysall = empty($weekdays) ? true : false;
if ($firstday_week_global == '1')
{
$weekdays_array = explode (',', $weekdays);
if (in_array('0', $weekdays_array))
{
$weekdays = str_replace('0', '', $weekdays);
$weekdays = $weekdays . ',7';
}
}
if ( ! $weekdaysall)
{
$weekdays_array = explode (',', $weekdays);
$wdaysArray = array();
foreach ($weekdays_array AS $wd)
{
if ($firstday_week_global != '1')
{
if ($wd == 0) $wdaysArray[] = Text::_('SUNDAY');
}
if ($wd == 1) $wdaysArray[] = Text::_('MONDAY');
if ($wd == 2) $wdaysArray[] = Text::_('TUESDAY');
if ($wd == 3) $wdaysArray[] = Text::_('WEDNESDAY');
if ($wd == 4) $wdaysArray[] = Text::_('THURSDAY');
if ($wd == 5) $wdaysArray[] = Text::_('FRIDAY');
if ($wd == 6) $wdaysArray[] = Text::_('SATURDAY');
if ($firstday_week_global == '1')
{
if ($wd == 7) $wdaysArray[] = Text::_('SUNDAY');
}
}
$last = array_slice($wdaysArray, -1);
$first = join(', ', array_slice($wdaysArray, 0, -1));
$both = array_filter(array_merge(array($first), $last));
// RTL css if site language is RTL
$lang = Factory::getLanguage();
$arrow_list = $lang->isRTL() ? '↵' : '↳';
$wdays = $arrow_list . ' <small><i><span class="ic-period-weekdays">' . join(' & ', $both) . '</span></i></small>';
}
if ($PeriodDates == 1
&& self::eventHasPeriod($item->period, $item->startdate, $item->enddate)
)
{
$startDate = icagendaRender::dateToFormat($item->startdate);
$endDate = icagendaRender::dateToFormat($item->enddate);
$startTime = icagendaRender::dateToTime($item->startdate);
$endTime = icagendaRender::dateToTime($item->enddate);
if ($startDate == $endDate)
{
$start = '<span class="ic-period-startdate">';
$start.= $startDate;
$start.= '</span>';
if ($item->displaytime == 1)
{
$timeOneDay = '<span class="evttime ic-period-time">' . $startTime;
$timeOneDay.= ($startTime !== $endTime) ? ' - ' . $endTime : '';
$timeOneDay.= '</span>';
}
}
else
{
$start = '<span class="ic-period-text-from">'
. ucfirst(Text::_('COM_ICAGENDA_PERIOD_FROM'))
. '</span> ';
$start.= '<span class="ic-period-startdate">'
. $startDate
. '</span>';
if ($item->displaytime == 1)
{
$start.= ' <span class="evttime ic-period-starttime">'
. $startTime
. '</span>';
}
$end = '<span class="ic-period-text-to">'
. Text::_('COM_ICAGENDA_PERIOD_TO')
. '</span> ';
$end.= '<span class="ic-period-enddate">'
. $endDate
. '</span>';
if ($item->displaytime == 1)
{
$end.= ' <span class="evttime ic-period-endtime">'
. $endTime
. '</span>';
}
$showDays = $wdays;
}
// Horizontal List
if ($SingleDatesListModel == 2)
{
$period = '<div class="ic-date-horizontal">' . Text::_('COM_ICAGENDA_EVENT_PERIOD') . ': ';
$period.= $start . ' ' . $end . ' ' . $timeOneDay;
if ( ! empty($showDays))
{
$period.= '<br /><span style="margin-left:30px">' . $showDays . '</span>';
}
$period.= '</div>';
}
// Vertical List
else
{
$period = '<ul class="ic-date-vertical"><li>';
$period.= $start . ' ' . $end . ' ' . $timeOneDay;
if ( ! empty($showDays))
{
$period.= '<br/>' . $showDays;
}
$period.= '</li></ul>';
}
return $period;
}
else
{
return false;
}
}
/*
* Function to check if period dates exist for this event
*/
public static function eventHasPeriod($period, $startdate, $enddate)
{
$period_dates = iCString::isSerialized($period) ? unserialize($period) : array(); // returns array
if (count($period_dates) > 0
&& iCDate::isDate($startdate)
&& iCDate::isDate($enddate))
{
return true;
}
return false;
}
/*
* Function to check if period is not finished
*/
public static function periodIsNotFinished($enddate)
{
$eventTimeZone = null;
$datetime_today = HTMLHelper::date('now', 'Y-m-d H:i');
$datetime_enddate = HTMLHelper::date($enddate, 'Y-m-d H:i', $eventTimeZone);
if (strtotime($datetime_enddate) > strtotime($datetime_today))
{
return true;
}
return false;
}
/*
* Function to set Meta-title for an event
*/
public static function setMetaTitle($item)
{
$limit = '60';
$metaTitle = iCFilterOutput::fullCleanHTML($item->title);
if (strlen($metaTitle) > $limit)
{
$string_cut = substr($metaTitle, 0, $limit);
$last_space = strrpos($string_cut, ' ');
$string_ok = substr($string_cut, 0, $last_space);
$metaTitle = $string_ok;
}
return $metaTitle;
}
/*
* Function to set Meta-description for an event
*/
public static function setMetaDesc($item)
{
$iCparams = ComponentHelper::getParams('com_icagenda');
$limit = $iCparams->get('char_limit_meta_description', '320');
$metaDesc = iCFilterOutput::fullCleanHTML($item->metadesc);
$metaDesc = (empty($metaDesc)) ? iCFilterOutput::fullCleanHTML($item->desc) : $metaDesc;
if (strlen($metaDesc) > $limit)
{
$string_cut = substr($metaDesc, 0, $limit);
$last_space = strrpos($string_cut, ' ');
$string_ok = substr($string_cut, 0, $last_space);
$metaDesc = $string_ok;
}
return $metaDesc;
}
/*
* Function to return event Url
*/
public static function eventURL($i)
{
$app = Factory::getApplication();
$input = $app->input;
$itemID = $input->get('Itemid', '0');
$eventnumber = $i->id;
$event_slug = empty($i->alias) ? $i->id : $i->id . ':' . $i->alias;
$date = $i->next;
// Get the "event" URL
$baseURL = Uri::base();
$subpathURL = Uri::base(true);
$baseURL = str_replace('/administrator', '', $baseURL);
$subpathURL = str_replace('/administrator', '', $subpathURL);
$urlevent = str_replace('&','&', Route::_('index.php?option=com_icagenda&view=event&Itemid=' . (int) $itemID . '&id=' . $event_slug));
// Sub Path filtering
$subpathURL = ltrim($subpathURL, '/');
// URL Event Details filtering
$urlevent = ltrim($urlevent, '/');
if (substr($urlevent, 0, strlen($subpathURL)+1) == "$subpathURL/")
{
$urlevent = substr($urlevent, strlen($subpathURL)+1);
}
$urlevent = rtrim($baseURL,'/') . '/' . ltrim($urlevent,'/');
$url = $urlevent;
if (is_numeric($itemID) && is_numeric($eventnumber)
&& ! is_array($itemID) && ! is_array($eventnumber)
)
{
return $url;
}
else
{
$url = Route::_('index.php');
return Uri::base() . $url;
}
}
/*
* Function to convert a datetime to URL alias
* (see iCDate::dateToAlias from iC Library for general function)
*
* @todo 3.8.0 (add &date= to this function to generate full date var)
*/
public static function urlDateVar($datetime)
{
if ( ! iCDate::isDate($datetime)) return false;
return '&date=' . iCDate::dateToAlias($datetime, 'Y-m-d-H-i');
}
/*
* Function to convert a URL date alias in an SQL datetime string.
*
* @return string The date string in SQL datetime format.
*/
public static function convertDateAliasToSQLDatetime($dateAlias)
{
if (strlen(iCDate::dateToNumeric($dateAlias)) != '12') return '';
$ex = explode('-', $dateAlias);
$datetime = (count($ex) == 5)
? $ex['0'] . '-' . $ex['1'] . '-' . $ex['2'] . ' ' . $ex['3'] . ':' . $ex['4'] . ':00'
: '';
return $datetime;
}
/*
* Function to generate the read more for introduction description
*/
public static function readMore($url, $desc, $content = '')
{
$iCparams = ComponentHelper::getParams('com_icagenda');
$limitGlobal = $iCparams->get('limitGlobal', 0);
if ($limitGlobal == 1)
{
$limit = $iCparams->get('ShortDescLimit', '100');
}
elseif ($limitGlobal == 0)
{
$customlimit = $iCparams->get('limit', '100');
$limit = is_numeric($customlimit) ? $customlimit : $iCparams->get('ShortDescLimit', '100');
}
$limit = is_numeric($limit) ? $limit : '1';
$readmore = '';
$readmore = ($limit <= 1) ? '' : $content;
$text = preg_replace('/<img[^>]*>/Ui', '', $desc);
if (strlen($text) > $limit)
{
$string_cut = substr($text, 0, $limit);
$last_space = strrpos($string_cut, ' ');
$string_ok = substr($string_cut, 0, $last_space);
$text = $string_ok . ' ';
$url = $url;
// $text = '<a href="' . $url . '" class="more" aria-hidden="true" tabindex="-1">' . $readmore . '</a>';
$text = $readmore;
}
else
{
$text = '';
}
return $text;
}
/**
* Loads the list of filled custom fields for this event
*
* @return array
*/
public static function getCustomFields($id = null)
{
$user = Factory::getApplication()->getIdentity();
$iCparams = ComponentHelper::getComponent('com_icagenda')->getParams();
$customFields = icagendaEventData::loadEventCustomFields($id);
$groups = $user->getAuthorisedViewLevels();
$global_show = $iCparams->get('show_cf_in_event_details', 1);
$global_access = $iCparams->get('access_cf_in_event_details', '');
foreach ($customFields as $cf) {
$CFparams = json_decode($cf->params);
$CFshow = (isset($CFparams->show_cf_in_event_details) && $CFparams->show_cf_in_event_details != '')
? $CFparams->show_cf_in_event_details
: $global_show;
$CFaccess = (isset($CFparams->access_cf_in_event_details) && $CFparams->access_cf_in_event_details != '')
? $CFparams->access_cf_in_event_details
: $global_access;
if ($CFshow && ($CFaccess == '' || \in_array($CFaccess, $groups))) {
if ($cf->title && $cf->value) {
switch ($cf->type) {
case 'url':
$cf->value = iCRender::urlTag($cf->value);
break;
case 'email':
$cf->value = HTMLHelper::_('email.cloak', $cf->value);
break;
default:
$cf->value = Text::_($cf->value);
break;
}
}
$cf->title = Text::_($cf->title);
} else {
$key = array_search($cf, $customFields);
if ($key !== false) {
unset($customFields[$key]);
}
}
}
return $customFields;
}
/**
* Function to get custom field groups of an event
*
* @param integer $id Event id
*
* @return array
*/
public static function getCustomfieldGroups($id = null)
{
// Create a new query object.
$db = Factory::getContainer()->get(\Joomla\Database\DatabaseInterface::class);
$query = (method_exists($db, 'createQuery') ? $db->createQuery() : $db->getQuery(true));
$query->select('e.params')
->from('#__icagenda_events AS e')
->where($db->qn('id') . ' = ' . $db->q($id));
$db->setQuery($query);
$result = $db->loadResult();
$result = $result ? json_decode($result) : '';
if (isset($result->custom_form))
{
return $result->custom_form;
}
return false;
}
}