Version 4.1.19

This commit is contained in:
Neo committed 2025-12-19 05:38:56 -08:00
1 parent 28bd025b35
commit 2bd5025018
2674 files changed
+233518 -77766

No files matched your search

+275 -44
View File
@@ -2,9 +2,9 @@
/**
* @brief Calendar Event Model
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @package IPS Community Suite
* @subpackage Calendar
* @since 7 Jan 2014
* @version SVN_VERSION_NUMBER
@@ -169,7 +169,7 @@ class _Event extends \IPS\Content\Item implements
public function set_title( $title )
{
$this->_data['title'] = $title;
$this->_data['title_seo'] = \IPS\Http\Url::seoTitle( $title );
$this->_data['title_seo'] = \IPS\Http\Url\Friendly::seoTitle( $title );
}
/**
@@ -181,11 +181,11 @@ class _Event extends \IPS\Content\Item implements
{
if( !$this->_data['title_seo'] )
{
$this->title_seo = \IPS\Http\Url::seoTitle( $this->title );
$this->title_seo = \IPS\Http\Url\Friendly::seoTitle( $this->title );
$this->save();
}
return $this->_data['title_seo'] ?: \IPS\Http\Url::seoTitle( $this->title );
return $this->_data['title_seo'] ?: \IPS\Http\Url\Friendly::seoTitle( $this->title );
}
/**
@@ -234,14 +234,15 @@ class _Event extends \IPS\Content\Item implements
/* Hold parameters to sprintf() into the language string */
$params = array();
$pluralize = array();
/* Figure out the basic language string */
$langString = "recur_human_" . $recurringData['event_repeats'];
if( $recurringData['event_repeat_freq'] > 1 )
{
$langString = $langString . '_multi';
$params[] = $recurringData['event_repeat_freq'];
$langString = $langString . '_multi';
$pluralize[] = $recurringData['event_repeat_freq'];
}
/* If recurring weekly, take days into account */
@@ -278,7 +279,7 @@ class _Event extends \IPS\Content\Item implements
$params[] = \IPS\Member::loggedIn()->language()->addToStack('recur_human__forever');
}
return \IPS\Member::loggedIn()->language()->addToStack( $langString, FALSE, array( 'sprintf' => $params ) );
return \IPS\Member::loggedIn()->language()->addToStack( $langString, FALSE, array( 'pluralize' => $pluralize, 'sprintf' => $params ) );
}
/**
@@ -384,7 +385,7 @@ class _Event extends \IPS\Content\Item implements
/* 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();
$nextTimes = array();
foreach ( $_repeatDays as $repeatDay )
{
$nextTimes[ $repeatDay ] = $date->adjust( "next {$repeatDay}" )->getTimestamp();
@@ -393,14 +394,28 @@ class _Event extends \IPS\Content\Item implements
$nextTimes = array_keys( $nextTimes );
$nextDay = array_shift( $nextTimes );
/* We have to reset the $_repeatDays array pointer so that it matches $nextDay, otherwise it is possible a day might be skipped */
while( current( $_repeatDays ) !== $nextDay )
{
$resetNextDay = next( $_repeatDays );
if( $resetNextDay === FALSE )
{
reset( $_repeatDays );
$resetNextDay = current( $_repeatDays );
}
}
/* We need to set a counter in case we need to repeat every X weeks */
$iteration = 1;
/* Do we have an occurrences limit? */
if( $recurringData['repeat_end_occurrences'] )
{
while( $occurrences < $recurringData['repeat_end_occurrences'] )
{
$date = $date->adjust( "next {$nextDay}" );
$eDate = ( $eDate !== NULL ) ? $eDate->adjust( "next {$nextDay}" ) : NULL;
$occurrences++;
$eDate = ( $eDate !== NULL ) ? $eDate->adjust( "next {$nextDay}" ) : NULL;
/* Figure out the next day this occurs on */
$nextDay = next( $_repeatDays );
@@ -411,6 +426,16 @@ class _Event extends \IPS\Content\Item implements
$nextDay = current( $_repeatDays );
}
/* Are we repeating every other week or something? */
if( $recurringData['event_repeat_freq'] AND $iteration % $recurringData['event_repeat_freq'] != 0 )
{
$iteration++;
continue;
}
$iteration++;
$occurrences++;
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
( $eDate !== NULL AND $date->mysqlDatetime( FALSE ) <= $startDate->mysqlDatetime( FALSE ) AND $eDate->mysqlDatetime( FALSE ) >= $endDate->mysqlDatetime( FALSE ) )
@@ -437,6 +462,15 @@ class _Event extends \IPS\Content\Item implements
$nextDay = current( $_repeatDays );
}
/* Are we repeating every other week or something? */
if( $recurringData['event_repeat_freq'] AND $iteration % $recurringData['event_repeat_freq'] != 0 )
{
$iteration++;
continue;
}
$iteration++;
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
( $eDate !== NULL AND $date->mysqlDatetime( FALSE ) <= $startDate->mysqlDatetime( FALSE ) AND $eDate->mysqlDatetime( FALSE ) >= $endDate->mysqlDatetime( FALSE ) )
@@ -463,6 +497,15 @@ class _Event extends \IPS\Content\Item implements
$nextDay = current( $_repeatDays );
}
/* Are we repeating every other week or something? */
if( $recurringData['event_repeat_freq'] AND $iteration % $recurringData['event_repeat_freq'] != 0 )
{
$iteration++;
continue;
}
$iteration++;
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
( $eDate !== NULL AND $date->mysqlDatetime( FALSE ) <= $startDate->mysqlDatetime( FALSE ) AND $eDate->mysqlDatetime( FALSE ) >= $endDate->mysqlDatetime( FALSE ) )
@@ -553,7 +596,7 @@ class _Event extends \IPS\Content\Item implements
}
}
}
return $results;
}
@@ -750,6 +793,68 @@ class _Event extends \IPS\Content\Item implements
return $this->dateObjects['end'];
}
/**
* Get a string with the event date/times in the timezone of the user who created the event
* Used in outgoing emails
*
* @param \IPS\Lang $language The language to use
* @return string
*/
public function fixedDateTimeDescription( \IPS\Lang $language )
{
/* Init */
$return = '';
try
{
$authorTimezone = new \DateTimeZone( $this->author()->timezone );
}
catch ( \Exception $e )
{
$authorTimezone = new \DateTimeZone('UTC');
}
/* Start */
$start = $this->_start_date->setTimezone( $authorTimezone );
$startOffset = $authorTimezone->getOffset( $start ) / 3600;
$return .= $start->calendarDate( $language );
if ( !$this->all_day )
{
$return .= ' ' . $start->localeTime( FALSE, TRUE, $language );
}
if ( $startOffset )
{
$return .= ' (GMT' . ( ( $startOffset > 0 ) ? '+' : '' ) . $startOffset . ')';
}
else
{
$return .= ' (GMT)';
}
/* End */
if ( $this->_end_date )
{
$return .= ' - ';
$end = $this->_end_date->setTimezone( $authorTimezone );
$endOffset = $authorTimezone->getOffset( $end ) / 3600; // Unlikely, but if the event spans the DST switch, the end offset could be different to the start
$return .= $end->calendarDate( $language );
if ( !$this->all_day )
{
$return .= ' ' . $end->localeTime( FALSE, TRUE, $language );
}
if ( $endOffset )
{
$return .= ' (GMT' . ( ( $endOffset > 0 ) ? '+' : '' ) . $endOffset . ')';
}
else
{
$return .= ' (GMT)';
}
}
/* Return */
return $return;
}
/**
* @brief Cached URLs
@@ -865,11 +970,11 @@ class _Event extends \IPS\Content\Item implements
*/
public function commentReviews( $tab )
{
if ( $tab === 'reviews' )
if ( $tab === 'reviews' and $this->container()->allow_reviews )
{
return \IPS\Theme::i()->getTemplate('view')->reviews( $this );
}
elseif( $tab === 'comments' )
elseif( $tab === 'comments' and $this->container()->allow_comments )
{
return \IPS\Theme::i()->getTemplate('view')->comments( $this );
}
@@ -903,7 +1008,7 @@ class _Event extends \IPS\Content\Item implements
public function moderateNewComments( \IPS\Member $member )
{
$commentClass = static::$commentClass;
return $this->container()->comment_moderate and !$member->group['g_avoid_q'];
return ( $this->container()->comment_moderate and !$member->group['g_avoid_q'] ) or parent::moderateNewComments( $member );
}
/**
@@ -915,7 +1020,7 @@ class _Event extends \IPS\Content\Item implements
public function moderateNewReviews( \IPS\Member $member )
{
$reviewClass = static::$reviewClass;
return $this->container()->review_moderate and !$member->group['g_avoid_q'];
return ( $this->container()->review_moderate and !$member->group['g_avoid_q'] ) or parent::moderateNewReviews( $member );
}
/**
@@ -933,7 +1038,7 @@ 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 int $container Container (e.g. forum) ID, if appropriate
* @param \IPS\Node\Model|NULL $container Container (e.g. forum) ID, if appropriate
* @return array
*/
public static function formElements( $item=NULL, \IPS\Node\Model $container=NULL )
@@ -949,7 +1054,7 @@ class _Event extends \IPS\Content\Item implements
/* We are using a custom template to provide an optimal experience for the user instead of a basic linear top-down form elements for the date fields */
$dateValues = array(
'single_day' => $item ? !$item->end_date : TRUE,
'single_day' => $item ? ( !$item->end_date or ( \IPS\calendar\Date::parseTime( $item->start_date, $item->all_day ? FALSE : TRUE )->format('Y-m-d') === \IPS\calendar\Date::parseTime( $item->end_date, $item->all_day ? FALSE : TRUE )->format('Y-m-d') ) ) : TRUE,
'start_date' => $item ? \IPS\calendar\Date::parseTime( $item->start_date, $item->all_day ? FALSE : TRUE ) : \IPS\calendar\Date::parseTime( $newDefault ),
'end_date' => ( $item AND $item->end_date ) ? \IPS\calendar\Date::parseTime( $item->end_date, $item->all_day ? FALSE : TRUE ) : NULL,
'all_day' => $item ? $item->all_day : $allDay,
@@ -1004,7 +1109,7 @@ class _Event extends \IPS\Content\Item implements
}
$end = null;
if( isset( $val['end_date'] ) AND $val['end_date'] )
{
if( !isset( $val['single_day'] ) OR !$val['single_day'] )
@@ -1021,8 +1126,19 @@ class _Event extends \IPS\Content\Item implements
}
}
}
else
{
try
{
$end = \IPS\calendar\Date::createFromForm( $val['start_date'], ( ( !isset( $val['all_day'] ) OR !$val['all_day'] ) ? $val['end_time'] : NULL ), ( isset( $val['all_day'] ) AND $val['all_day'] ) ? 'UTC' : $val['event_timezone'] )->format( 'Y-m-d H:i' );
}
catch( \Exception $e )
{
throw new \DomainException( "invalid_end_date" );
}
}
}
/* Check the dates */
if( $start === NULL )
{
@@ -1056,9 +1172,9 @@ class _Event extends \IPS\Content\Item implements
}
}, NULL, NULL, 'event_dates' );
/* Init */
$return['calendar'] = new \IPS\Helpers\Form\Node( static::$formLangPrefix . 'container', $container ? $container->id : ( isset( \IPS\Request::i()->id ) ? \IPS\Request::i()->id : NULL ), TRUE, array(
$return['calendar'] = new \IPS\Helpers\Form\Node( static::$formLangPrefix . 'container', $container ? $container->id : ( isset( \IPS\Request::i()->calendar ) ? \IPS\Request::i()->calendar : NULL ), TRUE, array(
'url' => \IPS\Http\Url::internal( 'app=calendar&module=calendar&controller=submit', 'front', 'calendar_submit' ),
'class' => 'IPS\calendar\Calendar',
'permissionCheck' => 'add',
@@ -1087,8 +1203,11 @@ class _Event extends \IPS\Content\Item implements
}
/* Event - request RSVP */
$return['rsvp'] = new \IPS\Helpers\Form\YesNo( 'event_rsvp', $item ? $item->rsvp : NULL, FALSE, array( 'togglesOn' => array( 'event_rsvp_limit' ) ), NULL, NULL, NULL, 'event_rsvp' );
$return['rsvplimit'] = new \IPS\Helpers\Form\Number( 'event_rsvp_limit', $item ? $item->rsvp_limit : -1, FALSE, array( 'unlimited' => -1 ), NULL, NULL, NULL, 'event_rsvp_limit' );
if( $container and $container->can( 'askrsvp', $item ? $item->author() : \IPS\Member::loggedIn() ) )
{
$return['rsvp'] = new \IPS\Helpers\Form\YesNo( 'event_rsvp', $item ? $item->rsvp : NULL, FALSE, array( 'togglesOn' => array( 'event_rsvp_limit' ) ), NULL, NULL, NULL, 'event_rsvp' );
$return['rsvplimit'] = new \IPS\Helpers\Form\Number( 'event_rsvp_limit', $item ? $item->rsvp_limit : -1, FALSE, array( 'unlimited' => -1 ), NULL, NULL, NULL, 'event_rsvp_limit' );
}
return $return;
}
@@ -1133,6 +1252,20 @@ class _Event extends \IPS\Content\Item implements
$this->start_date = \IPS\calendar\Date::createFromForm( $values['event_dates']['start_date'], ( ( !isset( $values['event_dates']['all_day'] ) OR !$values['event_dates']['all_day'] ) ? $values['event_dates']['start_time'] : NULL ), ( isset( $values['event_dates']['all_day'] ) AND $values['event_dates']['all_day'] ) ? 'UTC' : $values['event_dates']['event_timezone'] )->format( 'Y-m-d H:i' );
$this->end_date = null;
/* Clear clear fields for non-selected items */
switch( $values['event_dates']['repeat_end'] )
{
case 'never':
unset( $values['event_dates']['repeat_end_occurrences'], $values['event_dates']['repeat_end_date'] );
break;
case 'after':
unset( $values['event_dates']['repeat_end_date'] );
break;
case 'date':
unset( $values['event_dates']['repeat_end_occurrences'] );
break;
}
if( isset( $values['event_dates']['end_date'] ) AND $values['event_dates']['end_date'] )
{
if( !isset( $values['event_dates']['single_day'] ) OR !$values['event_dates']['single_day'] )
@@ -1170,7 +1303,7 @@ class _Event extends \IPS\Content\Item implements
}
/* Cover photo */
$this->cover_photo = ( $values['event_cover_photo'] !== NULL ) ? $values['event_cover_photo']->url : NULL;
$this->cover_photo = ( $values['event_cover_photo'] !== NULL ) ? (string) $values['event_cover_photo'] : NULL;
/* Set location */
$this->location = ( $values['event_location'] !== NULL ) ? json_encode( $values['event_location'] ) : NULL;
@@ -1186,8 +1319,8 @@ class _Event extends \IPS\Content\Item implements
}
/* RSVP options */
$this->rsvp = $values['event_rsvp'];
$this->rsvp_limit = $values['event_rsvp_limit'];
$this->rsvp = isset( $values['event_rsvp'] ) ? $values['event_rsvp'] : FALSE;
$this->rsvp_limit = isset( $values['event_rsvp_limit'] ) ? $values['event_rsvp_limit'] : 0;
/* Get the normal stuff */
parent::processForm( $values );
@@ -1206,6 +1339,21 @@ class _Event extends \IPS\Content\Item implements
/* And claim attachments */
\IPS\File::claimAttachments( 'calendar-event', $this->id );
/* And expire widget caches so an event for today will show in the upcoming events widget properly */
$this->expireWidgetCaches();
}
/**
* Create Notification
*
* @param string|NULL $extra Additional data
* @return \IPS\Notification
*/
protected function createNotification( $extra=NULL )
{
// New content is sent with itself as the item as we deliberately do not group notifications about new content items. Unlike comments where you're going to read them all - you might scan the notifications list for topic titles you're interested in
return new \IPS\Notification( \IPS\Application::load( 'calendar' ), 'new_content', $this, array( $this ) );
}
/**
@@ -1227,7 +1375,7 @@ class _Event extends \IPS\Content\Item implements
* Return the map for the event, if location is specified
*
* @param int $width Width
* @param int $heigth Height
* @param int $height Height
* @return string
* @note \BadMethodCallException can be thrown if the google maps integration is shut off - don't show any error if that happens.
*/
@@ -1251,8 +1399,9 @@ class _Event extends \IPS\Content\Item implements
* @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
* @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\Member $member The member (NULL to use currently logged in member)
* @return \IPS\Patterns\ActiveRecordIterator
* @throws \InvalidArgumentException
* @see \IPS\Content\_Item::getItemsWithPermission()
@@ -1286,7 +1435,7 @@ class _Event extends \IPS\Content\Item implements
}
/* Get timezone adjusted versions of start/end time */
$startDateTimezone = \IPS\calendar\Date::parseTime( $startDate->mysqlDatetime() );
$startDateTimezone = \IPS\calendar\Date::parseTime( $startDate->mysqlDatetime(), TRUE );
$endDateTimezone = ( $endDate !== NULL ) ? \IPS\calendar\Date::parseTime( $endDate->mysqlDatetime() ) : NULL;
if ( $member->timezone )
@@ -1368,7 +1517,7 @@ class _Event extends \IPS\Content\Item implements
}
/* Get the non-recurring events */
$events = \IPS\calendar\Event::getItemsWithPermission( array_merge( $where, $nonRecurring ), 'event_start_date ASC', NULL, 'read', NULL, 0, $member );
$events = \IPS\calendar\Event::getItemsWithPermission( array_merge( $where, $nonRecurring ), 'event_start_date ASC', NULL, 'read', \IPS\Content\Hideable::FILTER_AUTOMATIC, 0, $member );
/* We need to make sure ranged events repeat each day that they occur on */
$formattedEvents = array();
@@ -1391,14 +1540,7 @@ class _Event extends \IPS\Content\Item implements
}
else
{
if( $event->all_day )
{
$formattedEvents[ \IPS\calendar\Date::parseTime( $event->start_date, FALSE )->mysqlDatetime( FALSE ) ]['single'][ $event->id ] = $event;
}
else
{
$formattedEvents[ $event->_start_date->mysqlDatetime( FALSE ) ]['single'][ $event->id ] = $event;
}
$formattedEvents[ $event->_start_date->mysqlDatetime( FALSE ) ]['single'][ $event->id ] = $event;
}
}
}
@@ -1408,13 +1550,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' ) ) ), 'event_start_date ASC', NULL, 'read', NULL, 0, $member );
$recurringEvents = \IPS\calendar\Event::getItemsWithPermission( array_merge( $where, array( array( 'event_recurring IS NOT NULL' ) ) ), 'event_start_date ASC', NULL, 'read', \IPS\Content\Hideable::FILTER_AUTOMATIC, 0, $member );
/* Loop over any results */
foreach( $recurringEvents as $event )
{
/* Find occurrences within our date range (if any) */
$occurrences = $event->findOccurrences( $startDate, ( $endDate ? $endDate : $startDate->adjust( "+2 years" ) ) );
$thisEndDate = ( $endDate ? $endDate : $startDate->adjust( "+2 years" ) );
$occurrences = $event->findOccurrences( $startDate, $thisEndDate );
/* Do we have any? */
if( count( $occurrences ) )
@@ -1428,7 +1571,8 @@ class _Event extends \IPS\Content\Item implements
if( $occurrence['endDate'] !== NULL )
{
$date = $occurrence['startDate'];
while( $date->mysqlDatetime( FALSE ) < $occurrence['endDate']->mysqlDatetime( FALSE ) )
$eDate = ( $thisEndDate->mysqlDatetime( FALSE ) < $occurrence['endDate']->mysqlDatetime( FALSE ) ) ? $thisEndDate : $occurrence['endDate'];
while( $date->mysqlDatetime( FALSE ) < $eDate->mysqlDatetime( FALSE ) )
{
$formattedEvents[ $date->mysqlDatetime( FALSE ) ]['ranged'][ $event->id ] = $event;
$date = $date->adjust( '+1 day' );
@@ -1456,6 +1600,16 @@ class _Event extends \IPS\Content\Item implements
/* @note: Error suppressor is needed due to PHP bug https://bugs.php.net/bug.php?id=50688 */
@usort( $formattedEvents, function( $a, $b ) use ( $startDate )
{
if( $a->nextOccurrence( $startDate, 'startDate' ) === NULL )
{
return -1;
}
if( $b->nextOccurrence( $startDate, 'startDate' ) === NULL )
{
return 1;
}
if ( $a->nextOccurrence( $startDate, 'startDate' )->mysqlDatetime() == $b->nextOccurrence( $startDate, 'startDate' )->mysqlDatetime() )
{
return 0;
@@ -1555,7 +1709,7 @@ class _Event extends \IPS\Content\Item implements
* @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|NULL $containerData Basic data about the container. 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'
@@ -1581,4 +1735,81 @@ class _Event extends \IPS\Content\Item implements
return \IPS\Theme::i()->getTemplate( 'global', 'calendar', 'front' )->searchResultEventSnippet( $indexData, $itemData, $nextOccurance, $startDate, $endDate, $itemData['event_all_day'], $view == 'condensed' );
}
/**
* Get output for API
*
* @return array
* @apiresponse int id ID number
* @apiresponse string title Title
* @apiresponse \IPS\calendar\Calendar calendar Calendar
* @apiresponse datetime start Event start time
* @apiresponse datetime end Event end time
* @apiresponse string recurrence If this event recurs, the ICS recurrence definition
* @apiresponse bool rsvp If this event accepts RSVPs
* @apiresponse int rsvpLimit The number of RSVPs the event is limited to
* @apiresponse \IPS\GeoLocation location The location where the event is taking place
* @apiresponse \IPS\Member author The member thgat created the event
* @apiresponse datetime postedDate When the event was created
* @apiresponse string description Event description
* @apiresponse int comments Number of comments
* @apiresponse int reviews Number of reviews
* @apiresponse int views Number of posts
* @apiresponse string prefix The prefix tag, if there is one
* @apiresponse [string] tags The tags
* @apiresponse bool locked Event is locked
* @apiresponse bool hidden Event is hidden
* @apiresponse bool featured Event is featured
* @apiresponse string url URL
*/
public function apiOutput()
{
return array(
'id' => $this->tid,
'title' => $this->title,
'calendar' => $this->container()->apiOutput(),
'start' => $this->_start_date->rfc3339(),
'end' => $this->_end_date ? $this->_end_date->rfc3339() : NULL,
'recurrence' => $this->recurring,
'rsvp' => (bool) $this->rsvp,
'rsvpLimit' => $this->rsvp_limit == -1 ? null : $this->rsvp_limit,
'location' => $this->location ? \IPS\GeoLocation::buildFromJson( $this->location )->apiOutput() : null,
'author' => $this->author()->apiOutput(),
'postedDate' => \IPS\DateTime::ts( $this->saved )->rfc3339(),
'description' => $this->content(),
'comments' => $this->comments,
'reviews' => $this->reviews,
'views' => $this->views,
'prefix' => $this->prefix(),
'tags' => $this->tags(),
'locked' => (bool) $this->locked(),
'hidden' => (bool) $this->hidden(),
'featured' => (bool) $this->mapped('featured'),
'url' => (string) $this->url(),
);
}
/**
* Can comment?
*
* @param \IPS\Member\NULL $member The member (NULL for currently logged in member)
* @return bool
*/
public function canComment( $member=NULL )
{
$member = $member ?: \IPS\Member::loggedIn();
return parent::canComment( $member ) and $this->container()->allow_comments;
}
/**
* Can review?
*
* @param \IPS\Member\NULL $member The member (NULL for currently logged in member)
* @return bool
*/
public function canReview( $member = NULL )
{
$member = $member ?: \IPS\Member::loggedIn();
return parent::canReview( $member ) and $this->container()->allow_reviews;
}
}