Version 4.6.0

This commit is contained in:
Neo committed 2025-12-19 05:55:31 -08:00
1 parent f79dcf067a
commit 517a5e1f70
2036 files changed
+110041 -26162

No files matched your search

+48 -25
View File
@@ -31,7 +31,8 @@ class _Event extends \IPS\Content\Item implements
\IPS\Content\Searchable,
\IPS\Content\Embeddable,
\IPS\Content\MetaData,
\IPS\Content\EditHistory
\IPS\Content\EditHistory,
\IPS\Content\Anonymous
{
use \IPS\Content\Reactable, \IPS\Content\Reportable;
@@ -81,6 +82,7 @@ class _Event extends \IPS\Content\Item implements
public static $databaseColumnMap = array(
'container' => 'calendar_id',
'author' => 'member_id',
'author_name' => 'author_name',
'title' => 'title',
'content' => 'content',
'num_comments' => 'comments',
@@ -107,6 +109,7 @@ class _Event extends \IPS\Content\Item implements
'edit_show' => 'append_edit',
'edit_member_name' => 'edit_member_name',
'edit_reason' => 'edit_reason',
'is_anon' => 'is_anon',
);
/**
@@ -681,11 +684,18 @@ class _Event extends \IPS\Content\Item implements
- Then we can work forwards from there at the frequency interval. If start was year 1778, we can effectively skip forward to within a few days of our period more efficiently this way, rather than truly starting in 1778 and skipping forward 4 days at a time.
*/
$diff = $startDate->diff( $date );
$days = $diff->days % ( $recurringData['event_repeat_freq'] * 7 );
$dayOff = $diff->days;
if( ( ( $diff->h * 3600 ) + ( $diff->i * 60 ) + $diff->s ) < ( ( $date->format('H') * 3600 ) + ( $date->format('i') * 60 ) + $date->format('s') ) )
{
$dayOff += 1;
}
$days = $dayOff % ( $recurringData['event_repeat_freq'] * 7 );
$date = ( clone $startDate )->sub( new \DateInterval( 'P' . $days . 'D' ) )
->setTimezone( $date->getTimezone() )
->setTime( $date->format('H'), $date->format( 'i' ), $date->format('s') );
->setTime( $date->format('H'), $date->format('i'), $date->format('s') );
$eDate = static::_determineNewEndDate( $eventStart, $eventEnd, $date, $eDate );
}
@@ -789,6 +799,15 @@ class _Event extends \IPS\Content\Item implements
return ( $type === 'startDate' ) ? $this->_start_date : $this->_end_date;
}
/* If we have passed the last recurrence date, return the start or end date */
if( $this->recurring_end_date )
{
if( strtotime( $this->recurring_end_date ) < time() )
{
return ( $type === 'startDate' ) ? $this->_start_date : $this->_end_date;
}
}
/* This is typically called after findOccurrences() using the same start date, so try the cached array first */
if( \count( $this->parsedOccurrences ) )
{
@@ -832,22 +851,22 @@ class _Event extends \IPS\Content\Item implements
}
/* If we are checking end date, or if the end date is the same as the start date, then we can simply compare the dates */
if( $type == 'endDate' OR !$occurrence['endDate'] OR $occurrence['startDate']->mysqlDatetime( FALSE, TRUE ) == $occurrence['endDate']->mysqlDatetime( FALSE, TRUE ) )
if( $type == 'endDate' OR !$occurrence['endDate'] OR $occurrence['startDate']->mysqlDatetime( FALSE ) == $occurrence['endDate']->mysqlDatetime( FALSE ) )
{
if( $occurrence[ $type ] AND $occurrence[ $type ]->mysqlDatetime( FALSE, TRUE ) >= $date->mysqlDatetime( FALSE, TRUE ) )
if( $occurrence[ $type ] AND $occurrence[ $type ]->mysqlDatetime( FALSE ) >= $date->mysqlDatetime( FALSE ) )
{
return TRUE;
}
}
/* Otherwise if this is a ranged event, then what we really want to determine is if the date in question falls within the range or comes after */
if( $type == 'startDate' AND ( !$occurrence['endDate'] OR $occurrence['endDate']->mysqlDatetime( FALSE, TRUE ) > $occurrence['startDate']->mysqlDatetime( FALSE, TRUE ) ) )
if( $type == 'startDate' AND ( !$occurrence['endDate'] OR $occurrence['endDate']->mysqlDatetime( FALSE ) > $occurrence['startDate']->mysqlDatetime( FALSE ) ) )
{
if( $occurrence['startDate']->mysqlDatetime( FALSE, TRUE ) >= $date->mysqlDatetime( FALSE, TRUE ) )
if( $occurrence['startDate']->mysqlDatetime( FALSE ) >= $date->mysqlDatetime( FALSE ) )
{
return TRUE;
}
elseif( $occurrence['endDate'] AND $date->mysqlDatetime( FALSE, TRUE ) >= $occurrence['startDate']->mysqlDatetime( FALSE, TRUE ) AND $date->mysqlDatetime( FALSE, TRUE ) <= $occurrence['endDate']->mysqlDatetime( FALSE, TRUE ) )
elseif( $occurrence['endDate'] AND $date->mysqlDatetime( FALSE ) >= $occurrence['startDate']->mysqlDatetime( FALSE ) AND $date->mysqlDatetime( FALSE ) <= $occurrence['endDate']->mysqlDatetime( FALSE ) )
{
return TRUE;
}
@@ -1284,10 +1303,11 @@ class _Event extends \IPS\Content\Item implements
* Get elements for add/edit form
*
* @param \IPS\Content\Item|NULL $item The current item if editing or NULL if creating
* @param \IPS\Node\Model|NULL $container Container (e.g. forum) ID, if appropriate
* @param \IPS\Node\Model|NULL $container Container (e.g. forum) ID, if appropriate
* @param bool $isCopy TRUE if we are copying $item rather than editing it
* @return array
*/
public static function formElements( $item=NULL, \IPS\Node\Model $container=NULL )
public static function formElements( $item=NULL, \IPS\Node\Model $container=NULL, $isCopy=FALSE )
{
$newDefault = date( 'Y-m-d' );
$allDay = FALSE;
@@ -1304,7 +1324,7 @@ class _Event extends \IPS\Content\Item implements
$startDateObj = \IPS\calendar\Date::parseTime( $item->start_date, $item->all_day ? FALSE : TRUE );
$endDateObj = $item->end_date ? \IPS\calendar\Date::parseTime( $item->end_date, $item->all_day ? FALSE : TRUE ) : NULL;
if( $item->timezone )
if( $item->timezone AND !$item->all_day )
{
if( preg_match( "/-?([0-9]+?)(\.[0-9]+)?/", $item->timezone ) )
{
@@ -1549,7 +1569,7 @@ 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, 'allowStockPhotos' => TRUE, 'storageExtension' => 'calendar_Events' ) );
$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, 'allowStockPhotos' => TRUE, 'storageExtension' => 'calendar_Events', 'retainDeleted' => $isCopy ) );
if( \IPS\Settings::i()->calendar_venues_enabled )
{
@@ -1900,6 +1920,8 @@ class _Event extends \IPS\Content\Item implements
/* We should not delete maps for imported events, because we do not want to reimport them */
//\IPS\Db::i()->delete( 'calendar_import_map', array( 'import_event_id=?', $this->id ) );
$this->coverPhoto()->delete();
}
/**
@@ -2079,20 +2101,20 @@ class _Event extends \IPS\Content\Item implements
foreach( $events as $event )
{
/* Is this a ranged event? */
if( $event->_end_date !== NULL AND $event->_start_date->mysqlDatetime( FALSE, TRUE ) < $event->_end_date->mysqlDatetime( FALSE, TRUE ) )
if( $event->_end_date !== NULL AND $event->_start_date->mysqlDatetime( FALSE ) < $event->_end_date->mysqlDatetime( FALSE ) )
{
$date = $event->_start_date;
while( $date->mysqlDatetime( FALSE, TRUE ) < $event->_end_date->mysqlDatetime( FALSE, TRUE ) )
while( $date->mysqlDatetime( FALSE ) < $event->_end_date->mysqlDatetime( FALSE ) )
{
$formattedEvents[ $date->mysqlDatetime( FALSE ) ]['ranged'][ $event->id ] = $event;
$date = $date->adjust( '+1 day' );
}
$formattedEvents[ $event->_end_date->mysqlDatetime( FALSE, TRUE ) ]['ranged'][ $event->id ] = $event;
$formattedEvents[ $event->_end_date->mysqlDatetime( FALSE ) ]['ranged'][ $event->id ] = $event;
}
else
{
$formattedEvents[ $event->_start_date->mysqlDatetime( FALSE, TRUE ) ]['single'][ $event->id ] = $event;
$formattedEvents[ $event->_start_date->mysqlDatetime( FALSE ) ]['single'][ $event->id ] = $event;
}
}
}
@@ -2102,13 +2124,14 @@ class _Event extends \IPS\Content\Item implements
}
/* Now get the recurring events.... */
$recurringEvents = \IPS\calendar\Event::getItemsWithPermission( array_merge( $where, array( array( 'event_recurring IS NOT NULL AND (event_recurring_end_date IS NULL OR DATE(event_recurring_end_date) >= ' . $startDate->mysqlDatetime( FALSE ) . ')' ) ) ), 'event_start_date ASC', NULL, ( $skipPermissions === TRUE ) ? NULL : 'read', ( $skipPermissions === TRUE ) ? \IPS\Content\Hideable::FILTER_SHOW_HIDDEN : \IPS\Content\Hideable::FILTER_AUTOMATIC, 0, $member );
$recurringEvents = \IPS\calendar\Event::getItemsWithPermission( array_merge( $where, array( array( "event_recurring IS NOT NULL AND (event_recurring_end_date IS NULL OR DATE(event_recurring_end_date) >= '{$startDate->mysqlDatetime( FALSE )}')" ) ) ), 'event_start_date ASC', NULL, ( $skipPermissions === TRUE ) ? NULL : 'read', ( $skipPermissions === TRUE ) ? \IPS\Content\Hideable::FILTER_SHOW_HIDDEN : \IPS\Content\Hideable::FILTER_AUTOMATIC, 0, $member );
/* Loop over any results */
foreach( $recurringEvents as $event )
{
/* Find occurrences within our date range (if any) */
$thisEndDate = ( $endDate ? $endDate->setTime( 23, 59, 59 ) : $startDate->adjust( "+2 years" ) );
$thisEndDate = ( clone $thisEndDate )->adjust( "+1 day" );
$occurrences = $event->findOccurrences( $startDate, $thisEndDate );
/* Do we have any? */
@@ -2123,26 +2146,26 @@ class _Event extends \IPS\Content\Item implements
if( $occurrence['endDate'] !== NULL )
{
$date = $occurrence['startDate'];
$eDate = ( $thisEndDate->mysqlDatetime( FALSE, TRUE ) < $occurrence['endDate']->mysqlDatetime( FALSE, TRUE ) ) ? $thisEndDate : $occurrence['endDate'];
$eDate = ( $thisEndDate->mysqlDatetime( FALSE ) < $occurrence['endDate']->mysqlDatetime( FALSE ) ) ? $thisEndDate : $occurrence['endDate'];
if( $date->mysqlDatetime( FALSE, TRUE ) < $eDate->mysqlDatetime( FALSE, TRUE ) )
if( $date->mysqlDatetime( FALSE ) < $eDate->mysqlDatetime( FALSE ) )
{
while( $date->mysqlDatetime( FALSE, TRUE ) < $eDate->mysqlDatetime( FALSE, TRUE ) )
while( $date->mysqlDatetime( FALSE ) < $eDate->mysqlDatetime( FALSE ) )
{
$formattedEvents[ $date->mysqlDatetime( FALSE ) ]['ranged'][ $event->id ] = $event;
$date = $date->adjust( '+1 day' );
}
$formattedEvents[ $eDate->mysqlDatetime( FALSE, TRUE ) ]['ranged'][ $event->id ] = $event;
$formattedEvents[ $eDate->mysqlDatetime( FALSE ) ]['ranged'][ $event->id ] = $event;
}
else
{
$formattedEvents[ $date->mysqlDatetime( FALSE, TRUE ) ]['single'][ $event->id ] = $event;
$formattedEvents[ $date->mysqlDatetime( FALSE ) ]['single'][ $event->id ] = $event;
}
}
else
{
$formattedEvents[ $occurrence['startDate']->mysqlDatetime( FALSE, TRUE ) ]['single'][ $event->id ] = $event;
$formattedEvents[ $occurrence['startDate']->mysqlDatetime( FALSE ) ]['single'][ $event->id ] = $event;
}
}
}
@@ -2255,7 +2278,7 @@ class _Event extends \IPS\Content\Item implements
* @param string $title Title
* @return callable
*/
public function approvalQueueHtml( $ref=NULL, $container, $title )
public function approvalQueueHtml( $ref, $container, $title )
{
return \IPS\Theme::i()->getTemplate( 'modcp', 'calendar', 'front' )->approvalQueueItem( $this, $ref, $container, $title );
}
@@ -2326,7 +2349,7 @@ class _Event extends \IPS\Content\Item implements
* @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 )
public static function searchResultSnippet( array $indexData, array $authorData, array $itemData, ?array $containerData, 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;