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

+2
View File
@@ -489,6 +489,8 @@ class _events extends \IPS\Content\Api\ItemController
'rsvp_date' => time(),
'rsvp_response' => (int) \IPS\Request::i()->response
) );
$member->achievementAction( 'calendar', 'Rsvp', $event );
return new \IPS\Api\Response( 200, NULL );
}
+1 -1
View File
@@ -6,7 +6,7 @@
"calendars"
]
},
"app=calendar&module=calendars&controller=calendars&do=form": {
"app=calendar&module=calendars&controller=calendars": {
"lang_key": "menu__calendar_calendars_calendars",
"restriction": "calendars_manage",
"keywords": [
+2 -1
View File
@@ -4,5 +4,6 @@
"app_directory": "calendar",
"app_protected": 0,
"app_website": null,
"app_update_check": null
"app_update_check": null,
"app_hide_tab": 0
}
+1 -2
View File
@@ -19,8 +19,7 @@
<widget key="todaysBirthdays"><![CDATA[{"class":"\\IPS\\Widget\\StaticCache","restrict":[],"default_area":"","allow_reuse":false,"menu_style":"menu","embeddable":true}]]></widget>
<widget key="upcomingEvents"><![CDATA[{"class":"\\IPS\\Widget\\PermissionCache","restrict":["sidebar","cms"],"default_area":"","allow_reuse":true,"menu_style":"menu","embeddable":true}]]></widget>
<widget key="recentReviews"><![CDATA[{"class":"\\IPS\\Widget\\PermissionCache","restrict":[],"default_area":"","allow_reuse":false,"menu_style":"menu","embeddable":true}]]></widget>
<acpsearch key="app=calendar&amp;module=calendars&amp;controller=calendars"><![CDATA[{"lang_key":"menu__calendar_calendars_calendars","restriction":"calendars_manage","keywords":["calendars"]}]]></acpsearch>
<acpsearch key="app=calendar&amp;module=calendars&amp;controller=calendars&amp;do=form"><![CDATA[{"lang_key":"menu__calendar_calendars_calendars","restriction":"calendars_manage","keywords":["edit calendar"]}]]></acpsearch>
<acpsearch key="app=calendar&amp;module=calendars&amp;controller=calendars"><![CDATA[{"lang_key":"menu__calendar_calendars_calendars","restriction":"calendars_manage","keywords":["edit calendar"]}]]></acpsearch>
<acpsearch key="app=calendar&amp;module=calendars&amp;controller=calendars&amp;do=permissions"><![CDATA[{"lang_key":"menu__calendar_calendars_calendars","restriction":"calendars_manage","keywords":["calendar permissions"]}]]></acpsearch>
<acpsearch key="app=calendar&amp;module=calendars&amp;controller=calendars&amp;searchResult=cal_comment_moderate"><![CDATA[{"lang_key":"cal_comment_moderate","restriction":"calendars_manage","keywords":["approved","comments must be approved","require approval"]}]]></acpsearch>
<acpsearch key="app=calendar&amp;module=calendars&amp;controller=calendars&amp;searchResult=form_1_cal_allow_comments"><![CDATA[{"lang_key":"cal_allow_comments","restriction":"calendars_manage","keywords":["allow comments","comments"]}]]></acpsearch>
+20 -17
View File
@@ -1,38 +1,41 @@
{
"core": {
"ContentRouter": {
"calendar": "IPS\\calendar\\extensions\\core\\ContentRouter\\calendar"
},
"StreamItems": {
"StreamItems": "IPS\\calendar\\extensions\\core\\StreamItems\\StreamItems"
},
"LiveSearch": {
"Calendars": "IPS\\calendar\\extensions\\core\\LiveSearch\\Calendars"
},
"FileStorage": {
"Events": "IPS\\calendar\\extensions\\core\\FileStorage\\Events"
"AchievementAction": {
"Rsvp": "IPS\\calendar\\extensions\\core\\AchievementAction\\Rsvp"
},
"Announcements": {
"Calendars": "IPS\\calendar\\extensions\\core\\Announcements\\Calendars"
},
"EditorLocations": {
"Venue": "IPS\\calendar\\extensions\\core\\EditorLocations\\Venue",
"Calendar": "IPS\\calendar\\extensions\\core\\EditorLocations\\Calendar"
},
"Permissions": {
"Permissions": "IPS\\calendar\\extensions\\core\\Permissions\\Permissions"
"ContentRouter": {
"calendar": "IPS\\calendar\\extensions\\core\\ContentRouter\\calendar"
},
"CreateMenu": {
"Event": "IPS\\calendar\\extensions\\core\\CreateMenu\\Event"
},
"EditorLocations": {
"Calendar": "IPS\\calendar\\extensions\\core\\EditorLocations\\Calendar",
"Venue": "IPS\\calendar\\extensions\\core\\EditorLocations\\Venue"
},
"FileStorage": {
"Events": "IPS\\calendar\\extensions\\core\\FileStorage\\Events"
},
"FrontNavigation": {
"Calendar": "IPS\\calendar\\extensions\\core\\FrontNavigation\\Calendar"
},
"LiveSearch": {
"Calendars": "IPS\\calendar\\extensions\\core\\LiveSearch\\Calendars"
},
"MemberSync": {
"Calendar": "IPS\\calendar\\extensions\\core\\MemberSync\\Calendar"
},
"Notifications": {
"Events": "IPS\\calendar\\extensions\\core\\Notifications\\Events"
},
"Permissions": {
"Permissions": "IPS\\calendar\\extensions\\core\\Permissions\\Permissions"
},
"StreamItems": {
"StreamItems": "IPS\\calendar\\extensions\\core\\StreamItems\\StreamItems"
}
}
}
+7 -7
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<javascript app="calendar">
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/browse" javascript_name="ips.browse.main.js" javascript_type="controller" javascript_version="105100" javascript_position="1000250"><![CDATA[/**
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/browse" javascript_name="ips.browse.main.js" javascript_type="controller" javascript_version="106107" javascript_position="1000250"><![CDATA[/**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -112,7 +112,7 @@
}
});
}(jQuery, _));]]></file>
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/browse" javascript_name="ips.browse.monthView.js" javascript_type="controller" javascript_version="105100" javascript_position="1000250"><![CDATA[/**
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/browse" javascript_name="ips.browse.monthView.js" javascript_type="controller" javascript_version="106107" javascript_position="1000250"><![CDATA[/**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -254,7 +254,7 @@
}
});
}(jQuery, _));]]></file>
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/submit" javascript_name="ips.submit.dates.js" javascript_type="controller" javascript_version="105100" javascript_position="1000100"><![CDATA[/**
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/submit" javascript_name="ips.submit.dates.js" javascript_type="controller" javascript_version="106107" javascript_position="1000100"><![CDATA[/**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -827,7 +827,7 @@
}
});
}(jQuery, _));]]></file>
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/venue" javascript_name="ips.venue.main.js" javascript_type="controller" javascript_version="105100" javascript_position="1000200"><![CDATA[/**
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/venue" javascript_name="ips.venue.main.js" javascript_type="controller" javascript_version="106107" javascript_position="1000200"><![CDATA[/**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -939,7 +939,7 @@
}
});
}(jQuery, _));]]></file>
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/view" javascript_name="ips.view.reminderButton.js" javascript_type="controller" javascript_version="105100" javascript_position="1000150"><![CDATA[/**
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/view" javascript_name="ips.view.reminderButton.js" javascript_type="controller" javascript_version="106107" javascript_position="1000150"><![CDATA[/**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -1022,7 +1022,7 @@
}
});
}(jQuery, _));]]></file>
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/view" javascript_name="ips.view.reminderForm.js" javascript_type="controller" javascript_version="105100" javascript_position="1000150">/**
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/view" javascript_name="ips.view.reminderForm.js" javascript_type="controller" javascript_version="106107" javascript_position="1000150">/**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -1132,7 +1132,7 @@
});
}(jQuery, _));
</file>
<file javascript_app="calendar" javascript_location="front" javascript_path="templates" javascript_name="ips.calendar.templates.js" javascript_type="framework" javascript_version="105100" javascript_position="1000050"><![CDATA[/**
<file javascript_app="calendar" javascript_location="front" javascript_path="templates" javascript_name="ips.calendar.templates.js" javascript_type="framework" javascript_version="106107" javascript_position="1000050"><![CDATA[/**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*/
+13 -1
View File
@@ -1,14 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<language>
<app key="calendar" version="105100">
<app key="calendar" version="106107">
<word key="__app_calendar" js="0">Calendar</word>
<word key="frontnavigation_calendar" js="0">Calendar</word>
<word key="__indefart_calendar_event_comment" js="0">a comment on a calendar event</word>
<word key="__indefart_calendar_event" js="0">a calendar event</word>
<word key="__indefart_calendar_event_review" js="0">a review on a calendar event</word>
<word key="__defart_calendar_event_comment" js="0">comment on a calendar event</word>
<word key="__defart_calendar_event_comment_plural" js="0">{!#[1:comment][?:comments]} on a calendar event</word>
<word key="__defart_calendar_event" js="0">calendar event</word>
<word key="__defart_calendar_event_plural" js="0">calendar {!#[1:event][?:events]}</word>
<word key="__defart_calendar_event_review" js="0">review on a calendar event</word>
<word key="__defart_calendar_event_review_plural" js="0">{!#[1:review][?:reviews]} on a calendar event</word>
<word key="calendar_event_container" js="0">calendar</word>
<word key="menu__calendar_calendars" js="0">Calendar</word>
<word key="menu__calendar_calendars_calendars" js="0">Calendars</word>
@@ -76,6 +79,7 @@
<word key="calendar_block_past_changes_desc" js="0">If enabled, users will not be able to RSVP for events or edit events that have passed. Moderators will still be able to edit past events.</word>
<word key="calendars" js="0">Calendars</word>
<word key="calendars_sg" js="0">Calendar</word>
<word key="calendars_sg_lc" js="0">calendar</word>
<word key="calendar_settings" js="0">Settings</word>
<word key="calendar_permissions" js="0">Permissions</word>
<word key="calendar_moderation" js="0">Moderation</word>
@@ -454,6 +458,7 @@
<word key="email_event_reminder_where" js="0">Where: %s</word>
<word key="days_to_go" js="0">{# [1:day][?:days]}</word>
<word key="notification__event_reminder" js="0">Less than %s to go until %s</word>
<word key="notification__event_reminder_title" js="0">Upcoming {!#[1:event][?:events]}</word>
<word key="menu__calendar_calendars_venues" js="0">Venues</word>
<word key="venues" js="0">Venues</word>
<word key="venue_title" js="0">Venue Name</word>
@@ -473,6 +478,13 @@
<word key="venue_upcoming_events" js="0">Upcoming Events</word>
<word key="feed_venue_id" js="0">Venue</word>
<word key="event_new_venue" js="0">Save location as a new Venue?</word>
<word key="cal_allow_anonymous" js="0">Allow anonymous posts?</word>
<word key="AchievementAction__Rsvp" js="0">Member RSVP's for an event</word>
<word key="achievement_filter_Rsvp_nth_suffix" js="0"><![CDATA[<span data-role='th'>th</span> such RSVP]]></word>
<word key="achievement_filter_Rsvp_receiver" js="0">To the user who posted the event</word>
<word key="achievement_filter_Rsvp_giver" js="0">To the user who RSVP'd</word>
<word key="AchievementAction__Rsvp_log" js="0">RSVP'd to %s</word>
<word key="AchievementAction__Rsvp_title" js="0">Event RSVP</word>
<word key="x_daily" js="1">{# [1:day][?:days]}</word>
<word key="x_weekly" js="1">{# [1:week][?:weeks]}</word>
<word key="x_monthly" js="1">{# [1:month][?:months]}</word>
+48
View File
@@ -155,6 +155,18 @@
"zerofill": false,
"auto_increment": false,
"binary": false
},
"cal_allow_anonymous": {
"name": "cal_allow_anonymous",
"type": "TINYINT",
"length": null,
"decimals": null,
"values": null,
"allow_null": false,
"default": "0",
"comment": "",
"unsigned": true,
"auto_increment": false
}
},
"indexes": {
@@ -341,6 +353,18 @@
"unsigned": false,
"values": [],
"zerofill": false
},
"comment_is_anon": {
"name": "comment_is_anon",
"type": "TINYINT",
"length": null,
"decimals": null,
"values": null,
"allow_null": false,
"default": "0",
"comment": "",
"unsigned": true,
"auto_increment": false
}
},
"indexes": {
@@ -1121,6 +1145,30 @@
"zerofill": false,
"auto_increment": false,
"binary": false
},
"event_author_name": {
"name": "event_author_name",
"type": "VARCHAR",
"length": 255,
"decimals": null,
"values": null,
"allow_null": true,
"default": null,
"comment": "",
"unsigned": false,
"auto_increment": false
},
"event_is_anon": {
"name": "event_is_anon",
"type": "INT",
"length": null,
"decimals": null,
"values": null,
"allow_null": false,
"default": "0",
"comment": "",
"unsigned": true,
"auto_increment": false
}
},
"indexes": {
+18 -23
View File
@@ -14,13 +14,9 @@
{{endforeach}}]]></template>
<template template_group="browse" template_name="birthdaysTable" template_data="$table, $headers, $rows, $quickSearch" template_location="front" template_app="calendar"><![CDATA[<div data-baseurl='{$table->baseUrl}' data-resort='{$table->resortKey}' data-controller='core.global.core.table' {{if $table->getPaginationKey() != 'page'}}data-pageParam='{$table->getPaginationKey()}'{{endif}}>
{{if $table->pages > 1}}
<div class="ipsButtonBar ipsPad_half ipsClearfix ipsClear">
<div data-role="tablePagination">
{template="pagination" group="global" app="core" location="global" params="$table->baseUrl, $table->pages, $table->page, $table->limit, TRUE, $table->getPaginationKey()"}
</div>
</div>
{{endif}}
<div class="ipsButtonBar ipsPad_half ipsClearfix ipsClear {{if $table->pages <= 1}}ipsHide{{endif}}" data-role="tablePagination">
{template="pagination" group="global" app="core" location="global" params="$table->baseUrl, $table->pages, $table->page, $table->limit, TRUE, $table->getPaginationKey()"}
</div>
{{if \count( $rows )}}
@@ -40,13 +36,9 @@
</div>
{{endif}}
{{if $table->pages > 1}}
<div class="ipsButtonBar ipsPad_half ipsClearfix ipsClear">
<div data-role="tablePagination">
{template="pagination" group="global" app="core" location="global" params="$table->baseUrl, $table->pages, $table->page, $table->limit, TRUE, $table->getPaginationKey()"}
</div>
</div>
{{endif}}
<div class="ipsButtonBar ipsPad_half ipsClearfix ipsClear {{if $table->pages <= 1}}ipsHide{{endif}}" data-role="tablePagination">
{template="pagination" group="global" app="core" location="global" params="$table->baseUrl, $table->pages, $table->page, $table->limit, TRUE, $table->getPaginationKey()"}
</div>
</div>]]></template>
<template template_group="browse" template_name="calendarDay" template_data="$calendars, $date, $featured, $birthdays, $birthdayCount, $events, $tomorrow, $yesterday, $today, $thisCalendar, $jump" template_location="front" template_app="calendar"><![CDATA[
<div class='ipsBox'>
@@ -506,7 +498,7 @@
{{endif}}
{template="calendarFeatured" group="browse" app="calendar" params="$featured, $date"}]]></template>
<template template_group="browse" template_name="dateJump" template_data="$id, $action, $elements, $hiddenValues, $actionButtons, $uploadField, $class='', $attributes=array(), $sidebar, $form=NULL" template_location="front" template_app="calendar"><![CDATA[<div id='elCalendarJump' class='ipsMenu ipsMenu_medium ipsHide'>
<template template_group="browse" template_name="dateJump" template_data="$id, $action, $elements, $hiddenValues, $actionButtons, $uploadField, $class='', $attributes=array(), $sidebar=NULL, $form=NULL" template_location="front" template_app="calendar"><![CDATA[<div id='elCalendarJump' class='ipsMenu ipsMenu_medium ipsHide'>
<form accept-charset='utf-8' class="ipsPad ipsForm ipsForm_vertical" method='post' action='{$action}' data-ipsForm>
<input type="hidden" name="{$id}_submitted" value="1">
{{foreach $hiddenValues as $k => $v}}
@@ -1941,7 +1933,7 @@
<a class="ipsButton ipsButton_light ipsButton_verySmall {$buttonClass}" data-role="reminderButton" data-reminder="false" href="{url="app=calendar&module=calendar&controller=event&id={$event->id}&do=setReminder" csrf="true"}" title="{lang="event_set_reminder_tip"}" data-ipsTooltip class="ipsType_blendLinks ipsType_noUnderline" data-ipsHover data-ipsHover-cache='false' data-ipsHover-onClick>{lang="event_set_reminder"}</a>
{{endif}}
{{endif}}]]></template>
<template template_group="view" template_name="reminderForm" template_data="$id, $action, $elements, $hiddenValues, $actionButtons, $uploadField, $class='', $attributes=array(), $sidebar, $form=NULL" template_location="front" template_app="calendar"><![CDATA[<form {{if \IPS\Request::i()->isAjax() }}data-controller='calendar.front.view.reminderForm'{{endif}} accept-charset='utf-8' class="ipsForm {$class}" action="{$action}" method="post" {{if $uploadField}}enctype="multipart/form-data"{{endif}} {{foreach $attributes as $k => $v}}{$k}="{$v}"{{endforeach}} data-ipsForm >
<template template_group="view" template_name="reminderForm" template_data="$id, $action, $elements, $hiddenValues, $actionButtons, $uploadField, $class='', $attributes=array(), $sidebar=NULL, $form=NULL" template_location="front" template_app="calendar"><![CDATA[<form {{if \IPS\Request::i()->isAjax() }}data-controller='calendar.front.view.reminderForm'{{endif}} accept-charset='utf-8' class="ipsForm {$class}" action="{$action}" method="post" {{if $uploadField}}enctype="multipart/form-data"{{endif}} {{foreach $attributes as $k => $v}}{$k}="{$v}"{{endforeach}} data-ipsForm >
<input type="hidden" name="{$id}_submitted" value="1">
{{foreach $hiddenValues as $k => $v}}
<input type="hidden" name="{$k}" value="{$v}">
@@ -2114,7 +2106,10 @@
{template="userPhoto" app="core" group="global" params="$event->author(), 'tiny'"}
<div>
<p class="ipsType_reset ipsType_normal ipsType_blendLinks">
{lang="event_created_by" htmlsprintf="$event->author()->link( $event->warningRef() )"}
{lang="event_created_by" htmlsprintf="$event->author()->link( $event->warningRef(), NULL, $event->isAnonymous() )"}
{{if $event->isAnonymous() and \IPS\Member::loggedIn()->modPermission('can_view_anonymous_posters')}}
<a data-ipsHover data-ipsHover-width="370" data-ipsHover-onClick href="{$event->url( 'reveal' )->csrf()}"><span class="cAuthorPane_badge cAuthorPane_badge_small cAuthorPane_badge--anon" data-ipsTooltip title="{lang="post_anonymously_reveal"}"></span></a>
{{endif}}
</p>
{{if $event->container()->allow_reviews}}
<div>
@@ -2202,7 +2197,7 @@
<ul id='elEventActions_menu' class='ipsMenu ipsMenu_auto ipsHide'>
{{if $event->canReportOrRevoke() === TRUE}}
<li class='ipsMenu_item'>
<a href='{$event->url('report')}' data-ipsDialog data-ipsDialog-size='medium' data-ipsDialog-title="{lang="report_event"}" data-ipsDialog-remoteSubmit data-ipsDialog-flashMessage="{lang="report_submit_success"}" title="{lang="report_event"}">{lang="report_event"}</a>
<a href='{$event->url('report')}' {{if member.member_id or \IPS\Helpers\Form\Captcha::supportsModal()}}data-ipsDialog data-ipsDialog-size='medium' data-ipsDialog-title="{lang="report_event"}" data-ipsDialog-remoteSubmit data-ipsDialog-flashMessage="{lang="report_submit_success"}"{{endif}} title="{lang="report_event"}">{lang="report_event"}</a>
</li>
<li class='ipsMenu_sep'><hr></li>
{{endif}}
@@ -2221,7 +2216,7 @@
<li class='ipsMenu_item'><a href='{$event->url()->csrf()->setQueryString( array( 'do' => 'moderate', 'action' => 'unfeature' ) )}' title='{lang="unfeature_title_event"}'>{lang="unfeature"}</a></li>
{{endif}}
{{if $event->canHide()}}
<li class='ipsMenu_item'><a href='{$event->url()->csrf()->setQueryString( array( 'do' => 'moderate', 'action' => 'hide' ) )}' title='{lang="hide_title_event"}' data-ipsDialog data-ipsDialog-title="{lang="hide"}">{lang="hide"}</a></li>
<li class='ipsMenu_item'><a href='{$event->url()->setQueryString( array( 'do' => 'moderate', 'action' => 'hide' ) )}' title='{lang="hide_title_event"}' data-ipsDialog data-ipsDialog-title="{lang="hide"}">{lang="hide"}</a></li>
{{endif}}
{{if $event->canUnhide()}}
<li class='ipsMenu_item'><a href='{$event->url()->csrf()->setQueryString( array( 'do' => 'moderate', 'action' => 'unhide' ) )}' title='{{if $event->hidden() === 1}}{lang="approve_title_event"}{{else}}{lang="unhide_title_event"}{{endif}}'>{{if $event->hidden() === 1}}{lang="approve"}{{else}}{lang="unhide"}{{endif}}</a></li>
@@ -2233,24 +2228,24 @@
<li class='ipsMenu_item'><a href='{$event->url()->csrf()->setQueryString( array( 'do' => 'moderate', 'action' => 'unlock' ) )}' title='{lang="unlock_title_event"}'>{lang="unlock"}</a></li>
{{endif}}
{{if $event->canMove()}}
<li class='ipsMenu_item'><a href='{$event->url()->csrf()->setQueryString( array( 'do' => 'move' ) )}' data-ipsDialog data-ipsDialog-size='narrow' data-ipsDialog-title="{lang="move"}" title='{lang="event_move_title"}'>{lang="move"}</a></li>
<li class='ipsMenu_item'><a href='{$event->url()->setQueryString( array( 'do' => 'move' ) )}' data-ipsDialog data-ipsDialog-size='narrow' data-ipsDialog-title="{lang="move"}" title='{lang="event_move_title"}'>{lang="move"}</a></li>
{{endif}}
{{if $event->canDelete()}}
<li class='ipsMenu_item'><a href='{$event->url()->csrf()->setQueryString( array( 'do' => 'moderate', 'action' => 'delete' ) )}' data-confirm title='{lang="calendar_delete_title"}'>{lang="delete"}</a></li>
{{endif}}
{{if $event->canOnMessage( 'add' )}}
<li class='ipsMenu_item'><a href='{$event->url()->csrf()->setQueryString( array( 'do' => 'messageForm' ) )}' data-ipsDialog data-ipsDialog-title='{lang="add_message"}'>{lang="add_message"}</a></li>
<li class='ipsMenu_item'><a href='{$event->url()->setQueryString( array( 'do' => 'messageForm' ) )}' data-ipsDialog data-ipsDialog-title='{lang="add_message"}'>{lang="add_message"}</a></li>
{{endif}}
{{if \IPS\Member::loggedIn()->modPermission('can_view_moderation_log')}}
<li class='ipsMenu_sep'><hr></li>
<li class="ipsMenu_item"><a href='{$event->url()->csrf()->setQueryString( array( 'do' => 'modLog' ) )}' data-ipsDialog data-ipsDialog-title='{lang="moderation_history"}'>{lang="moderation_history"}</a></li>
<li class="ipsMenu_item"><a href='{$event->url()->setQueryString( array( 'do' => 'modLog' ) )}' data-ipsDialog data-ipsDialog-title='{lang="moderation_history"}'>{lang="moderation_history"}</a></li>
{{endif}}
{{endif}}
</ul>
</li>
{{elseif $event->canReportOrRevoke() === TRUE}}
<li>
<a href='{$event->url('report')}' class='ipsButton ipsButton_link ipsButton_verySmall ipsButton_fullWidth' data-ipsDialog data-ipsDialog-size='medium' data-ipsDialog-title="{lang="report_event"}" data-ipsDialog-remoteSubmit data-ipsDialog-flashMessage="{lang="report_submit_success"}" title="{lang="report_event"}">{lang="report_event"}</a>
<a href='{$event->url('report')}' class='ipsButton ipsButton_link ipsButton_verySmall ipsButton_fullWidth' {{if member.member_id or \IPS\Helpers\Form\Captcha::supportsModal()}}data-ipsDialog data-ipsDialog-size='medium' data-ipsDialog-title="{lang="report_event"}" data-ipsDialog-remoteSubmit data-ipsDialog-flashMessage="{lang="report_submit_success"}"{{endif}} title="{lang="report_event"}">{lang="report_event"}</a>
</li>
{{endif}}
+39 -1
View File
@@ -327,6 +327,7 @@
"104067": "4.4.10",
"104068": "4.4.10",
"104069": "4.4.10",
"104070": "4.4.11",
"105013": "4.5.0 Beta 1",
"105014": "4.5.0 Beta 1",
"105015": "4.5.0 Beta 2",
@@ -347,5 +348,42 @@
"105030": "4.5.0 Beta 11",
"105031": "4.5.0 Beta 11",
"105032": "4.5.0 Beta 12",
"105100": "4.5.0"
"105100": "4.5.0",
"105101": "4.5.0",
"105102": "4.5.1 Beta 1",
"105103": "4.5.1 Beta 1",
"105104": "4.5.1 Beta 2",
"105105": "4.5.1 Beta 3",
"105106": "4.5.1",
"105107": "4.5.2",
"105108": "4.5.2",
"105109": "4.5.2",
"105110": "4.5.2",
"105111": "4.5.2",
"105112": "4.5.3",
"105113": "4.5.3",
"105114": "4.5.3",
"105115": "4.5.3",
"105116": "4.5.4",
"105117": "4.5.4",
"105118": "4.5.4",
"105119": "4.5.4",
"105120": "4.5.4",
"105121": "4.5.4",
"105122": "4.5.4",
"105123": "4.5.4",
"105124": "4.5.4.1",
"105125": "4.5.4.2",
"105126": "4.5.4.2",
"105127": "4.5.4.2",
"105128": "4.5.4.2",
"105129": "4.5.4.2",
"105130": "4.5.4.2",
"106100": "4.6.0 Beta 1",
"106101": "4.6.0 Beta 1.1",
"106103": "4.6.0 Beta 2",
"106104": "4.6.0 Beta 3",
"106105": "4.6.0 Beta 3.1",
"106106": "4.6.0 Beta 4",
"106107": "4.6.0"
}
@@ -0,0 +1,315 @@
<?php
/**
* @brief Achievement Action Extension
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @subpackage Calendar
* @since 17 Mar 2021
*/
namespace IPS\calendar\extensions\core\AchievementAction;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Achievement Action Extension
*/
class _Rsvp extends \IPS\core\Achievements\Actions\AbstractAchievementAction // NOTE: Other classes exist to provided bases for common situations, like where node-based filters will be required
{
/**
* Get filter form elements
*
* @param array|NULL $filters Current filter values (if editing)
* @param \IPS\Http\Url $url The URL the form is being shown on
* @return array
*/
public function filters( ?array $filters, \IPS\Http\Url $url ): array
{
$return = array();
$return['nodes'] = new \IPS\Helpers\Form\Node( 'achievement_filter_Rsvp_nodes', ( $filters and isset( $filters['nodes'] ) and $filters['nodes'] ) ? $filters['nodes'] : 0, FALSE, [
'url' => $url,
'class' => 'IPS\calendar\Calendar',
'showAllNodes' => TRUE,
'multiple' => TRUE,
], NULL, \IPS\Member::loggedIn()->language()->addToStack( 'achievement_filter_NewContentItem_node_prefix', FALSE, [ 'sprintf' => [
\IPS\Member::loggedIn()->language()->addToStack( 'rsvp', FALSE ),
\IPS\Member::loggedIn()->language()->addToStack( 'calendars_sg', FALSE, [ 'strtolower' => TRUE ] )
] ] ) );
$return['nodes']->label = \IPS\Member::loggedIn()->language()->addToStack( 'achievement_filter_NewContentItem_node', FALSE, [ 'sprintf' => [ \IPS\Member::loggedIn()->language()->addToStack( 'calendars_sg', FALSE, [ 'strtolower' => TRUE ] ) ] ] );
$return['milestone'] = new \IPS\Helpers\Form\Number( 'achievement_filter_Rsvp_nth', ( $filters and isset( $filters['milestone'] ) and $filters['milestone'] ) ? $filters['milestone'] : 0, FALSE, [], NULL, \IPS\Member::loggedIn()->language()->addToStack('achievement_filter_nth_their'), \IPS\Member::loggedIn()->language()->addToStack('achievement_filter_Rsvp_nth_suffix') );
$return['milestone']->label = \IPS\Member::loggedIn()->language()->addToStack('achievement_filter_NewContentItem_nth');
return $return;
}
/**
* Format filter form values
*
* @param array $values The values from the form
* @return array
*/
public function formatFilterValues( array $values ): array
{
$return = [];
if ( isset( $values['achievement_filter_Rsvp_nodes'] ) )
{
$return['nodes'] = array_keys( $values['achievement_filter_Rsvp_nodes'] );
}
if ( isset( $values['achievement_filter_Rsvp_nth'] ) )
{
$return['milestone'] = $values['achievement_filter_Rsvp_nth'];
}
return $return;
}
/**
* Work out if the filters applies for a given action
*
* Important note for milestones: consider the context. This method is called by \IPS\Member::achievementAction(). If your code
* calls that BEFORE making its change in the database (or there is read/write separation), you will need to add
* 1 to the value being considered for milestones
*
* @param \IPS\Member $subject The subject member
* @param array $filters The value returned by formatFilterValues()
* @param mixed $extra Any additional information about what is happening (e.g. if a post is being made: the post object)
* @return bool
*/
public function filtersMatch( \IPS\Member $subject, array $filters, $extra = NULL ): bool
{
if ( isset( $filters['nodes'] ) )
{
if ( !\in_array( $extra->container()->_id, $filters['nodes'] ) )
{
return FALSE;
}
}
if ( isset( $filters['milestone'] ) )
{
$query = $this->getQuery( 'COUNT(*)', [ [ 'rsvp_member_id=?', $subject->member_id ] ], NULL, NULL, $filters );
if ( $query->first() < $filters['milestone'] )
{
return FALSE;
}
}
return TRUE;
}
/**
* Get the labels for the people this action might give awards to
*
* @return array
*/
public function awardOptions(): array
{
return [
'subject' => 'achievement_filter_Rsvp_receiver',
'other' => 'achievement_filter_Rsvp_giver'
];
}
/**
* Get the "other" people we need to award =stuff to
*
* @param mixed $extra Any additional information about what is happening (e.g. if a post is being made: the post object)
* @return array
*/
public function awardOther( $extra = NULL ): array
{
return [ $extra->author() ];
}
/**
* Get identifier to prevent the member being awarded points for the same action twice
* Must be unique within within of this domain, must not exceed 32 chars.
*
* @param \IPS\Member $subject The subject member
* @param mixed $extra Any additional information about what is happening (e.g. if a post is being made: the post object)
* @return string
*/
public function identifier( \IPS\Member $subject, $extra = NULL ): string
{
return 'Rsvp:' . $extra->id . ':' . $subject->member_id;
}
/**
* Return a description for this action to show in the log
*
* @param string $identifier The identifier as returned by identifier()
* @param array $actor If the member was the "subject", "other", or both
* @return string
*/
public function logRow( string $identifier, array $actor ): string
{
$exploded = explode( ':', $identifier );
$sprintf = [];
try
{
$item = \IPS\calendar\Event::load( $exploded[1] );
$sprintf = [ 'htmlsprintf' => [
\IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $item->url(), TRUE, $item->mapped('title') ?: $item->indefiniteArticle(), FALSE )
] ];
}
catch ( \OutOfRangeException $e )
{
$sprintf = [ 'sprintf' => [ \IPS\Member::loggedIn()->language()->addToStack('modcp_deleted') ] ];
}
return \IPS\Member::loggedIn()->language()->addToStack( 'AchievementAction__Rsvp_log', FALSE, $sprintf );
}
/**
* Get "description" for rule
*
* @param \IPS\core\Achievements\Rule $rule The rule
* @return string|NULL
*/
public function ruleDescription( \IPS\core\Achievements\Rule $rule ): ?string
{
$conditions = [];
if ( isset( $rule->filters['milestone'] ) )
{
$conditions[] = \IPS\Member::loggedIn()->language()->addToStack( 'achievements_title_filter_milestone', FALSE, [
'htmlsprintf' => [
\IPS\Theme::i()->getTemplate( 'achievements' )->ruleDescriptionBadge( 'milestone', \IPS\Member::loggedIn()->language()->addToStack( 'achievements_title_filter_milestone_nth', FALSE, [ 'pluralize' => [ $rule->filters['milestone'] ] ] ) )
],
'sprintf' => [ \IPS\Member::loggedIn()->language()->addToStack('rsvp') ]
] );
}
if ( $nodeCondition = $this->_nodeFilterDescription( $rule ) )
{
$conditions[] = $nodeCondition;
}
return \IPS\Theme::i()->getTemplate( 'achievements' )->ruleDescription(
\IPS\Member::loggedIn()->language()->addToStack( 'AchievementAction__Rsvp_title' ),
$conditions
);
}
/**
* Get "description" for rule (usually a description of the rule's filters)
*
* @param \IPS\core\Achievements\Rule $rule The rule
* @return string|NULL
*/
protected function _nodeFilterDescription( \IPS\core\Achievements\Rule $rule ): ?string
{
if ( isset( $rule->filters['nodes'] ) )
{
$nodeNames = [];
foreach ( $rule->filters['nodes'] as $id )
{
try
{
$nodeNames[] = \IPS\calendar\Calendar::load( $id )->_title;
}
catch ( \OutOfRangeException $e ) {}
}
if ( $nodeNames )
{
return \IPS\Member::loggedIn()->language()->addToStack( 'achievements_title_filter_location', FALSE, [
'htmlsprintf' => [
\IPS\Theme::i()->getTemplate( 'achievements' )->ruleDescriptionBadge( 'location',
\count( $nodeNames ) === 1 ? $nodeNames[0] : \IPS\Member::loggedIn()->language()->addToStack( 'achievements_title_filter_location_val', FALSE, [ 'sprintf' => [
\count( $nodeNames ),
\IPS\Member::loggedIn()->language()->addToStack( 'calendars', FALSE, [ 'strtolower' => TRUE ] )
] ] ),
\count( $nodeNames ) === 1 ? NULL : $nodeNames
)
],
] );
}
}
return NULL;
}
/**
* Rebuild points and badges based on the content this rule manages
*
* @param array $data The rebuild data
* @param array $filters The value returned by formatFilterValues()
* @param int $lastId The last ID returned by a previous iteration
* @param int $limit The limit of how many to rebuild
* @param \IPS\DataTime|null $time Any time limit to add
* @return array
*/
public function processRebuild( $data, $filters, $lastId, $limit, \IPS\DateTime $time = NULL ): array
{
$where = ( $time ? [ ['rsvp_id > ? and rsvp_date >= ?', $lastId, $time->getTimestamp() ] ] : [ [ 'rsvp_id > ?', $lastId ] ] );
/* Try and limit the number of rows for the good of humanity */
$query = $this->getQuery( '*', $where, $limit, 'rsvp_id ASC', $filters );
$done = 0;
foreach( $query as $row )
{
try
{
\IPS\Member::load( $row['rsvp_member_id'] )->achievementAction( 'calendar', 'Rsvp', [ \IPS\calendar\Event::load( $row['rsvp_event_id'] ) ] );
}
catch( \Exception $e ){}
$done++;
$lastId = $row['rsvp_id'];
}
return [ 'processed' => $done, 'lastId' => $lastId ];
}
/**
* Get rebuild data
*
* @param array $data Data stored with the queue item
* @param array $filters The value returned by formatFilterValues()
* @param \IPS\DataTime|null $time Any time limit to add
* @return void
*/
public function preRebuildData( &$data, $filters, \IPS\DateTime $time = NULL )
{
$data['count'] = $this->getQuery( 'COUNT(*)', ( $time ? [ ['rsvp_date >= ?', $time->getTimestamp() ] ] : [] ), NULL, NULL, $filters )->first();
}
/**
* Get a query to use for multiple methods within this extension
* @param string $select Select for the query
* @param array|NULL $where Where for the query
* @param int|NULL $limit Limit for the query
* @param string|NULL $order Order by for the query
* @param array $filters Rule filters
* @return \IPS\Db\Select
*/
public function getQuery( $select, $where, $limit, $order, $filters ): \IPS\Db\Select
{
$joinContainers = FALSE;
$extraJoinCondition = NULL;
$where = \is_array( $where ) ? $where : array();
/* Limit by node */
if ( isset( $filters['nodes'] ) )
{
$joinContainers = TRUE;
$extraJoinCondition = ' AND ' . \IPS\Db::i()->in( 'calendar_events.event_calendar_id', $filters['nodes'] );
}
$query = \IPS\Db::i()->select( $select, 'calendar_event_rsvp', $where, $order, $limit );
if ( $joinContainers )
{
$query->join( 'calendar_events', 'calendar_event_rsvp.rsvp_event_id=calendar_events.event_id' . $extraJoinCondition, 'INNER' );
}
return $query;
}
}
@@ -67,11 +67,13 @@ class _Events
{
throw new \OutOfRangeException;
}
$name = ( $item->isAnonymous() ) ? \IPS\Member::loggedIn()->language()->addToStack( 'post_anonymously_placename' ) : $item->author()->name;
return array(
'title' => \IPS\Member::loggedIn()->language()->addToStack( 'notification__new_content', FALSE, array(
( $htmlEscape ? 'sprintf' : 'htmlsprintf' ) => array(
$item->author()->name,
$name,
mb_strtolower( $item->indefiniteArticle() ),
$item->container()->getTitleForLanguage( \IPS\Member::loggedIn()->language(), $htmlEscape ? array( 'escape' => TRUE ) : array() ),
$item->mapped('title')
@@ -130,6 +132,9 @@ class _Events
public static function parse_mobile_event_reminder( \IPS\Lang $language, \IPS\calendar\Event $event, $daysToGo )
{
return array(
'title' => $language->addToStack( 'notification__event_reminder_title', FALSE, array(
'pluralize' => array(1)
) ),
'body' => $language->addToStack( 'notification__event_reminder', FALSE, array( 'htmlsprintf' => array(
$language->addToStack( "days_to_go", FALSE, array( 'pluralize' => array(
$daysToGo
@@ -138,7 +143,7 @@ class _Events
) ) ),
'data' => array(
'url' => (string) $event->url(),
'author' => $event->author()
'author' => $event->author(),
),
'channelId' => 'events',
);
@@ -341,7 +341,7 @@ class _ical extends \IPS\Dispatcher\Controller
/* Insert the new record */
$feed->title = $values['feed_title'];
$feed->url = $values['feed_url'];
$feed->calendar_id = $values['feed_calendar_id'];
$feed->calendar_id = $values['feed_calendar_id']->_id;
if( \IPS\Settings::i()->calendar_venues_enabled )
{
@@ -349,6 +349,8 @@ class _event extends \IPS\Content\Controller
) );
$message = 'rsvp_selection_' . \IPS\Request::i()->action;
\IPS\Member::loggedIn()->achievementAction( 'calendar', 'Rsvp', $this->event );
}
\IPS\Output::i()->redirect( $this->event->url(), $message );
@@ -149,10 +149,10 @@ class _submit extends \IPS\Dispatcher\Controller
{
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=calendar&module=calendar&controller=submit', 'front', 'calendar_submit' ) );
}
$form = new \IPS\Helpers\Form( 'form', \IPS\Member::loggedIn()->language()->checkKeyExists( \IPS\Calendar\Event::$formLangPrefix . '_save' ) ? \IPS\Calendar\Event::$formLangPrefix . '_save' : 'save' );
$form->class = 'ipsForm_vertical';
$formElements = \IPS\Calendar\Event::formElements( $existing, $existing->container() );
$formElements = \IPS\Calendar\Event::formElements( $existing, $existing->container(), TRUE );
foreach ( $formElements as $key => $object )
{
if ( \is_object( $object ) )
@@ -183,6 +183,7 @@ class _submit extends \IPS\Dispatcher\Controller
/* Set cover photo offset from original if we're using the same photo */
if( $existing->cover_photo == $obj->cover_photo )
{
$obj->cover_photo = \IPS\File::get( 'calendar_Events', $existing->cover_photo )->duplicate();
$obj->cover_offset = $existing->cover_offset;
$obj->save();
}
@@ -345,13 +345,23 @@ class _view extends \IPS\Dispatcher\Controller
{
$dayEvents['count']++;
if( $_event->all_day )
if( $_event->all_day AND (
$_event->nextOccurrence( $date, 'startDate' )->strFormat('%d') == \IPS\Request::i()->d OR
$_event->nextOccurrence( $date, 'endDate' ) AND $_event->nextOccurrence( $date, 'endDate' )->strFormat('%d') == \IPS\Request::i()->d
) )
{
$dayEvents['allDay'][ $_event->id ] = $_event;
}
else
{
$dayEvents[ $_event->_start_date->hours ][ $_event->id ] = $_event;
if( $_event->nextOccurrence( $date, 'startDate' )->strFormat('%d') == \IPS\Request::i()->d )
{
$dayEvents[ $_event->_start_date->hours ][ $_event->id ] = $_event;
}
elseif( $_event->nextOccurrence( $date, 'endDate' ) AND $_event->nextOccurrence( $date, 'endDate' )->strFormat('%d') == \IPS\Request::i()->d )
{
$dayEvents[ 0 ][ $_event->id ] = $_event;
}
}
}
}
@@ -46,7 +46,14 @@ class _Upgrade
$did++;
$recurrenceRule = \IPS\calendar\Icalendar\ICSParser::parseRrule( $event['event_recurring'], 'UTC' );
try
{
$recurrenceRule = \IPS\calendar\Icalendar\ICSParser::parseRrule( $event['event_recurring'], 'UTC' );
}
catch( \InvalidArgumentException $e )
{
continue;
}
$endDate = NULL;
@@ -0,0 +1,24 @@
{
"id": 105101,
"name": "4.5.0",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"whatsnew": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,24 @@
{
"id": 105102,
"name": "4.5.1 Beta 1",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"whatsnew": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,24 @@
{
"id": 105103,
"name": "4.5.1 Beta 1",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"whatsnew": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,24 @@
{
"id": 105104,
"name": "4.5.1 Beta 2",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"whatsnew": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,24 @@
{
"id": 105105,
"name": "4.5.1 Beta 3",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"whatsnew": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,24 @@
{
"id": 105106,
"name": "4.5.1",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"whatsnew": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,24 @@
{
"id": 105107,
"name": "4.5.2",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"whatsnew": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,24 @@
{
"id": 105108,
"name": "4.5.2",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"whatsnew": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,24 @@
{
"id": 105109,
"name": "4.5.2",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"whatsnew": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,24 @@
{
"id": 105110,
"name": "4.5.2",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"whatsnew": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,24 @@
{
"id": 105111,
"name": "4.5.2",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"whatsnew": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,24 @@
{
"id": 105112,
"name": "4.5.3",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"whatsnew": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,24 @@
{
"id": 105113,
"name": "4.5.3",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"whatsnew": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,24 @@
{
"id": 105114,
"name": "4.5.3",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"whatsnew": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,24 @@
{
"id": 105115,
"name": "4.5.3",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"whatsnew": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,24 @@
{
"id": 105116,
"name": "4.5.4",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"whatsnew": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,24 @@
{
"id": 105117,
"name": "4.5.4",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"whatsnew": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,24 @@
{
"id": 105118,
"name": "4.5.4",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"whatsnew": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,24 @@
{
"id": 105119,
"name": "4.5.4",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"whatsnew": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,24 @@
{
"id": 105120,
"name": "4.5.4",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"whatsnew": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,24 @@
{
"id": 105121,
"name": "4.5.4",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"whatsnew": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,24 @@
{
"id": 105122,
"name": "4.5.4",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"whatsnew": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,24 @@
{
"id": 105123,
"name": "4.5.4",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"whatsnew": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,24 @@
{
"id": 105124,
"name": "4.5.4.1",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"whatsnew": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,24 @@
{
"id": 105125,
"name": "4.5.4.2",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"whatsnew": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,24 @@
{
"id": 105126,
"name": "4.5.4.2",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"whatsnew": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,24 @@
{
"id": 105127,
"name": "4.5.4.2",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"whatsnew": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,24 @@
{
"id": 105128,
"name": "4.5.4.2",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"whatsnew": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,24 @@
{
"id": 105129,
"name": "4.5.4.2",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"whatsnew": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,24 @@
{
"id": 105130,
"name": "4.5.4.2",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"whatsnew": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,24 @@
{
"id": 106100,
"name": "4.6.0 Beta 1",
"steps": {
"queries": true,
"lang": true,
"theme": true,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"whatsnew": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,24 @@
{
"normal": {
"added": [
"__defart_calendar_event_comment_plural",
"__defart_calendar_event_plural",
"__defart_calendar_event_review_plural",
"notification__event_reminder_title",
"cal_allow_anonymous",
"AchievementAction__Rsvp",
"achievement_filter_Rsvp_nth_suffix",
"achievement_filter_Rsvp_receiver",
"achievement_filter_Rsvp_giver",
"AchievementAction__Rsvp_log",
"AchievementAction__Rsvp_title"
],
"edited": [],
"removed": []
},
"js": {
"added": [],
"edited": [],
"removed": []
}
}
@@ -0,0 +1,74 @@
{
"1": {
"method": "addColumn",
"params": [
"calendar_calendars",
{
"name": "cal_allow_anonymous",
"type": "TINYINT",
"length": null,
"decimals": null,
"values": null,
"allow_null": false,
"default": "0",
"comment": "",
"unsigned": true,
"auto_increment": false
}
]
},
"2": {
"method": "addColumn",
"params": [
"calendar_events",
{
"name": "event_author_name",
"type": "VARCHAR",
"length": 255,
"decimals": null,
"values": null,
"allow_null": true,
"default": null,
"comment": "",
"unsigned": false,
"auto_increment": false
}
]
},
"3": {
"method": "addColumn",
"params": [
"calendar_events",
{
"name": "event_is_anon",
"type": "INT",
"length": null,
"decimals": null,
"values": null,
"allow_null": false,
"default": "0",
"comment": "",
"unsigned": true,
"auto_increment": false
}
]
},
"4": {
"method": "addColumn",
"params": [
"calendar_event_comments",
{
"name": "comment_is_anon",
"type": "TINYINT",
"length": null,
"decimals": null,
"values": null,
"allow_null": false,
"default": "0",
"comment": "",
"unsigned": true,
"auto_increment": false
}
]
}
}
@@ -0,0 +1,22 @@
{
"html": {
"added": [],
"edited": [
"front\/browse\/birthdaysTable",
"front\/browse\/dateJump",
"front\/view\/reminderForm",
"front\/view\/view"
],
"removed": []
},
"css": {
"added": [],
"edited": [],
"removed": []
},
"resources": {
"added": [],
"edited": [],
"removed": []
}
}
@@ -0,0 +1,24 @@
{
"id": 106101,
"name": "4.6.0 Beta 1.1",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"whatsnew": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,9 @@
{
"added": [],
"edited": [
"app=calendar&module=calendars&controller=calendars"
],
"removed": [
"app=calendar&module=calendars&controller=calendars&do=form"
]
}
@@ -0,0 +1,24 @@
{
"id": 106103,
"name": "4.6.0 Beta 2",
"steps": {
"queries": false,
"lang": true,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": true,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"whatsnew": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,14 @@
{
"normal": {
"added": [
"calendars_sg_lc"
],
"edited": [],
"removed": []
},
"js": {
"added": [],
"edited": [],
"removed": []
}
}
@@ -0,0 +1,24 @@
{
"id": 106104,
"name": "4.6.0 Beta 3",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"whatsnew": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,24 @@
{
"id": 106105,
"name": "4.6.0 Beta 3.1",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"whatsnew": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,24 @@
{
"id": 106106,
"name": "4.6.0 Beta 4",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"whatsnew": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,24 @@
{
"id": 106107,
"name": "4.6.0",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"whatsnew": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -168,6 +168,7 @@ class _Calendar extends \IPS\Node\Model implements \IPS\Node\Permissions
$form->add( new \IPS\Helpers\Form\YesNo( 'cal_comment_moderate', $this->id ? $this->comment_moderate : FALSE, FALSE, array(), NULL, NULL, NULL, 'cal_comment_moderate' ) );
$form->add( new \IPS\Helpers\Form\YesNo( 'cal_allow_reviews', $this->id ? $this->allow_reviews : FALSE, FALSE, array( 'togglesOn' => array( 'cal_review_moderate' ) ) ) );
$form->add( new \IPS\Helpers\Form\YesNo( 'cal_review_moderate', $this->id ? $this->review_moderate : FALSE, FALSE, array(), NULL, NULL, NULL, 'cal_review_moderate' ) );
$form->add( new \IPS\Helpers\Form\YesNo( 'cal_allow_anonymous', $this->id ? $this->allow_anonymous : FALSE, FALSE, array(), NULL, NULL, NULL, 'cal_allow_anonymous' ) );
if ( \IPS\Settings::i()->tags_enabled )
{
+29 -4
View File
@@ -99,8 +99,33 @@ class _Date extends \IPS\DateTime
if ( $offset === NULL and \IPS\Member::loggedIn()->timezone )
{
$timezone = \IPS\DateTime::create();
$timezone->setTimezone( new \DateTimeZone( \IPS\Member::loggedIn()->timezone ) );
$timezone = \IPS\DateTime::create();
$validTimezone = TRUE;
if( \in_array( \IPS\Member::loggedIn()->timezone, static::getTimezoneIdentifiers() ) )
{
try
{
$timezone->setTimezone( new \DateTimeZone( \IPS\Member::loggedIn()->timezone ) );
}
catch ( \Exception $e )
{
$validTimezone = FALSE;
}
}
else
{
$validTimezone = FALSE;
}
if( ! $validTimezone )
{
\IPS\Member::loggedIn()->timezone = null;
if ( \IPS\Member::loggedIn()->member_id )
{
\IPS\Member::loggedIn()->save();
}
}
$offset = $timezone->getOffset();
}
@@ -552,11 +577,11 @@ class _Date extends \IPS\DateTime
{
if( $includeTime )
{
return date( 'Y-m-d H:i:s', isset( $this->dateInformation[0] ) ? $this->dateInformation[0] : $this->getTimestamp() );
return $this->dateInformation['year'] . '-' . str_pad( $this->dateInformation['mon'], 2, 0, STR_PAD_LEFT ) . '-' . str_pad( $this->dateInformation['mday'], 2, 0, STR_PAD_LEFT ) . ' ' . str_pad( $this->dateInformation['hours'], 2, 0, STR_PAD_LEFT ) . ':' . str_pad( $this->dateInformation['minutes'], 2, 0, STR_PAD_LEFT ) . ':' . str_pad( $this->dateInformation['seconds'], 2, 0, STR_PAD_LEFT );
}
else
{
return date( 'Y-m-d', isset( $this->dateInformation[0] ) ? $this->dateInformation[0] : $this->getTimestamp() );
return $this->dateInformation['year'] . '-' . str_pad( $this->dateInformation['mon'], 2, 0, STR_PAD_LEFT ) . '-' . str_pad( $this->dateInformation['mday'], 2, 0, STR_PAD_LEFT );
}
}
@@ -21,7 +21,7 @@ if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
/**
* Event Comment Model
*/
class _Comment extends \IPS\Content\Comment implements \IPS\Content\EditHistory, \IPS\Content\Hideable, \IPS\Content\Searchable, \IPS\Content\Embeddable
class _Comment extends \IPS\Content\Comment implements \IPS\Content\EditHistory, \IPS\Content\Hideable, \IPS\Content\Searchable, \IPS\Content\Embeddable, \IPS\Content\Anonymous
{
use \IPS\Content\Reactable, \IPS\Content\Reportable;
@@ -58,7 +58,8 @@ class _Comment extends \IPS\Content\Comment implements \IPS\Content\EditHistory,
'edit_time' => 'edit_time',
'edit_member_name' => 'edit_name',
'edit_show' => 'append_edit',
'approved' => 'approved'
'approved' => 'approved',
'is_anon' => 'is_anon'
);
/**
@@ -114,7 +115,7 @@ class _Comment extends \IPS\Content\Comment implements \IPS\Content\EditHistory,
* @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;
+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;
@@ -121,7 +121,7 @@ class _Review extends \IPS\Content\Review implements \IPS\Content\EditHistory, \
* @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 )
{
return \IPS\calendar\Event\Comment::searchResultSnippet( $indexData, $authorData, $itemData, $containerData, $reputationData, $reviewRating, $view );
}
@@ -483,6 +483,7 @@ class _ICSParser
/* Time */
$newEvent->saved = ( isset( $event['created'] ) AND $event['created'] AND $event['created'] < time() ) ? $event['created'] : time();
$newEvent->lastupdated = ( isset( $event['created'] ) AND $event['created'] AND $event['created'] < time() ) ? $event['created'] : time();
}
}
@@ -492,16 +493,6 @@ class _ICSParser
$newEvent->content = \IPS\Text\Parser::parseStatic( $content, TRUE, NULL, $this->member );
$newEvent->sequence = ( isset( $event['sequence'] ) ? \intval( $event['sequence'] ) : 0 );
/* Times and dates */
if( isset( $event['last_modified'] ) AND $event['last_modified'] AND $event['last_modified'] < time() )
{
$newEvent->lastupdated = $event['last_modified'];
}
elseif( !$eventId )
{
$newEvent->lastupdated = ( isset( $event['created'] ) AND $event['created'] AND $event['created'] < time() ) ? $event['created'] : time();
}
$newEvent->all_day = $event_all_day;
$newEvent->recurring = ( isset( $event['recurr'] ) ) ? $event['recurr'] : NULL;
$newEvent->start_date = $event_unix_from->setTimezone( new \DateTimeZone( 'UTC' ) )->format( 'Y-m-d H:i:s' );
@@ -1381,7 +1372,7 @@ class _ICSParser
protected function _convertToGmt( $data )
{
/* Fix events */
if ( \is_array( $data['events'] ) AND \count( $data['events'] ) )
if ( isset( $data['events'] ) AND \is_array( $data['events'] ) AND \count( $data['events'] ) )
{
foreach( $data['events'] as $id => $event )
{
@@ -150,7 +150,7 @@ class _upcomingEvents extends \IPS\Widget\PermissionCache
}
}
$events = \IPS\calendar\Event::retrieveEvents( $_today, $endDate, ( $calendars === NULL ? NULL : !\is_array( $calendars ) ? array( $calendars ) : $calendars ), $count, FALSE );
$events = \IPS\calendar\Event::retrieveEvents( $_today, $endDate, ( $calendars === NULL ? NULL : ( !\is_array( $calendars ) ? array( $calendars ) : $calendars ) ), $count, FALSE );
/* Auto hiding? */
if( !\count($events) AND isset( $this->configuration['auto_hide'] ) AND $this->configuration['auto_hide'] )