Version 4.1.2

This commit is contained in:
Neo committed 2025-12-19 05:32:19 -08:00
1 parent 3ba79295ee
commit 28bd025b35
1131 files changed
+63658 -20579

No files matched your search

+150 -44
View File
@@ -145,6 +145,21 @@ class _Event extends \IPS\Content\Item implements
const RSVP_YES = 1;
const RSVP_MAYBE = 2;
/**
* Columns needed to query for search result / stream view
*
* @return array
*/
public static function basicDataColumns()
{
$return = parent::basicDataColumns();
$return[] = 'event_recurring';
$return[] = 'event_start_date';
$return[] = 'event_end_date';
$return[] = 'event_all_day';
return $return;
}
/**
* Set the title
*
@@ -308,10 +323,27 @@ class _Event extends \IPS\Content\Item implements
//return $results;
}
/* Now figure out when this event occurs on */
/* Return the results we found after storing them */
$this->parsedOccurrences = static::_findOccurances( $this->_start_date, $this->_end_date, $startDate, $endDate, $recurringData );
return $this->parsedOccurrences;
}
/**
* Get occurances
*
* @param \IPS\calendar\Date $eventStart Event start date
* @param \IPS\calendar\Date $eventEnd Event end date
* @param \IPS\calendar\Date $startDate Date to start from
* @param \IPS\calendar\Date $endDate Date to end at
* @param array $recurringData Reccurance data
*/
public static function _findOccurances( $eventStart, $eventEnd, $startDate, $endDate, $recurringData )
{
$instances = array();
$occurrences = 0;
$keyword = NULL;
$results = array();
switch( $recurringData['event_repeats'] )
{
@@ -338,8 +370,8 @@ class _Event extends \IPS\Content\Item implements
}
else
{
$date = $this->_start_date;
$eDate = $this->_end_date;
$date = $eventStart;
$eDate = $eventEnd;
if( ( $date->mysqlDatetime( FALSE ) >= $startDate->mysqlDatetime( FALSE ) AND $date->mysqlDatetime( FALSE ) <= $endDate->mysqlDatetime( FALSE ) ) OR
( $eDate !== NULL AND $eDate->mysqlDatetime( FALSE ) >= $startDate->mysqlDatetime( FALSE ) AND $eDate->mysqlDatetime( FALSE ) <= $endDate->mysqlDatetime( FALSE ) ) OR
@@ -348,8 +380,18 @@ class _Event extends \IPS\Content\Item implements
{
$results[] = array( 'startDate' => $date, 'endDate' => $eDate );
}
$nextDay = current( $_repeatDays );
/* Figure out which of teh days is next. For example, if the start date is a Wednesday, and the
event repeats every Monday and Friday, we need to start with Friday (not Monday) because that's
when the first occurance is */
$nextTimes = array();
foreach ( $_repeatDays as $repeatDay )
{
$nextTimes[ $repeatDay ] = $date->adjust( "next {$repeatDay}" )->getTimestamp();
}
asort( $nextTimes );
$nextTimes = array_keys( $nextTimes );
$nextDay = array_shift( $nextTimes );
/* Do we have an occurrences limit? */
if( $recurringData['repeat_end_occurrences'] )
@@ -445,8 +487,8 @@ class _Event extends \IPS\Content\Item implements
/* Normal recurrence checks */
if( $keyword !== NULL )
{
$date = $this->_start_date;
$eDate = $this->_end_date;
$date = $eventStart;
$eDate = $eventEnd;
if( ( $date->mysqlDatetime( FALSE ) >= $startDate->mysqlDatetime( FALSE ) AND $date->mysqlDatetime( FALSE ) <= $endDate->mysqlDatetime( FALSE ) ) OR
( $eDate !== NULL AND $eDate->mysqlDatetime( FALSE ) >= $startDate->mysqlDatetime( FALSE ) AND $eDate->mysqlDatetime( FALSE ) <= $endDate->mysqlDatetime( FALSE ) ) OR
@@ -496,7 +538,7 @@ class _Event extends \IPS\Content\Item implements
/* Recurs indefinitely... the most fun type... */
else
{
while( $date->mysqlDatetime( FALSE ) < $endDate->mysqlDatetime( FALSE ) )
while( $date->mysqlDatetime( FALSE ) <= $endDate->mysqlDatetime( FALSE ) )
{
if( ( $date->mysqlDatetime( FALSE ) >= $startDate->mysqlDatetime( FALSE ) AND $date->mysqlDatetime( FALSE ) <= $endDate->mysqlDatetime( FALSE ) ) OR
( $eDate !== NULL AND $eDate->mysqlDatetime( FALSE ) >= $startDate->mysqlDatetime( FALSE ) AND $eDate->mysqlDatetime( FALSE ) <= $endDate->mysqlDatetime( FALSE ) ) OR
@@ -511,11 +553,8 @@ class _Event extends \IPS\Content\Item implements
}
}
}
/* Return the results we found after storing them */
$this->parsedOccurrences = $results;
return $this->parsedOccurrences;
return $results;
}
/**
@@ -716,29 +755,21 @@ class _Event extends \IPS\Content\Item implements
* @brief Cached URLs
*/
protected $_url = array();
/**
* Get URL
*
* @param string|NULL $action Action
* @return \IPS\Http\Url
*/
public function url( $action=NULL )
{
$_key = md5( $action );
if( !isset( $this->_url[ $_key ] ) )
{
$this->_url[ $_key ] = \IPS\Http\Url::internal( "app=calendar&module=calendar&controller=event&id={$this->id}", 'front', 'calendar_event', $this->title_seo );
if ( $action )
{
$this->_url[ $_key ] = $this->_url[ $_key ]->setQueryString( 'do', $action );
}
}
return $this->_url[ $_key ];
}
/**
* @brief URL Base
*/
public static $urlBase = 'app=calendar&module=calendar&controller=event&id=';
/**
* @brief URL Base
*/
public static $urlTemplate = 'calendar_event';
/**
* @brief SEO Title Column
*/
public static $seoTitleColumn = 'title_seo';
/**
* Get URL for last comment page
@@ -772,6 +803,40 @@ class _Event extends \IPS\Content\Item implements
return array( \IPS\Theme::i()->getTemplate( 'global', 'calendar' ), 'rows' );
}
/**
* HTML to manage an item's follows
*
* @return callable
*/
public static function manageFollowRows()
{
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'calendar.css', 'calendar' ) );
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'calendar_responsive.css', 'calendar' ) );
return array( \IPS\Theme::i()->getTemplate( 'global', 'calendar', 'front' ), 'manageFollowRow' );
}
/**
* Are comments supported by this class?
*
* @param \IPS\Member\NULL $member The member to check for or NULL fto not check permission
* @return int
*/
public static function supportsComments( \IPS\Member $member = NULL )
{
return parent::supportsComments() and ( !$member or \IPS\calendar\Calendar::countWhere( 'read', $member, array( 'cal_allow_comments=1' ) ) );
}
/**
* Are reviews supported by this class?
*
* @param \IPS\Member\NULL $member The member to check for or NULL to not check permission
* @return int
*/
public static function supportsReviews( \IPS\Member $member = NULL )
{
return parent::supportsReviews() and ( !$member or \IPS\calendar\Calendar::countWhere( 'read', $member, array( 'cal_allow_reviews=1' ) ) );
}
/**
* Get available comment/review tabs
*
@@ -1009,12 +1074,12 @@ class _Event extends \IPS\Content\Item implements
/* Cover photo and location */
$return['header'] = new \IPS\Helpers\Form\Upload( 'event_cover_photo', ( $item AND $item->cover_photo ) ? \IPS\File::get( 'calendar_Events', $item->cover_photo ) : NULL, FALSE, array( 'image' => TRUE, 'storageExtension' => 'calendar_Events' ) );
$return['location'] = new \IPS\Helpers\Form\Address( 'event_location', ( $item AND $item->location ) ? \IPS\GeoLocation::buildFromJson( $item->location ) : NULL, FALSE, array( 'minimize' => TRUE ) );
$return['location'] = new \IPS\Helpers\Form\Address( 'event_location', ( $item AND $item->location ) ? \IPS\GeoLocation::buildFromJson( $item->location ) : NULL, FALSE, array( 'minimize' => TRUE, 'requireFullAddress' => FALSE ) );
/* Gallery album association */
if( \IPS\Application::appIsEnabled( 'gallery' ) )
{
$return['album'] = new \IPS\Helpers\Form\Node( 'event_album', ( $item AND $item->event_album ) ? $item->event_album : NULL, FALSE, array(
$return['album'] = new \IPS\Helpers\Form\Node( 'event_album', ( $item AND $item->album ) ? $item->album : NULL, FALSE, array(
'url' => \IPS\Http\Url::internal( 'app=calendar&module=calendar&controller=submit', 'front', 'calendar_submit' ),
'class' => 'IPS\gallery\Album',
'permissionCheck' => 'add',
@@ -1049,7 +1114,7 @@ class _Event extends \IPS\Content\Item implements
* @return void
*/
public function processForm( $values )
{
{
/* Anything but Chrome, basically, falls back to a text input and submitter might submit 22.00 instead of 22:00 */
if( isset( $values['event_dates']['start_time'] ) )
{
@@ -1183,11 +1248,11 @@ class _Event extends \IPS\Content\Item implements
/**
* Retrieve events to show based on a provided start and end date, optionally filtering by a supplied calendar
*
* @param \IPS\calendar\Date $startDate Date to start from
* @param \IPS\calendar\Date|NULL $endDate Cut off date for events. NULL accepted as a possible value only if $formatEvents is set to FALSE.
* @param \IPS\calendar\Calendar|NULL $calendar Calendar to filter by
* @param int|null $limit Maximum number of events to return (only supported when not formatting events)
* @param bool $formatEvents Whether or not to format events into a structured array
* @param \IPS\calendar\Date $startDate Date to start from
* @param \IPS\calendar\Date|NULL $endDate Cut off date for events. NULL accepted as a possible value only if $formatEvents is set to FALSE.
* @param \IPS\calendar\Calendar|NULL|array $calendar Calendar to filter by
* @param int|null $limit Maximum number of events to return (only supported when not formatting events)
* @param bool $formatEvents Whether or not to format events into a structured array
* @return \IPS\Patterns\ActiveRecordIterator
* @throws \InvalidArgumentException
* @see \IPS\Content\_Item::getItemsWithPermission()
@@ -1198,7 +1263,15 @@ class _Event extends \IPS\Content\Item implements
if( $calendar !== NULL )
{
$where[] = array( 'event_calendar_id=?', (int) $calendar->_id );
if ( is_array( $calendar ) )
{
$where[] = array( \IPS\Db::i()->in( 'event_calendar_id', $calendar ) );
}
else
{
$where[] = array( 'event_calendar_id=?', (int) $calendar->_id );
}
}
if( $endDate === NULL AND $formatEvents === TRUE )
@@ -1475,4 +1548,37 @@ class _Event extends \IPS\Content\Item implements
{
return \IPS\Theme::i()->getTemplate( 'global', 'calendar' )->embedCalendar_event( $this, $this->url()->setQueryString( $params ) );
}
/**
* Get snippet HTML for search result display
*
* @param array $indexData Data from the search index
* @param array $authorData Basic data about the author. Only includes columns returned by \IPS\Member::columnsForPhoto()
* @param array $itemData Basic data about the item. Only includes columns returned by item::basicDataColumns()
* @param array|NULL $containerData Basic data about the author. Only includes columns returned by container::basicDataColumns()
* @param array $reputationData Array of people who have given reputation and the reputation they gave
* @param int|NULL $reviewRating If this is a review, the rating
* @param string $view 'expanded' or 'condensed'
* @return callable
*/
public static function searchResultSnippet( array $indexData, array $authorData, array $itemData, array $containerData = NULL, array $reputationData, $reviewRating, $view )
{
$startDate = \IPS\calendar\Date::parseTime( $itemData['event_start_date'], $itemData['event_all_day'] ? FALSE : TRUE );
$endDate = $itemData['event_end_date'] ? \IPS\calendar\Date::parseTime( $itemData['event_end_date'], $itemData['event_all_day'] ? FALSE : TRUE ) : NULL;
$nextOccurance = $startDate;
if ( $itemData['event_recurring'] )
{
$occurances = \IPS\calendar\Event::_findOccurances( $startDate, $endDate, $startDate->adjust( "-1 month" ), $startDate->adjust( "+2 years" ), \IPS\calendar\Icalendar\ICSParser::parseRrule( $itemData['event_recurring'] ) );
foreach( $occurances as $occurrence )
{
if( $occurrence['startDate'] AND $occurrence['startDate']->mysqlDatetime( FALSE ) >= $startDate->mysqlDatetime( FALSE ) )
{
$nextOccurance = $occurrence['startDate'];
break;
}
}
}
return \IPS\Theme::i()->getTemplate( 'global', 'calendar', 'front' )->searchResultEventSnippet( $indexData, $itemData, $nextOccurance, $startDate, $endDate, $itemData['event_all_day'], $view == 'condensed' );
}
}