Version 4.0.13.1
This commit is contained in:
1 parent
f9e857d255
commit
c6a86f0d9b
7517 files changed
+597400
-668041
No files matched your search
@@ -0,0 +1,147 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Calendar Application Class
|
||||
* @author <a href=''>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2013 Invision Power Services, Inc.
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Calendar
|
||||
* @since 18 Dec 2013
|
||||
* @version
|
||||
*/
|
||||
|
||||
namespace IPS\calendar;
|
||||
|
||||
/**
|
||||
* Core Application Class
|
||||
*/
|
||||
class _Application extends \IPS\Application
|
||||
{
|
||||
/**
|
||||
* Init
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
/* Requesting iCal/RSS Subscription, but guests are required to login */
|
||||
if( \IPS\Request::i()->module == 'calendar' and \IPS\Request::i()->controller == 'view' and in_array( \IPS\Request::i()->do, array( 'rss', 'download' ) ) )
|
||||
{
|
||||
/* Validate RSS/Download key */
|
||||
if( \IPS\Request::i()->member )
|
||||
{
|
||||
$member = \IPS\Member::load( \IPS\Request::i()->member );
|
||||
if( \IPS\Request::i()->key != md5( ( $member->members_pass_hash ?: $member->email ) . $member->members_pass_salt ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2L217/1', 404, '' );
|
||||
}
|
||||
}
|
||||
|
||||
/* Output */
|
||||
if( \IPS\Request::i()->do == 'download' )
|
||||
{
|
||||
$this->download( \IPS\Request::i()->member ? $member : NULL );
|
||||
}
|
||||
|
||||
$this->rss( \IPS\Request::i()->member ? $member : NULL );
|
||||
}
|
||||
|
||||
/* Reset first day of week */
|
||||
if( \IPS\Settings::i()->ipb_calendar_mon )
|
||||
{
|
||||
\IPS\Output::i()->jsVars['date_first_day'] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Get Icon for tree
|
||||
*
|
||||
* @note Return the class for the icon (e.g. 'globe')
|
||||
* @return string|null
|
||||
*/
|
||||
protected function get__icon()
|
||||
{
|
||||
return 'calendar';
|
||||
}
|
||||
|
||||
/**
|
||||
* Latest events RSS
|
||||
*
|
||||
* @return void
|
||||
* @note There is a hard limit of the most recent 500 events updated
|
||||
*/
|
||||
public function download( $member=NULL )
|
||||
{
|
||||
$feed = new \IPS\calendar\Icalendar\ICSParser;
|
||||
$calendar = NULL;
|
||||
|
||||
/* Are we viewing a specific calendar only? */
|
||||
if( \IPS\Request::i()->id )
|
||||
{
|
||||
$calendar = \IPS\calendar\Calendar::load( \IPS\Request::i()->id );
|
||||
|
||||
if ( !$calendar->can( 'view' ) )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
}
|
||||
}
|
||||
|
||||
$where = array();
|
||||
|
||||
if( $calendar !== NULL )
|
||||
{
|
||||
$where[] = array( 'event_calendar_id=?', $calendar->id );
|
||||
}
|
||||
|
||||
foreach( \IPS\calendar\Event::getItemsWithPermission( $where, 'event_lastupdated DESC', 500, 'read', NULL, 0, $member ) as $event )
|
||||
{
|
||||
$feed->addEvent( $event );
|
||||
}
|
||||
|
||||
$ics = $feed->buildICalendarFeed( $this->_calendar );
|
||||
|
||||
\IPS\Output::i()->sendHeader( "Content-type: text/calendar; charset=UTF-8" );
|
||||
\IPS\Output::i()->sendHeader( 'Content-Disposition: inline; filename=calendarEvents.ics' );
|
||||
|
||||
print $ics;
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Latest events RSS
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function rss( $member=NULL )
|
||||
{
|
||||
if( !\IPS\Settings::i()->calendar_rss_feed )
|
||||
{
|
||||
\IPS\Output::i()->error( 'event_rss_feed_off', '2L182/1', 404, 'event_rss_feed_off_admin' );
|
||||
}
|
||||
|
||||
/* Load member */
|
||||
if ( $member === NULL )
|
||||
{
|
||||
$member = \IPS\Member::loggedIn();
|
||||
}
|
||||
|
||||
$rssTitle = $member->language()->get('calendar_rss_title');
|
||||
$document = \IPS\Xml\Rss::newDocument( \IPS\Http\Url::internal( 'app=calendar&module=calendar&controller=view', 'front', 'calendar' ), $rssTitle, $rssTitle );
|
||||
|
||||
$_today = \IPS\calendar\Date::getDate();
|
||||
|
||||
$endDate = NULL;
|
||||
|
||||
if( \IPS\Settings::i()->calendar_rss_feed_days > 0 )
|
||||
{
|
||||
$endDate = $_today->adjust( "+" . \IPS\Settings::i()->calendar_rss_feed_days . " days" );
|
||||
}
|
||||
|
||||
foreach ( \IPS\calendar\Event::retrieveEvents( $_today, $endDate, NULL, NULL, FALSE ) as $event )
|
||||
{
|
||||
$document->addItem( $event->title, $event->url(), $event->content, $event->nextOccurrence( $_today, 'startDate' ), $event->id );
|
||||
}
|
||||
|
||||
/* @note application/rss+xml is not a registered IANA mime-type so we need to stick with text/xml for RSS */
|
||||
\IPS\Output::i()->sendOutput( $document->asXML(), 200, 'text/xml' );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"calendars": {
|
||||
"calendars": {
|
||||
"tab": "community",
|
||||
"controller": "calendars",
|
||||
"do": "",
|
||||
"restriction": "calendars_manage"
|
||||
},
|
||||
"ical": {
|
||||
"tab": "community",
|
||||
"controller": "ical",
|
||||
"do": "",
|
||||
"restriction": "calendar_feeds_manage"
|
||||
},
|
||||
"settings": {
|
||||
"tab": "community",
|
||||
"controller": "settings",
|
||||
"do": "",
|
||||
"restriction": "settings_manage"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"calendars": {
|
||||
"calendars": {
|
||||
"calendars_manage": "calendars_manage",
|
||||
"calendars_add": "calendars_add",
|
||||
"calendars_edit": "calendars_edit",
|
||||
"calendars_permissions": "calendars_permissions",
|
||||
"calendars_delete": "calendars_delete"
|
||||
},
|
||||
"ical": {
|
||||
"calendar_feeds_manage": "calendar_feeds_manage",
|
||||
"calendar_feeds_add": "calendar_feeds_add",
|
||||
"calendar_feeds_edit": "calendar_feeds_edit",
|
||||
"calendar_feeds_delete": "calendar_feeds_delete"
|
||||
},
|
||||
"settings": {
|
||||
"settings_manage": "settings_manage"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"app=calendar&module=calendars&controller=calendars":{"lang_key":"menu__calendar_calendars_calendars","restriction":"calendars_manage","keywords":["calendars"]},"app=calendar&module=calendars&controller=settings&searchResult=form_calendar_default_view":{"lang_key":"calendar_default_view","restriction":"settings_manage","keywords":["calendar layout"]},"app=calendar&module=calendars&controller=settings&searchResult=form_calendar_date_format":{"lang_key":"calendar_date_format","restriction":"settings_manage","keywords":["calendar date format"]},"app=calendar&module=calendars&controller=settings&searchResult=form_show_bday_calendar":{"lang_key":"show_bday_calendar","restriction":"settings_manage","keywords":["birthdays"]},"app=calendar&module=calendars&controller=settings&searchResult=form_ipb_calendar_mon":{"lang_key":"ipb_calendar_mon","restriction":"settings_manage","keywords":["monday","sunday","calendar start"]},"app=calendar&module=calendars&controller=settings&searchResult=form_calendar_rss_feed":{"lang_key":"calendar_rss_feed","restriction":"settings_manage","keywords":["calendar rss","events rss"]},"app=calendar&module=calendars&controller=ical":{"lang_key":"menu__calendar_calendars_ical","restriction":"calendar_feeds_manage","keywords":["iCal","calendar export","iCalendar","feeds"]}}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"application_title": "Calendar",
|
||||
"app_author": "Invision Power Services, Inc.",
|
||||
"app_directory": "calendar",
|
||||
"app_protected": 0,
|
||||
"app_website": null,
|
||||
"app_update_check": null
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<emails><template><template_app>calendar</template_app><template_name>digests__item</template_name><template_content_html><![CDATA[<tr style='border-bottom: 1px solid #eeeeee'>
|
||||
<td width='120' valign='top' align='center'>
|
||||
<table width='120' cellpadding='10' cellspacing='0' border='0' bgcolor='#fafafa'>
|
||||
<tr>
|
||||
<td>
|
||||
<table width='100' cellpadding='0' cellspacing='0' border='0' bgcolor='#ffffff' style='border: 1px solid #cccccc;'>
|
||||
<tr>
|
||||
<td align='center' style="color: #a93848; font-size: 18px; line-height: 30px; text-transform: uppercase; font-family: 'Helvetica Neue', helvetica, sans-serif; font-weight: bold; padding-top: 5px;">
|
||||
{$event->nextOccurrence( \IPS\calendar\Date::getDate(), 'startDate' )->monthNameShort}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align='center' style="color: #333333; line-height: 40px; font-size: 44px; font-family: 'Helvetica Neue', helvetica, sans-serif; font-weight: 300; padding-bottom: 10px">
|
||||
{$event->nextOccurrence( \IPS\calendar\Date::getDate(), 'startDate' )->mday}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
<td align='left'>
|
||||
<p style='font-family: "Helvetica Neue", helvetica, sans-serif; margin: 0; font-size: 13px; font-weight: bold'>
|
||||
{$email->language->addToStack("x_created_event_in", FALSE, array( 'sprintf' => array( $event->author()->name, $event->container()->_title ) ) )}
|
||||
</p>
|
||||
<h2 style="font-family: 'Helvetica Neue', helvetica, sans-serif; font-size: 18px; font-weight: 500 !important; margin: 0">
|
||||
<a href='{$event->url()}' style='text-decoration: none;'>{$event->title}</a>
|
||||
{{if $event->mapped('featured')}} <span style='color: #68a72f; font-weight: bold; font-size: 12px; text-transform: uppercase;'>{$email->language->addToStack("featured", FALSE)}</span>{{endif}}
|
||||
</h2>
|
||||
<p style='font-family: "Helvetica Neue", helvetica, sans-serif; font-size: 16px;'>
|
||||
<strong>
|
||||
{$event->_start_date->dayName} {$event->_start_date->mday} {$event->_start_date->monthName} {$event->_start_date->year}{{if !$event->all_day}}, {$event->_start_date->localeTime( FALSE )}{{endif}}
|
||||
{{if $event->_end_date}}
|
||||
»
|
||||
{$event->_end_date->dayName} {$event->_end_date->mday} {$event->_end_date->monthName} {$event->_end_date->year}{{if !$event->all_day}}, {$event->_end_date->localeTime( FALSE )}{{endif}}
|
||||
{{endif}}
|
||||
</strong>
|
||||
</p>
|
||||
|
||||
<div style='font-family: "Helvetica Neue", helvetica, sans-serif; line-height: 22px; margin-top: 5px; margin-bottom: 5px'>
|
||||
{$email->parseTextForEmail( $event->content() )|raw}
|
||||
</div>
|
||||
|
||||
{{if $event->rsvp}}
|
||||
<div style="font-size: 13px; font-family: 'Helvetica Neue', helvetica, sans-serif; margin-top: 10px">
|
||||
{{if $attendees = $row->attendees()}}{{endif}}
|
||||
<strong style="text-transform: uppercase; font-size: 12px; font-family: 'Helvetica Neue', helvetica, sans-serif;">{$email->language->addToStack("digest_users_going", FALSE, array( 'pluralize' => array( count( $attendees[1] ) ) ) )}</strong>
|
||||
{{if count( $attendees[1] )}}
|
||||
{{foreach $attendees[1] as $idx => $attendee}}
|
||||
{{if $idx < 10}}
|
||||
<img src="{$attendee->photo}" width="32" height="32" style="border: 1px solid #000; vertical-align: middle;">
|
||||
{{endif}}
|
||||
{{endforeach}}
|
||||
{{if count( $attendees[1] ) > 10}}
|
||||
<span style="font-size: 13px; font-family: 'Helvetica Neue', helvetica, sans-serif; color: #8c8c8c">{$email->language->addToStack("and_x_more", FALSE, array( 'sprintf' => array( count( $attendees[1] ) - 10 ) ) )}</span>
|
||||
{{endif}}
|
||||
{{endif}}
|
||||
</div>
|
||||
{{endif}}
|
||||
<br />
|
||||
|
||||
{{if $event->container()->allow_reviews or $event->container()->allow_comments}}
|
||||
<p style='font-family: "Helvetica Neue", helvetica, sans-serif; margin: 0; font-size: 13px; margin-bottom: 15px'>
|
||||
{{if $event->container()->allow_reviews}}
|
||||
{{foreach range( 1, 5 ) as $i}}{{if $i <= $event->averageReviewRating()}}<img src='{resource="email/rating_on.png" location="interface" app="core"}' width='14' height='13' style='vertical-align: middle; margin-right: 2px'>{{else}}<img src='{resource="email/rating_off.png" location="interface" app="core"}' width='14' height='13' style='vertical-align: middle; margin-right: 2px'>{{endif}}{{endforeach}}
|
||||
{{endif}}
|
||||
{{if $event->container()->allow_comments}}
|
||||
|
||||
<strong style='font-family: "Helvetica Neue", helvetica, sans-serif; '><img src='{resource="email/comment.png" location="interface" app="core"}' width='13' height='12' style='vertical-align: middle'> {$email->language->addToStack("num_comments", FALSE, array( 'pluralize' => array( $event->comments ) ) )}</strong>
|
||||
{{endif}}
|
||||
</p>
|
||||
{{endif}}
|
||||
</td>
|
||||
</tr>]]></template_content_html><template_data>$event, $email</template_data><template_content_plaintext><![CDATA[{$email->language->addToStack("x_created_event_in", FALSE, array( 'sprintf' => array( $event->author()->name, $event->container()->_title ) ) )}: {$event->title} ({$event->url()})
|
||||
]]></template_content_plaintext></template><template><template_app>calendar</template_app><template_name>digests__comment</template_name><template_content_html><![CDATA[<tr style='border-bottom: 1px solid #eeeeee'>
|
||||
<td width='120' valign='top' align='center'>
|
||||
<table width='120' cellpadding='10' cellspacing='0' border='0' bgcolor='#fafafa'>
|
||||
<tr>
|
||||
<td>
|
||||
<table width='100' cellpadding='0' cellspacing='0' border='0' bgcolor='#ffffff' style='border: 1px solid #cccccc;'>
|
||||
<tr>
|
||||
<td align='center' style="color: #a93848; font-size: 18px; line-height: 30px; text-transform: uppercase; font-family: 'Helvetica Neue', helvetica, sans-serif; font-weight: bold; padding-top: 5px;">
|
||||
{$comment->item()->nextOccurrence( $today, 'startDate' )->monthNameShort}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align='center' style="color: #333333; line-height: 40px; font-size: 44px; font-family: 'Helvetica Neue', helvetica, sans-serif; font-weight: 300; padding-bottom: 10px">
|
||||
{$comment->item()->nextOccurrence( $today, 'startDate' )->mday}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
<td align='left'>
|
||||
<p style='font-family: "Helvetica Neue", helvetica, sans-serif; margin: 0; font-size: 13px; font-weight: bold'>
|
||||
{$email->language->addToStack("x_commented_event", FALSE, array( 'sprintf' => array( $comment->author()->name ) ) )}
|
||||
</p>
|
||||
<h2 style="font-family: 'Helvetica Neue', helvetica, sans-serif; font-size: 15px; font-weight: 500 !important; margin: 0">
|
||||
<a href='{$comment->item()->url()}' style='text-decoration: none;'>{$comment->item()->name}</a>
|
||||
</h2>
|
||||
<p style='font-family: "Helvetica Neue", helvetica, sans-serif; margin: 0; color: #8c8c8c; font-size: 13px;'>
|
||||
{$email->language->addToStack("email_event_on", FALSE)} {$comment->item()->_start_date->dayName} {$comment->item()->_start_date->mday} {$comment->item()->_start_date->monthName} {$comment->item()->_start_date->year}{{if !$comment->item()->all_day}}, {$comment->item()->_start_date->localeTime( FALSE )}{{endif}}
|
||||
{{if $comment->item()->_end_date}}
|
||||
»
|
||||
{$comment->item()->_end_date->dayName} {$comment->item()->_end_date->mday} {$comment->item()->_end_date->monthName} {$comment->item()->_end_date->year}{{if !$comment->item()->all_day}}, {$comment->item()->_end_date->localeTime( FALSE )}{{endif}}
|
||||
{{endif}}
|
||||
</p>
|
||||
<div style='font-family: "Helvetica Neue", helvetica, sans-serif; line-height: 22px; margin-top: 10px; margin-bottom: 10px; border-left: 3px solid #8c8c8c; padding-left: 15px; font-size: 14px; margin-left: 15px'>
|
||||
{$email->parseTextForEmail( $comment->content() )|raw}
|
||||
</div>
|
||||
|
||||
</td>
|
||||
</tr>]]></template_content_html><template_data>$comment, $email</template_data><template_content_plaintext><![CDATA[{$email->language->addToStack("x_commented_event", FALSE, array( 'sprintf' => array( $comment->author()->name ) ) )}: {$comment->item()->name} ({$comment->url()})
|
||||
]]></template_content_plaintext></template></emails>
|
||||
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
* Friendly URL Structure
|
||||
*
|
||||
* For each value in the $furl array:
|
||||
* The key should be the "SEO Template" - an identifier which you'll use when displaying a URL.
|
||||
* The value should be an associative array with two or three elements: 'friendly' and 'real', and optionally 'verify':
|
||||
* 'friendly'
|
||||
* The friendly URL to use - encase variables in {curly braces} containing a symbol, followed by the name of the parameter that matches in the "real" URL
|
||||
* The symbol should be # for numbers or @ for strings
|
||||
* For example, if the "real" URL contains id=XXX, where XXX is a number, you should include {#id} somewhere in the friendly URL.
|
||||
* You can also use the tag {?} for the "SEO Title" (that is, any variables that shouldn't be part of the real URL, such as the name of the topipc being viewed).
|
||||
* If you want to support more than one SEO Title, you can give them zero-indexed keys like so: {?0} {?1} {?2}
|
||||
* 'real'
|
||||
* This should be the base of the real URL. You should not include parameters which will be parsed out from the friendly URL.
|
||||
* 'verify'
|
||||
* This should be the name of a class that contains a loadFromUrl() and an url() method. The dynamic URL (i.e. app=core&...) will be passed to loadFromUrl(), and the url()
|
||||
* method will subsequently be called to retrieve the correct URL, ideal with ActiveRecord pattern classes.
|
||||
*
|
||||
* IMPORTANT: Ensure values are listed with the most specific ones first. This is to ensure that non-FURL redirects are done correctly. For example, if you have these FURLs:
|
||||
* /index.php?app=myapp&module=mymodule&controller=mycontroller&do=myaction -> /myfolder/myaction
|
||||
* /index.php?app=myapp&module=mymodule&controller=mycontroller -> /myfolder
|
||||
* They must be provided in that order, otherwise the former will redirec to /myfolder/?do=myaction rather than /myfolder/myaction
|
||||
*/
|
||||
{
|
||||
"topLevel": "calendar",
|
||||
"pages": {
|
||||
"calendar_calweek": {
|
||||
"friendly": "{#id}-{?}/week/{@w}",
|
||||
"real": "app=calendar&module=calendar&controller=view&view=week"
|
||||
},
|
||||
"calendar_calstream": {
|
||||
"friendly": "{#id}-{?}/events/{#y}/{#m}",
|
||||
"real": "app=calendar&module=calendar&controller=view&view=stream"
|
||||
},
|
||||
"calendar_calicaldownload": {
|
||||
"friendly": "{#id}-{?}/download",
|
||||
"real": "app=calendar&module=calendar&controller=view&do=download"
|
||||
},
|
||||
"calendar_calday": {
|
||||
"friendly": "{#id}-{?}/{#y}/{#m}/{#d}",
|
||||
"real": "app=calendar&module=calendar&controller=view&view=day",
|
||||
"alias": "calendar/{#id}-{?}/day-{#y}-{#m}-{#d}"
|
||||
},
|
||||
"calendar_calmonth": {
|
||||
"friendly": "{#id}-{?}/{#y}/{#m}",
|
||||
"real": "app=calendar&module=calendar&controller=view&view=month"
|
||||
},
|
||||
"calendar_calendar": {
|
||||
"friendly": "{#id}-{?}",
|
||||
"real": "app=calendar&module=calendar&controller=view",
|
||||
"verify": "\\IPS\\calendar\\Calendar"
|
||||
},
|
||||
"calendar_day": {
|
||||
"friendly": "{#y}/{#m}/{#d}",
|
||||
"real": "app=calendar&module=calendar&controller=view&view=day"
|
||||
},
|
||||
"calendar_month": {
|
||||
"friendly": "{#y}/{#m}",
|
||||
"real": "app=calendar&module=calendar&controller=view&view=month"
|
||||
},
|
||||
"calendar_week": {
|
||||
"friendly": "week/{@w}",
|
||||
"real": "app=calendar&module=calendar&controller=view&view=week"
|
||||
},
|
||||
"calendar_rss": {
|
||||
"friendly": "events.xml",
|
||||
"real": "app=calendar&module=calendar&controller=view&do=rss"
|
||||
},
|
||||
"calendar_stream": {
|
||||
"friendly": "events/{#y}/{#m}",
|
||||
"real": "app=calendar&module=calendar&controller=view&view=stream"
|
||||
},
|
||||
"calendar_icaldownload": {
|
||||
"friendly": "download",
|
||||
"real": "app=calendar&module=calendar&controller=view&do=download"
|
||||
},
|
||||
"calendar_event": {
|
||||
"friendly": "event/{#id}-{?}",
|
||||
"real": "app=calendar&module=calendar&controller=event",
|
||||
"verify": "\\IPS\\calendar\\Event"
|
||||
},
|
||||
"calendar_submit": {
|
||||
"friendly": "submit",
|
||||
"real": "app=calendar&module=calendar&controller=submit"
|
||||
},
|
||||
"calendar": {
|
||||
"friendly": "",
|
||||
"real": "app=calendar&module=calendar&controller=view"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
[]
|
||||
Whitespace-only changes.
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"calendar_calendar_1": "Community Calendar"
|
||||
}
|
||||
@@ -0,0 +1,661 @@
|
||||
<?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="100045" javascript_position="1000050"><![CDATA[/**
|
||||
* IPS Social Suite 4
|
||||
* (c) 2013 Invision Power Services - http://www.invisionpower.com
|
||||
*
|
||||
* ips.browse.main.js - Calendar main browsing controller
|
||||
*
|
||||
* Author: Rikki Tissier
|
||||
*/
|
||||
;( function($, _, undefined){
|
||||
"use strict";
|
||||
|
||||
ips.controller.register('calendar.front.browse.main', {
|
||||
|
||||
_ajaxObj: null,
|
||||
|
||||
initialize: function () {
|
||||
this.on( 'click', '[data-action="changeView"]', this.changeView );
|
||||
this.on( window, 'statechange', this.stateChange );
|
||||
this.setup();
|
||||
},
|
||||
|
||||
/**
|
||||
* Controller setup method
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
setup: function () {
|
||||
History.pushState( { controller: 'calendarView' }, document.title, window.location.href );
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the calendar view dynamically
|
||||
*
|
||||
* @param {event} e Event object
|
||||
* @returns {void}
|
||||
*/
|
||||
changeView: function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
// Load the url via ajax instead
|
||||
var self = this;
|
||||
var title = $( e.currentTarget ).attr('title');
|
||||
var url = $( e.currentTarget ).attr('href');
|
||||
|
||||
History.pushState( { controller: 'calendarView' }, title, url );
|
||||
},
|
||||
|
||||
/**
|
||||
* Event handler for history state changes
|
||||
*
|
||||
* @param {event} e Event object
|
||||
* @returns {void}
|
||||
*/
|
||||
stateChange: function () {
|
||||
var state = History.getState();
|
||||
|
||||
if( _.isUndefined( state.data.controller ) || state.data.controller != 'calendarView' ) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._updateView( state.url, state.title )
|
||||
},
|
||||
|
||||
/**
|
||||
* Loads a new view
|
||||
*
|
||||
* @param {string} url URL to load
|
||||
* @param {string} title New browser title
|
||||
* @returns {void}
|
||||
*/
|
||||
_updateView: function (url, title) {
|
||||
var self = this;
|
||||
|
||||
if( this._ajaxObj && _.isFunction( this._ajaxObj.abort ) ){
|
||||
this._ajaxObj.abort();
|
||||
}
|
||||
|
||||
this._setLoading( true );
|
||||
|
||||
this._ajaxObj = ips.getAjax()( url, {
|
||||
showLoading: true
|
||||
} )
|
||||
.done( function (response) {
|
||||
self.scope.html( response );
|
||||
|
||||
$( document ).trigger( 'contentChange', [ self.scope ] );
|
||||
|
||||
History.pushState( { controller: 'calendarView' }, title, url );
|
||||
})
|
||||
.always( function () {
|
||||
self._setLoading( false );
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Toggles the loading state on the view
|
||||
*
|
||||
* @param {boolean} state Enable the loading state?
|
||||
* @returns {void}
|
||||
*/
|
||||
_setLoading: function (state) {
|
||||
if( state ){
|
||||
this.scope.animate( { opacity: 0.6 }, 'fast' );
|
||||
} else {
|
||||
this.scope.animate( { opacity: 1 }, 'fast' );
|
||||
}
|
||||
}
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/browse" javascript_name="ips.browse.monthView.js" javascript_type="controller" javascript_version="100045" javascript_position="1000050"><![CDATA[/**
|
||||
* IPS Social Suite 4
|
||||
* (c) 2013 Invision Power Services - http://www.invisionpower.com
|
||||
*
|
||||
* ips.browse.monthView.js - Month view controller
|
||||
*
|
||||
* Author: Rikki Tissier
|
||||
*/
|
||||
;( function($, _, undefined){
|
||||
"use strict";
|
||||
|
||||
ips.controller.register('calendar.front.browse.monthView', {
|
||||
|
||||
_emptyEvent: "<li class='cEvents_event cEvents_empty' data-eventid='0'><span></span></a></li>",
|
||||
|
||||
initialize: function () {
|
||||
this.setup();
|
||||
},
|
||||
|
||||
/**
|
||||
* Setup method
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
setup: function () {
|
||||
this._alignEvents();
|
||||
},
|
||||
|
||||
|
||||
_alignEvents: function () {
|
||||
// Lets start by getting all active days in the current calendar
|
||||
var days = this.scope.find('.cCalendar_date');
|
||||
var currentPositions = [];
|
||||
var self = this;
|
||||
|
||||
_.each( days, function (day) {
|
||||
var day = $( day );
|
||||
var dayNumber = day.find('.cCalendar_dayNumber').text();
|
||||
var weekStart = false;
|
||||
|
||||
if( day.closest('td').is('tr > td:first-child') ){
|
||||
weekStart = true;
|
||||
}
|
||||
|
||||
// Get events for this day
|
||||
var events = day.find('.cEvents_ranged [data-eventID]');
|
||||
|
||||
// If there's no events, we can skip this day
|
||||
if( !events.length ){
|
||||
currentPositions = [];
|
||||
return;
|
||||
}
|
||||
|
||||
// Build a wrapper into which we'll move our events
|
||||
var wrapper = $("<ul/>").addClass('cEvents');
|
||||
var spaces = 0;
|
||||
|
||||
// Now we loop over currentPositions (from the previous day), and try and arrange today's events
|
||||
// in the same order
|
||||
if( currentPositions.length ){
|
||||
var doneEvent = false;
|
||||
|
||||
for( var i = 0; i < currentPositions.length; i++ ){
|
||||
if( events.filter('[data-eventID="' + currentPositions[i] + '"]').length ){
|
||||
wrapper.append( events.filter('[data-eventID="' + currentPositions[i] + '"]') );
|
||||
doneEvent = true;
|
||||
} else {
|
||||
|
||||
// If this is the first day of the week, we won't bother adding spacers unless we've already done an event today
|
||||
// This prevents lots of unnecessary spacers carrying over from the previous row
|
||||
if( !weekStart || doneEvent ){
|
||||
wrapper.append( self._emptyEvent );
|
||||
spaces++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var remainingEvents = day.find('.cEvents_ranged [data-eventID]');
|
||||
|
||||
// If we have any remaining events, and there's gaps available, we can move those events into the gaps rather than
|
||||
// just putting them at the end
|
||||
if( spaces && remainingEvents.length ){
|
||||
var availableSpaces = wrapper.find('[data-eventID="0"]');
|
||||
|
||||
// If we have a space and an event, move the event into that space
|
||||
for( var i = 0; i <= spaces; i++ ){
|
||||
if( remainingEvents[ i ] && availableSpaces[ i ] ){
|
||||
$( availableSpaces[ i ] ).replaceWith( $( remainingEvents[ i ] ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Update remaining events again
|
||||
remainingEvents = day.find('.cEvents_ranged [data-eventID]');
|
||||
}
|
||||
|
||||
// Add in remaining events
|
||||
wrapper.append( remainingEvents );
|
||||
|
||||
// Replace the existing wrapper with the new, correctly-ordered one
|
||||
day.find('.cEvents_ranged > .cEvents').replaceWith( wrapper );
|
||||
|
||||
// Now we need to build a new currentPositions array for this day, so that the following
|
||||
// day can use it to do its thing
|
||||
currentPositions = [];
|
||||
|
||||
_.each( day.find('.cEvents_ranged [data-eventID]'), function (event) {
|
||||
var eventID = parseInt( $( event ).attr('data-eventID') );
|
||||
|
||||
if( eventID === 0 ){
|
||||
currentPositions.push('-');
|
||||
} else if( _.isNumber( eventID ) && !_.isNaN( eventID ) ){
|
||||
currentPositions.push( eventID );
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Now get all rows and cells to recalculate height
|
||||
_.each( this.scope.find('tr'), function (row) {
|
||||
|
||||
// Don't bother if there's no birthdays in this row
|
||||
if( !$( row ).find('.cCalendar_birthdays').length ){
|
||||
return;
|
||||
}
|
||||
|
||||
var cells = $( row ).find('td.cCalendar_date');
|
||||
var maxHeightCell = _.max( cells, function (cell) {
|
||||
return parseInt( $( cell ).height() );
|
||||
});
|
||||
|
||||
if( !_.isElement( maxHeightCell ) ){
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the div height
|
||||
cells.find('> div').css({
|
||||
height: $( maxHeightCell ).height() + 20 + 'px'
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/submit" javascript_name="ips.submit.dates.js" javascript_type="controller" javascript_version="100045" javascript_position="1000100"><![CDATA[/**
|
||||
* IPS Social Suite 4
|
||||
* (c) 2013 Invision Power Services - http://www.invisionpower.com
|
||||
*
|
||||
* ips.submit.dates.js - Helper for date selection enhancements
|
||||
*
|
||||
* Author: Rikki Tissier
|
||||
*/
|
||||
;( function($, _, undefined){
|
||||
"use strict";
|
||||
|
||||
ips.controller.register('calendar.front.submit.dates', {
|
||||
|
||||
initialize: function () {
|
||||
this.on( 'click', '[data-action="updateTimezone"]', this.updateTimezone );
|
||||
|
||||
// Monitor focus in recurring event input fields and select appropriate radio button
|
||||
this.on( 'focus', 'input[name="repeat_end_occurrences"]', function(){ $('#event_repeat_end_afterx').prop('checked', true); } );
|
||||
this.on( 'focus', 'input[name="repeat_end_date"]', function(){ $('#event_repeat_end_ondate').prop('checked', true); } );
|
||||
|
||||
this.on( 'change', 'input, select', this.checkForSummaryChange );
|
||||
this.on( 'change', 'input, select', this.setEndDate );
|
||||
this.on( 'change', '#check_single_day, #check_all_day', this.toggleFields );
|
||||
this.on( 'click', '#elRecurRemove', this.disableRecurring );
|
||||
|
||||
$( window ).on( 'resize', _.bind( this._resizeEndGrid, this ) );
|
||||
|
||||
this.on( 'click', '[data-action="updateRepeat"]', this.finishRepeat );
|
||||
|
||||
this.setup();
|
||||
},
|
||||
|
||||
/**
|
||||
* Set the end date for single & all day event
|
||||
*/
|
||||
setEndDate: function() {
|
||||
var singleDay = this.scope.find('#check_single_day');
|
||||
var allDay = this.scope.find('#check_all_day');
|
||||
|
||||
if( singleDay.is(':checked') && !allDay.is(':checked') ) {
|
||||
this.scope.find('input[name="event_dates[end_date]"]').val( this.scope.find('input[name="event_dates[start_date]"]').val() )
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Finish setting the options
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
finishRepeat: function () {
|
||||
this._updateSummary();
|
||||
$('#elRecurEdit_menu').trigger('closeMenu');
|
||||
},
|
||||
|
||||
/**
|
||||
* Setup method
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
setup: function () {
|
||||
this._updateSummary();
|
||||
this.toggleFields();
|
||||
this.updateTimezone();
|
||||
|
||||
// Make Event End cell as big as Event Start cell
|
||||
this._resizeEndGrid();
|
||||
},
|
||||
|
||||
/**
|
||||
* Manual toggle functionality for the Single/All Day checkboxes
|
||||
*
|
||||
* @param {event} e Event object
|
||||
* @returns {void}
|
||||
*/
|
||||
toggleFields: function (e) {
|
||||
var singleDay = this.scope.find('#check_single_day');
|
||||
var allDay = this.scope.find('#check_all_day');
|
||||
var self = this;
|
||||
|
||||
var toggles = {
|
||||
start_time_wrap: true,
|
||||
end_time_wrap: true,
|
||||
event_end_date_wrap: true,
|
||||
elDateGrid_arrow: true,
|
||||
elDateGrid_end: true
|
||||
};
|
||||
|
||||
// Single day, not all day
|
||||
if( singleDay.is(':checked') && !allDay.is(':checked') ){
|
||||
toggles.event_end_date_wrap = false;
|
||||
// Single day, all day
|
||||
} else if( singleDay.is(':checked') && allDay.is(':checked') ){
|
||||
toggles.elDateGrid_arrow = false;
|
||||
toggles.elDateGrid_end = false;
|
||||
toggles.start_time_wrap = false;
|
||||
// Multiple days, all day
|
||||
} else if( !singleDay.is(':checked') && allDay.is(':checked') ){
|
||||
toggles.start_time_wrap = false;
|
||||
toggles.end_time_wrap = false;
|
||||
}
|
||||
|
||||
// Hide appropriate elements
|
||||
_.each( toggles, function (val, key) {
|
||||
self.scope.find( '#' + key ).toggle( val );
|
||||
});
|
||||
|
||||
// Manual check for ful;-width start date
|
||||
this.scope.find('#elDateGrid_start').toggleClass('ipsGrid_span5', this.scope.find('#elDateGrid_end').is(':visible') );
|
||||
},
|
||||
|
||||
/**
|
||||
* Monitor changes to the repeat options and update the summary
|
||||
*
|
||||
* @param {event} e Event object
|
||||
* @param {object} data Event data object
|
||||
* @returns {void}
|
||||
*/
|
||||
checkForSummaryChange: function (e) {
|
||||
if( $( e.currentTarget ).attr('name').startsWith('event_dates[') ){
|
||||
this._updateSummary();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates the timezone value both in the hidden field and in the display to the end user
|
||||
*
|
||||
* @param {event} e Event object
|
||||
* @returns {void}
|
||||
*/
|
||||
updateTimezone: function (e) {
|
||||
if( e ){
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
// Update displayed timezone
|
||||
this.scope.find('[data-role="timezone_display"]').text( $('#event_timezone option:selected').data('abbreviated') ).trigger('closeMenu');
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes the Repeat summary and unchecks the Repeat checkbox
|
||||
*
|
||||
* @param {event} e Event object
|
||||
* @param {object} data Event data object
|
||||
* @returns {void}
|
||||
*/
|
||||
disableRecurring: function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
this.scope.find('#elRepeatCb').prop( 'checked', false );
|
||||
this._updateSummary();
|
||||
},
|
||||
|
||||
/**
|
||||
* Finalize our recurring options
|
||||
*
|
||||
* @param {event} e Event object
|
||||
* @param {object} data Event data object
|
||||
* @returns {void}
|
||||
*/
|
||||
finishRepeatConfiguration: function (e, data) {
|
||||
e.preventDefault();
|
||||
|
||||
// Copy the summary from the menu to the main display and close the menu
|
||||
this.scope.find('[data-role="recur_summary_final"]').text( this.scope.find('[data-role="recur_summary"]').text() );
|
||||
this.scope.find('#elRecurEdit').trigger('closeMenu');
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the recurring string
|
||||
*
|
||||
* @param {event} e Event object
|
||||
* @param {object} data Event data object
|
||||
* @returns {void}
|
||||
*/
|
||||
_updateSummary: function () {
|
||||
var summary = this.scope.find('[data-role="recurringSummary"]');
|
||||
|
||||
// Update repeating text
|
||||
if( this.scope.find('#elRepeatCb').is(':checked') ){
|
||||
summary.text( this._getSummary() );
|
||||
this.scope.find('#elRepeatRow_hidden').hide();
|
||||
this.scope.find('#elRepeatRow_shown').show();
|
||||
} else {
|
||||
summary.html( "<em class='ipsType_light'>" + ips.getString('doesnt_repeat') + "</em>" );
|
||||
this.scope.find('#elRepeatRow_hidden').show();
|
||||
this.scope.find('#elRepeatRow_shown').hide();
|
||||
}
|
||||
|
||||
// Update the dates
|
||||
this.scope.find('[data-role="dateSummary"]').html( this._dateSummary() );
|
||||
},
|
||||
|
||||
/**
|
||||
* Get date object from input
|
||||
*
|
||||
* @param {object} input Input element
|
||||
* @returns {object} Date object
|
||||
*/
|
||||
_getDate: function(input) {
|
||||
/* jQuery UI Polyfill needs to be changed into the correct format */
|
||||
if ( input.hasClass('hasDatepicker') ) {
|
||||
/* If it has been initiated, we can use the getDate method */
|
||||
try {
|
||||
return input.datepicker( "getDate" );
|
||||
}
|
||||
/* If it hasn't we can pull the 'value' attribute which can't have been changed yet. Not .val() as that will be in the wrong format */
|
||||
catch(err) {
|
||||
return new Date( input.attr('value') );
|
||||
}
|
||||
}
|
||||
/* Actual HTML5 input always returns .val() in the correct YYYY-MM-DD format */
|
||||
else {
|
||||
return new Date( input.val() );
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Builds a summary of the selected dates/times
|
||||
*
|
||||
* @returns {string}
|
||||
*/
|
||||
_dateSummary: function () {
|
||||
// Build start date
|
||||
var startDate = this._getDate( this.scope.find('input[name="event_dates[start_date]"]') );
|
||||
var singleDay = this.scope.find('#check_single_day');
|
||||
var allDay = this.scope.find('#check_all_day');
|
||||
|
||||
// If there's no start time, then abandon showing any summary for now
|
||||
if( !ips.utils.time.isValidDateObj( startDate ) || startDate.getFullYear() < 1900 ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// We need to add the offset to ensure the day stays correct
|
||||
if ( this.scope.find( 'input[name="event_dates[start_date]"]' ).hasClass('hasDatepicker') ) {
|
||||
startDate.setTime( startDate.getTime() - new Date().getTimezoneOffset()*60000 );
|
||||
}
|
||||
|
||||
var startDateString = ips.utils.time.localeDateString( startDate, { weekday: 'short', month: 'short', day: 'numeric', year: 'numeric', timeZone: 'UTC' } );
|
||||
|
||||
var startTime = this._getTime( this.scope.find('input[name="event_dates[start_time]"]').val() );
|
||||
var endTime = this._getTime( this.scope.find('input[name="event_dates[end_time]"]').val() );
|
||||
var endDate = this._getDate( this.scope.find('input[name="event_dates[end_date]"]') );
|
||||
var endDateString = '';
|
||||
|
||||
// If we have a valid end date...
|
||||
if( !singleDay.is(':checked') && ips.utils.time.isValidDateObj( endDate ) ){
|
||||
if ( this.scope.find('input[name="event_dates[end_date]"]' ).hasClass( 'hasDatepicker' ) )
|
||||
{
|
||||
endDate.setTime( endDate.getTime() - new Date().getTimezoneOffset()*60000 );
|
||||
}
|
||||
endDateString = ips.utils.time.localeDateString( endDate, { weekday: 'short', month: 'short', day: 'numeric', year: 'numeric', timeZone: 'UTC' } );
|
||||
}
|
||||
|
||||
// Now build strings
|
||||
var finalString = '';
|
||||
|
||||
if( singleDay.is(':checked') && !allDay.is(':checked') ){
|
||||
finalString = ips.getString( 'single_not_allday', { startDate: startDateString, startTime: startTime, endTime: endTime } );
|
||||
} else if ( ( !singleDay.is(':checked') && !allDay.is(':checked') ) && endDateString && startTime && endTime ) {
|
||||
finalString = ips.getString( 'not_single_not_allday', { startDate: startDateString, endDate: endDateString, startTime: startTime, endTime: endTime } );
|
||||
} else if( !singleDay.is(':checked') && allDay.is(':checked') && endDateString ) {
|
||||
finalString = ips.getString( 'not_single_allday', { startDate: startDateString, endDate: endDateString } );
|
||||
} else {
|
||||
finalString = ips.getString( 'single_allday', { startDate: startDateString } );
|
||||
}
|
||||
|
||||
return finalString;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the given time, or a placeholder string if empty
|
||||
*
|
||||
* @param {string} time Time string
|
||||
* @returns {string}
|
||||
*/
|
||||
_getTime: function (time) {
|
||||
if( !time ){
|
||||
return "<em class='ipsType_light ipsType_unbold ipsFaded'>" + ips.getString('select_time') + "</em>";
|
||||
}
|
||||
|
||||
return time;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the summary string for recurring events
|
||||
*
|
||||
* @returns {string}
|
||||
*/
|
||||
_getSummary: function () {
|
||||
var type = this.scope.find('#elSelect_event_repeats').val();
|
||||
var intervalString = '';
|
||||
var endString = '';
|
||||
|
||||
// Build the 'interval' string
|
||||
switch( type ){
|
||||
case 'daily':
|
||||
case 'monthly':
|
||||
case 'yearly':
|
||||
intervalString = this._buildString( type );
|
||||
break;
|
||||
case 'weekly':
|
||||
intervalString = this._buildWeekly();
|
||||
break;
|
||||
}
|
||||
|
||||
// Build the 'end after' string
|
||||
if( this.scope.find('#event_repeat_end_afterx').is(':checked') ){
|
||||
var occurrences = parseInt( this.scope.find('input[name="event_dates[repeat_end_occurrences]"]').val() );
|
||||
|
||||
if( _.isNumber( occurrences ) && !_.isNaN( occurrences ) ){
|
||||
endString = ips.pluralize( ips.getString( 'x_times' ), occurrences );
|
||||
}
|
||||
} else if( this.scope.find('#event_repeat_end_ondate').is(':checked') ){
|
||||
var dateObj = this._getDate( this.scope.find('input[name="event_dates[repeat_end_date]"]') );
|
||||
|
||||
if( ips.utils.time.isValidDateObj( dateObj ) && dateObj.getFullYear() > 1900 ){ // > 1900 just so it doesn't start updating on year 19 etc.
|
||||
endString = ips.getString('until', { date: ips.utils.time.localeDateString( dateObj, { weekday: 'short', month: 'short', day: 'numeric', year: 'numeric' } ) } );
|
||||
}
|
||||
}
|
||||
|
||||
// Put it together
|
||||
if( endString ){
|
||||
return ips.getString( 'with_end', { interval: intervalString, endAfter: endString } );
|
||||
} else {
|
||||
return intervalString;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Builds a summary string for daily, monthly and yearly repeats
|
||||
*
|
||||
* @param {string} type The type of repeat
|
||||
* @returns {string}
|
||||
*/
|
||||
_buildString: function ( type ) {
|
||||
var val = parseInt( this.scope.find('#elSelect_event_repeat_freq').val() ) || 1;
|
||||
return ips.pluralize( ips.getString( 'every_x', { period: ips.pluralize( ips.getString( 'x_' + type ), val ) } ), val );
|
||||
},
|
||||
|
||||
/**
|
||||
* Builds a summary string for weekly repeats
|
||||
*
|
||||
* @returns {string}
|
||||
*/
|
||||
_buildWeekly: function () {
|
||||
var selectedDays = this.scope.find('[data-iCal]:checked');
|
||||
var val = parseInt( this.scope.find('#elSelect_event_repeat_freq').val() ) || 1;
|
||||
var weekString = '';
|
||||
|
||||
weekString = ips.pluralize( ips.getString( 'x_weekly' ), val );
|
||||
|
||||
// If no days are selected, we can bypass and finish now
|
||||
if( !selectedDays.length ){
|
||||
return weekString;
|
||||
}
|
||||
|
||||
// Get full days
|
||||
var fullDays = _.map( selectedDays, function (day, key) {
|
||||
return ips.getString( $( day ).attr('data-iCal') );
|
||||
});
|
||||
|
||||
// Build string
|
||||
var dayString = '';
|
||||
|
||||
if( fullDays.length === 1 ){
|
||||
dayString = ips.getString( 'one_day', { first: fullDays[0] } );
|
||||
} else {
|
||||
dayString = ips.getString( 'multiple_day', { days: fullDays.slice(0, -1).join(', '), last: fullDays[ fullDays.length - 1 ] });
|
||||
}
|
||||
|
||||
return ips.getString( 'week_string', { week: weekString, days: dayString } );
|
||||
},
|
||||
|
||||
/**
|
||||
* Resizes the "Event End" grid box to be the same height as the start box
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
_resizeEndGrid: function () {
|
||||
var height = 'auto';
|
||||
|
||||
if( !ips.utils.responsive.enabled() || !ips.utils.responsive.currentIs('phone') ){
|
||||
height = this.scope.find('#elDateGrid_start').outerHeight() + 'px';
|
||||
}
|
||||
|
||||
this.scope.find('#elDateGrid_end').css({
|
||||
height: height
|
||||
});
|
||||
}
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<order app="global" path="/dev/js//framework/">templates
|
||||
common/ui
|
||||
common/utils
|
||||
common
|
||||
controllers</order>
|
||||
<order app="global" path="/dev/js//library/">underscore
|
||||
jquery
|
||||
mustache
|
||||
jstz
|
||||
Debug.js
|
||||
app.js</order>
|
||||
<order app="global" path="/dev/js//library//jquery">jquery.js
|
||||
jquery.history.js
|
||||
jquery.transform.js</order>
|
||||
<order app="global" path="/dev/js//library//xregexp">xregexp-all.js
|
||||
xregexp-lookbehind.js</order>
|
||||
</javascript>
|
||||
@@ -0,0 +1,398 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<language>
|
||||
<app key="calendar" version="100045">
|
||||
<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="menu__calendar_calendars" js="0">Calendar</word>
|
||||
<word key="menu__calendar_calendars_calendars" js="0">Calendars</word>
|
||||
<word key="menu__calendar_calendars_ical" js="0">iCalendar Feeds</word>
|
||||
<word key="menu__calendar_calendars_settings" js="0">Settings</word>
|
||||
<word key="module__calendar_calendar" js="0">Calendar</word>
|
||||
<word key="module__calendar_calendars" js="0">Calendars</word>
|
||||
<word key="module__calendar_events" js="0">Events</word>
|
||||
<word key="event" js="0">Event</word>
|
||||
<word key="editor__calendar_Events" js="0">Calendar Events</word>
|
||||
<word key="acp_search_title_calendar_Calendars" js="0">Calendars</word>
|
||||
<word key="r__calendars" js="0">Calendars</word>
|
||||
<word key="r__calendars_manage" js="0">Can manage calendars?</word>
|
||||
<word key="r__calendars_add" js="0">Can add calendars?</word>
|
||||
<word key="r__calendars_edit" js="0">Can edit calendars?</word>
|
||||
<word key="r__calendars_permissions" js="0">Can manage calendar permissions?</word>
|
||||
<word key="r__calendars_delete" js="0">Can delete calendars?</word>
|
||||
<word key="r__ical" js="0">iCalendar Feeds</word>
|
||||
<word key="r__calendar_feeds_manage" js="0">Can manage iCalendar feed imports?</word>
|
||||
<word key="r__calendar_feeds_add" js="0">Can add iCalendar feed imports?</word>
|
||||
<word key="r__calendar_feeds_edit" js="0">Can edit iCalendar feed imports?</word>
|
||||
<word key="r__calendar_feeds_delete" js="0">Can delete iCalendar feed imports?</word>
|
||||
<word key="loc_calendar_viewing_calendar" js="0">Viewing Calendar: %s</word>
|
||||
<word key="loc_calendar_viewing_calendar_all" js="0">Viewing Calendar</word>
|
||||
<word key="loc_calendar_viewing_event" js="0">Viewing Event: %s</word>
|
||||
<word key="show_bday_calendar" js="0">Show birthdays on calendar</word>
|
||||
<word key="show_bday_calendar_desc" js="0">When enabled, the calendar will show the number of member birthdays for each day and will list member birthdays when viewing a date.</word>
|
||||
<word key="ipb_calendar_mon" js="0">Start calendar on Monday</word>
|
||||
<word key="ipb_calendar_mon_desc" js="0">By default, the calendar will use Sunday as the start day for each week. You can use this setting to start the calendar on Monday instead.</word>
|
||||
<word key="calendar_rss_feed" js="0">Enable upcoming events RSS feed</word>
|
||||
<word key="calendar_rss_feed_days" js="0">Number of forthcoming days to include in the feed</word>
|
||||
<word key="acplogs__calendar_settings" js="0">Updated calendar settings</word>
|
||||
<word key="calendar_default_view" js="0">Default layout</word>
|
||||
<word key="calendar_default_view_desc" js="0">This setting allows you to control the default layout of the calendar homepage. Users can override the default view if they wish.</word>
|
||||
<word key="cal_df_month" js="0">Current month</word>
|
||||
<word key="cal_df_week" js="0">Current week</word>
|
||||
<word key="cal_df_day" js="0">Current day</word>
|
||||
<word key="cal_df_stream" js="0">Stream of upcoming events</word>
|
||||
<word key="filestorage__calendar_Events" js="0">IP.Calendar Event Cover Photos</word>
|
||||
<word key="calendar_df_locale" js="0">Use default date formatting</word>
|
||||
<word key="calendar_df_d_sm_y" js="0">DD MMM YYYY (Example: 01 Jan 2000)</word>
|
||||
<word key="calendar_df_d_lm_y" js="0">DD Month YYYY (Example: 01 January 2000)</word>
|
||||
<word key="calendar_df_sm_d_y" js="0">MMM DD, YYYY (Example: Jan 01, 2000)</word>
|
||||
<word key="calendar_df_lm_d_y" js="0">Month DD, YYYY (Example: January 01, 2000)</word>
|
||||
<word key="calendar_custom_df" js="0">Or specify a custom date format</word>
|
||||
<word key="calendar_date_format" js="0">Date format for events</word>
|
||||
<word key="calendar_date_format_custom" js="0">Custom date format</word>
|
||||
<word key="calendar_date_format_custom_desc" js="0"><![CDATA[You can use any <a href='http://php.net/strftime' target='_blank'>PHP strftime</a> options to specify a custom format for dates in calendar]]></word>
|
||||
<word key="calendar_no_date_format" js="0">You must either choose a predefined date format or specify a custom date format</word>
|
||||
<word key="calendars" js="0">Calendars</word>
|
||||
<word key="calendars_sg" 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>
|
||||
<word key="cal_title" js="0">Name</word>
|
||||
<word key="cal_moderate" js="0">Events must be approved?</word>
|
||||
<word key="cal_comment_moderate" js="0">Comments must be approved?</word>
|
||||
<word key="cal_allow_comments" js="0">Allow comments?</word>
|
||||
<word key="cal_allow_reviews" js="0">Allow reviews?</word>
|
||||
<word key="cal_review_moderate" js="0">Reviews must be approved?</word>
|
||||
<word key="calperm_perm__label" js="0"></word>
|
||||
<word key="calperm_perm__view" js="0">See Calendar</word>
|
||||
<word key="calperm_perm__read" js="0">View Events</word>
|
||||
<word key="calperm_perm__add" js="0">Add Events</word>
|
||||
<word key="calperm_perm__reply" js="0">Comment</word>
|
||||
<word key="calperm_perm__askrsvp" js="0">Request RSVP</word>
|
||||
<word key="calperm_perm__rsvp" js="0">RSVP</word>
|
||||
<word key="calperm_perm__review" js="0">Review</word>
|
||||
<word key="cal_color" js="0">Color</word>
|
||||
<word key="add_calendar" js="0">Add Calendar</word>
|
||||
<word key="edit_calendar" js="0">Edit Calendar</word>
|
||||
<word key="modperms__core_Content_calendar_Event" js="0">Calendar</word>
|
||||
<word key="calendar_calendars" js="0">Calendars</word>
|
||||
<word key="can_pin_calendar_event" js="0">Can pin events?</word>
|
||||
<word key="can_unpin_calendar_event" js="0">Can unpin events?</word>
|
||||
<word key="can_feature_calendar_event" js="0">Can feature events?</word>
|
||||
<word key="can_unfeature_calendar_event" js="0">Can unfeature events?</word>
|
||||
<word key="can_move_calendar_event" js="0">Can move events?</word>
|
||||
<word key="can_lock_calendar_event" js="0">Can lock events?</word>
|
||||
<word key="can_unlock_calendar_event" js="0">Can unlock events?</word>
|
||||
<word key="can_reply_to_locked_calendar_event" js="0">Can comment on locked events?</word>
|
||||
<word key="can_edit_calendar_event" js="0">Can edit events?</word>
|
||||
<word key="can_hide_calendar_event" js="0">Can hide events?</word>
|
||||
<word key="can_unhide_calendar_event" js="0">Can unhide events?</word>
|
||||
<word key="can_view_hidden_calendar_event" js="0">Can view hidden events?</word>
|
||||
<word key="can_delete_calendar_event" js="0">Can delete events?</word>
|
||||
<word key="can_edit_calendar_event_comment" js="0">Can edit comments?</word>
|
||||
<word key="can_hide_calendar_event_comment" js="0">Can hide comments?</word>
|
||||
<word key="can_unhide_calendar_event_comment" js="0">Can unhide comments?</word>
|
||||
<word key="can_view_hidden_calendar_event_comment" js="0">Can view hidden comments?</word>
|
||||
<word key="can_delete_calendar_event_comment" js="0">Can delete comments?</word>
|
||||
<word key="can_edit_calendar_event_review" js="0">Can edit reviews?</word>
|
||||
<word key="can_hide_calendar_event_review" js="0">Can hide reviews?</word>
|
||||
<word key="can_unhide_calendar_event_review" js="0">Can unhide reviews?</word>
|
||||
<word key="can_view_hidden_calendar_event_review" js="0">Can view hidden reviews?</word>
|
||||
<word key="can_delete_calendar_event_review" js="0">Can delete reviews?</word>
|
||||
<word key="ical_title" js="0">iCalendar Feed Imports</word>
|
||||
<word key="ical_feed_title" js="0">Title</word>
|
||||
<word key="ical_feed_added" js="0">Added</word>
|
||||
<word key="ical_feed_lastupdated" js="0">Last Updated</word>
|
||||
<word key="ical_feed_calendar_id" js="0">Calendar</word>
|
||||
<word key="ical_feed_url" js="0">URL</word>
|
||||
<word key="calendar_feeds_add" js="0">Add iCalendar Feed</word>
|
||||
<word key="calendar_feeds_upload" js="0">Upload iCalendar File</word>
|
||||
<word key="update_ical" js="0">Import new events</word>
|
||||
<word key="feed_title" js="0">Name</word>
|
||||
<word key="feed_url" js="0">URL</word>
|
||||
<word key="feed_url_desc" js="0">The URL should start with http://, https:// or webcal://</word>
|
||||
<word key="feed_member_id" js="0">Member</word>
|
||||
<word key="feed_member_id_desc" js="0">Events from this feed will be created by this member</word>
|
||||
<word key="feed_calendar_id" js="0">Calendar</word>
|
||||
<word key="feed_calendar_id_desc" js="0">Select the calendar that events from this feed will be saved to</word>
|
||||
<word key="feed_allow_rsvp" js="0">Enable RSVP</word>
|
||||
<word key="feed_allow_rsvp_desc" js="0">If enabled, RSVP will be enabled for all events imported from this feed</word>
|
||||
<word key="acplog__ical_uploaded" js="0">Uploaded an iCalendar file (%s events imported and %s events skipped)</word>
|
||||
<word key="acplog__icalfeed_created" js="0">Added %s iCalendar feed</word>
|
||||
<word key="acplog__icalfeed_updated" js="0">Edited %s iCalendar feed</word>
|
||||
<word key="feed_uploaded" js="0">iCalendar Events Imported</word>
|
||||
<word key="acplog__icalfeed_refreshed" js="0">Refreshed iCalendar feed (%s events imported and %s events skipped)</word>
|
||||
<word key="feed_refreshed" js="0">iCalendar Feed Refreshed</word>
|
||||
<word key="feed_file" js="0">iCalendar File</word>
|
||||
<word key="feed_file_desc" js="0">iCalendar files usually have a .ics extension</word>
|
||||
<word key="feed_not_found" js="0">We could not find that iCalendar feed</word>
|
||||
<word key="acplog__icalfeed_deleted" js="0">%s iCalendar feed deleted</word>
|
||||
<word key="keep_events" js="0">Keep Events</word>
|
||||
<word key="keep_events_desc" js="0">You can choose to remove events that were imported from this feed</word>
|
||||
<word key="ical_error_NO_CONTENT" js="0">The feed appears to be invalid because no content was returned</word>
|
||||
<word key="ical_error_BAD_CONTENT" js="0">The feed appears to be invalid because content not matching the expected format was returned</word>
|
||||
<word key="cal_month_title" js="0">%s %s</word>
|
||||
<word key="cal_month_stream_title" js="0">Event stream for %s %s</word>
|
||||
<word key="cal_week_title" js="0">%s %s %s - %s %s %s</word>
|
||||
<word key="cal_week_title_wb" js="0">w/b %s %s %s</word>
|
||||
<word key="cal_month_day" js="0">%s %s, %s</word>
|
||||
<word key="all_calendars" js="0">All Calendars</word>
|
||||
<word key="create_event" js="0">Create Event</word>
|
||||
<word key="add_event" js="0">Add event</word>
|
||||
<word key="previous_month" js="0">Prev Month</word>
|
||||
<word key="next_month" js="0">Next Month</word>
|
||||
<word key="day" js="0">Day</word>
|
||||
<word key="yesterday" js="0">Yesterday</word>
|
||||
<word key="tomorrow" js="0">Tomorrow</word>
|
||||
<word key="prev_day" js="0">Prev Day</word>
|
||||
<word key="next_day" js="0">Next Day</word>
|
||||
<word key="event_stream" js="0">Event Stream</word>
|
||||
<word key="event_stream_short" js="0">Stream</word>
|
||||
<word key="previous_week" js="0">Prev Week</word>
|
||||
<word key="next_week" js="0">Next Week</word>
|
||||
<word key="no_events_today" js="0">No events scheduled today</word>
|
||||
<word key="no_events_month" js="0">No events scheduled this month</word>
|
||||
<word key="error_bad_date" js="0">The date you requested appears to be invalid</word>
|
||||
<word key="birthdays_today" js="0">{# [1:birthday][?:birthdays]} today</word>
|
||||
<word key="birthdays_count" js="0">{# [1:birthday][?:birthdays]}</word>
|
||||
<word key="calendar_event" js="0">Event</word>
|
||||
<word key="calendar_event_comment" js="0">Event Comment</word>
|
||||
<word key="calendar_event_review" js="0">Event Review</word>
|
||||
<word key="calendar_event_pl" js="0">Events</word>
|
||||
<word key="calendar_event_comment_pl" js="0">Event Comments</word>
|
||||
<word key="calendar_event_review_pl" js="0">Event Reviews</word>
|
||||
<word key="event_review_count" js="0"><![CDATA[<span id='reviewCount'>{#}</span> {!# [1:Review][?:Reviews]}]]></word>
|
||||
<word key="event_comment_count" js="0"><![CDATA[<span id='commentCount'>{#}</span> {!# [1:Comment][?:Comments]}]]></word>
|
||||
<word key="event_rsvp_attendees_list" js="0">{# [1:user has][?:users have]} RSVPed{!#[0: ][?:, including]}</word>
|
||||
<word key="calendar_rss_title" js="0">Upcoming Events</word>
|
||||
<word key="submit_event" js="0">Submit an event</word>
|
||||
<word key="with_calendar" js="0">With '%s'</word>
|
||||
<word key="with_all_calendars" js="0">With All Calendars</word>
|
||||
<word key="event_calendar_id" js="0">Calendar</word>
|
||||
<word key="event_container" js="0">Calendar</word>
|
||||
<word key="event_title" js="0">Title</word>
|
||||
<word key="event_tags" js="0">Tags</word>
|
||||
<word key="event_content" js="0">Description</word>
|
||||
<word key="event_dates" js="0">Date</word>
|
||||
<word key="rsvp" js="0">RSVP</word>
|
||||
<word key="event_rsvp" js="0">Request RSVP</word>
|
||||
<word key="event_rsvp_desc" js="0">Members who are allowed to RSVP for events will be asked to do so and will be able to see the list of members who have RSVP'd for this event</word>
|
||||
<word key="event_to" js="0">to</word>
|
||||
<word key="event_all_day" js="0">This is an all day event</word>
|
||||
<word key="event_repeat" js="0">Repeat</word>
|
||||
<word key="change_timezone" js="0">Change the time zone</word>
|
||||
<word key="event_timezone" js="0">Event Time Zone</word>
|
||||
<word key="event_rpm_repeats" js="0">Repeats:</word>
|
||||
<word key="event_rpm_repeats_daily" js="0">Daily</word>
|
||||
<word key="event_rpm_repeats_weekly" js="0">Weekly</word>
|
||||
<word key="event_rpm_repeats_monthly" js="0">Monthly</word>
|
||||
<word key="event_rpm_repeats_yearly" js="0">Yearly</word>
|
||||
<word key="event_rpm_repeatevery" js="0">Repeat every:</word>
|
||||
<word key="event_rpm_repeatevery_day" js="0">days</word>
|
||||
<word key="event_rpm_repeatevery_week" js="0">weeks</word>
|
||||
<word key="event_rpm_repeatevery_month" js="0">months</word>
|
||||
<word key="event_rpm_repeatevery_year" js="0">years</word>
|
||||
<word key="event_rpm_repeaton" js="0">Repeat on:</word>
|
||||
<word key="event_single_day" js="0">Single day event</word>
|
||||
<word key="event_rpm_ends" js="0">Ends:</word>
|
||||
<word key="event_rpm_ends_never" js="0">Never</word>
|
||||
<word key="event_rpm_ends_afterx" js="0">After</word>
|
||||
<word key="event_rpm_ends_occurrencesx" js="0">occurrences</word>
|
||||
<word key="event_rpm_ends_date" js="0">On</word>
|
||||
<word key="event_auto_follow" js="0"></word>
|
||||
<word key="event_auto_follow_suffix" js="0">Notify me when other comments are posted</word>
|
||||
<word key="event_rsvp_limit" js="0">RSVP Limit</word>
|
||||
<word key="event_rsvp_limit_desc" js="0">Once the limit is reached, no further attendees will be allowed to RSVP for this event</word>
|
||||
<word key="event_cover_photo" js="0">Cover Photo</word>
|
||||
<word key="event_location" js="0">Location</word>
|
||||
<word key="event_album" js="0">Album</word>
|
||||
<word key="event_album_desc" js="0">You can link an album from the Gallery to this event which will show the images on the event page and cause information about the event to be displayed on the album page</word>
|
||||
<word key="submit_event_start" js="0">Event Start</word>
|
||||
<word key="submit_event_end" js="0">Event End</word>
|
||||
<word key="submit_event_summary" js="0">Summary</word>
|
||||
<word key="submit_event_repeats_check" js="0">This event repeats</word>
|
||||
<word key="submit_event_repeats" js="0">Repeats</word>
|
||||
<word key="submit_event_remove_repeat" js="0">remove</word>
|
||||
<word key="add_cal_event_header" js="0">Add Calendar Event</word>
|
||||
<word key="calendar_jump" js="0">Go</word>
|
||||
<word key="calendar_jump_today" js="0">Go to today</word>
|
||||
<word key="jump_to_placeholder" js="0">Jump to...</word>
|
||||
<word key="jump_to" js="0">Jump to</word>
|
||||
<word key="events_happening_today" js="0">Events happening today</word>
|
||||
<word key="day_view_all_day" js="0"><![CDATA[ALL<br>DAY]]></word>
|
||||
<word key="you_are_going" js="0">You are going</word>
|
||||
<word key="you_are_going_to_this" js="0">You are going to this event</word>
|
||||
<word key="you_are_not_going_to_this" js="0">You are not going to this event</word>
|
||||
<word key="confirm_attendance" js="0">Confirm attendance</word>
|
||||
<word key="featured_events" js="0">Featured Events</word>
|
||||
<word key="end_date_before_start" js="0">Please select an end date after the event start date</word>
|
||||
<word key="invalid_start_date" js="0">The provided start date is not valid</word>
|
||||
<word key="invalid_end_date" js="0">The provided end date is not valid</word>
|
||||
<word key="event__save" js="0">Save</word>
|
||||
<word key="calendar_delete_title" js="0">Delete this event</word>
|
||||
<word key="blurb_date_with_time" js="0">%s %s</word>
|
||||
<word key="blurb_start_and_end" js="0">%s - %s in %s</word>
|
||||
<word key="blurb_start_only" js="0">%s in %s</word>
|
||||
<word key="download_ical" js="0">Download Event</word>
|
||||
<word key="download_ical_title" js="0">Download this event as an iCal file</word>
|
||||
<word key="event_details" js="0">Event details</word>
|
||||
<word key="event_created_by" js="0">Event created by %s</word>
|
||||
<word key="event_rating_value" js="0">Your Rating</word>
|
||||
<word key="event_review_text" js="0">Your Review</word>
|
||||
<word key="event__review_placeholder" js="0">Add a review...</word>
|
||||
<word key="event__comment_placeholder" js="0">Add a comment...</word>
|
||||
<word key="event_submit_comment" js="0">Submit Comment</word>
|
||||
<word key="event_rsvp_attendees" js="0">Attendees</word>
|
||||
<word key="report_event" js="0">Report Event</word>
|
||||
<word key="calendar_edit_details" js="0">Edit Details</word>
|
||||
<word key="calendar_edit_details_title" js="0">Edit this event's details</word>
|
||||
<word key="manage_event" js="0">Manage Event</word>
|
||||
<word key="event_pending_approval" js="0">This event is not yet approved and is only visible to staff.</word>
|
||||
<word key="rsvp_leave_event" js="0">Leave event</word>
|
||||
<word key="rsvp_attend_event" js="0">Going</word>
|
||||
<word key="rsvp_maybe_event" js="0">Maybe</word>
|
||||
<word key="rsvp_notgoing_event" js="0">Decline</word>
|
||||
<word key="rsvp_attendees" js="0">Going</word>
|
||||
<word key="rsvp_maybe_attendees" js="0">Maybe</word>
|
||||
<word key="rsvp_notgoing_attendees" js="0">Declined</word>
|
||||
<word key="no_rsvps_yet" js="0">No one is attending yet.</word>
|
||||
<word key="no_decline_rsvps_yet" js="0">No one has declined yet.</word>
|
||||
<word key="no_maybe_rsvps_yet" js="0">No one has said they might go yet.</word>
|
||||
<word key="rsvp_limit_reached" js="0">RSVP limit reached</word>
|
||||
<word key="rsvp_error" js="0">You do not have permission to RSVP for this event</word>
|
||||
<word key="rsvp_not_going" js="0">Your name has been removed from the guest list for this event</word>
|
||||
<word key="rsvp_selection_yes" js="0">Your name has been added to the guest list</word>
|
||||
<word key="rsvp_selection_no" js="0">It's too bad you won't be able to make it to the event!</word>
|
||||
<word key="rsvp_selection_maybe" js="0">Your name has been added to the maybe list</word>
|
||||
<word key="rsvp_download" js="0">Download guest list</word>
|
||||
<word key="event_rsvp_attendees_other" js="0">Other Responses</word>
|
||||
<word key="recur_human_yearly" js="0">This event repeats every year %s</word>
|
||||
<word key="recur_human_yearly_multi" js="0">This event repeats every %s years %s</word>
|
||||
<word key="recur_human_monthly" js="0">This event repeats every month %s</word>
|
||||
<word key="recur_human_monthly_multi" js="0">This event repeats every %s months %s</word>
|
||||
<word key="recur_human_weekly" js="0">This event repeats every week %s</word>
|
||||
<word key="recur_human_weekly_multi" js="0">This event repeats every %s weeks %s</word>
|
||||
<word key="recur_human_weekly_days" js="0">This event repeats every week on %s %s</word>
|
||||
<word key="recur_human_weekly_multi_days" js="0">This event repeats every %s weeks on %s %s</word>
|
||||
<word key="recur_human_daily" js="0">This event repeats every day %s</word>
|
||||
<word key="recur_human_daily_multi" js="0">This event repeats every %s days %s</word>
|
||||
<word key="recur_human__forever" js="0">forever</word>
|
||||
<word key="recur_human__occurrences" js="0">for {# [1:occurrence][?:occurrences]}</word>
|
||||
<word key="recur_human__until" js="0">until %s</word>
|
||||
<word key="event_rss_feed_off" js="0">This RSS feed is currently unavailable</word>
|
||||
<word key="event_rss_feed_off_admin" js="0">The calendar RSS feed is currently disabled in the admin control panel</word>
|
||||
<word key="event_attendees" js="0">Attendees for %s</word>
|
||||
<word key="rsvp_limit_info" js="0">{# [1:user][?:users]} out of a total limit of %s have RSVPed for this event</word>
|
||||
<word key="rsvp_limit_nomaybe" js="0">You may only indicate you are going or not going when an event has a limit specified</word>
|
||||
<word key="no_event_review" js="0">You do not have permission to review events</word>
|
||||
<word key="task_BAD_CONTENT" js="0">The iCalendar feed %s is not correctly formatted in a recognized iCalendar format</word>
|
||||
<word key="task_NO_CONTENT" js="0">The iCalendar feed %s did not return any events to process</word>
|
||||
<word key="subscribe_webcal" js="0">Subscribe to iCalendar feed</word>
|
||||
<word key="download_webcal" js="0">Download iCalendar export</word>
|
||||
<word key="calendar_id" js="0">Calendar</word>
|
||||
<word key="event_locked_can_comment" js="0">This event is locked, but your permissions allow you to add new comments.</word>
|
||||
<word key="event_locked_cannot_comment" js="0">This event is now closed to further comments.</word>
|
||||
<word key="event_images" js="0">Images from this event</word>
|
||||
<word key="event_move_title" js="0">Move this event</word>
|
||||
<word key="feature_title_event" js="0">Feature this event</word>
|
||||
<word key="unfeature_title_event" js="0">Unfeature this event</word>
|
||||
<word key="pin_title_event" js="0">Pin this event</word>
|
||||
<word key="unpin_title_event" js="0">Unpin this event</word>
|
||||
<word key="hide_title_event" js="0">Hide this event</word>
|
||||
<word key="unhide_title_event" js="0">Unhide this event</word>
|
||||
<word key="lock_title_event" js="0">Lock this event</word>
|
||||
<word key="unlock_title_event" js="0">Unlock this event</word>
|
||||
<word key="approve_title_event" js="0">Approve this event</word>
|
||||
<word key="block_upcomingEvents" js="0">Upcoming Events</word>
|
||||
<word key="block_upcomingEvents_desc" js="0">Shows upcoming calendar events</word>
|
||||
<word key="auto_hide" js="0">Automatically hide block</word>
|
||||
<word key="auto_hide_desc" js="0">Hide this block when there are no results to display</word>
|
||||
<word key="days_ahead" js="0">Number of days to show</word>
|
||||
<word key="maximum_count" js="0">Number of events</word>
|
||||
<word key="view_this_event" js="0">View %s</word>
|
||||
<word key="block_todaysBirthdays" js="0">Today's Birthdays</word>
|
||||
<word key="block_todaysBirthdays_desc" js="0">Shows birthdays from today</word>
|
||||
<word key="no_members_birthday_today" js="0">No users celebrating today</word>
|
||||
<word key="no_upcoming_events" js="0">No upcoming events found</word>
|
||||
<word key="member_age" js="0">(%s years old)</word>
|
||||
<word key="block_recentReviews" js="0">Recent Event Reviews</word>
|
||||
<word key="block_recentReviews_desc" js="0">Display the most recent reviews</word>
|
||||
<word key="no_recent_reviews" js="0">No recent reviews found</word>
|
||||
<word key="announce_calendars" js="0">Calendars</word>
|
||||
<word key="review_count" js="0">Number of reviews to show</word>
|
||||
<word key="embed_calendar_event" js="0">Calendar Event</word>
|
||||
<word key="x_users_going" js="0">{# [1:user][?:users]} going</word>
|
||||
<word key="timezone_offset_short" js="0">GMT %s</word>
|
||||
<word key="timezone_offset_-12" js="0">[GMT - 12] Baker Island Time</word>
|
||||
<word key="timezone_offset_-11" js="0">[GMT - 11] Samoa Standard Time</word>
|
||||
<word key="timezone_offset_-10" js="0">[GMT - 10] Hawaii Standard Time</word>
|
||||
<word key="timezone_offset_-9.5" js="0">[GMT - 9:30] Marquesas Islands Time</word>
|
||||
<word key="timezone_offset_-9" js="0">[GMT - 9] Alaska Standard Time</word>
|
||||
<word key="timezone_offset_-8" js="0">[GMT - 8] Pacific Standard Time</word>
|
||||
<word key="timezone_offset_-7" js="0">[GMT - 7] Mountain Standard Time</word>
|
||||
<word key="timezone_offset_-6" js="0">[GMT - 6] Central Standard Time</word>
|
||||
<word key="timezone_offset_-5" js="0">[GMT - 5] Eastern Standard Time</word>
|
||||
<word key="timezone_offset_-4.5" js="0">[GMT - 4:30] Venezuelan Standard Time</word>
|
||||
<word key="timezone_offset_-4" js="0">[GMT - 4] Atlantic Standard Time</word>
|
||||
<word key="timezone_offset_-3.5" js="0">[GMT - 3:30] Newfoundland Standard Time</word>
|
||||
<word key="timezone_offset_-3" js="0">[GMT - 3] Brasília time</word>
|
||||
<word key="timezone_offset_-2" js="0">[GMT - 2] Fernando de Noronha Time</word>
|
||||
<word key="timezone_offset_-1" js="0">[GMT - 1] Eastern Greenland Time</word>
|
||||
<word key="timezone_offset_0" js="0">[GMT] Greenwich Mean Time</word>
|
||||
<word key="timezone_offset_1" js="0">[GMT + 1] Central European Time</word>
|
||||
<word key="timezone_offset_2" js="0">[GMT + 2] Eastern European Time</word>
|
||||
<word key="timezone_offset_3" js="0">[GMT + 3] Eastern African Time</word>
|
||||
<word key="timezone_offset_3.5" js="0">[GMT + 3:30] Iran Standard Time</word>
|
||||
<word key="timezone_offset_4" js="0">[GMT + 4] Gulf Standard Time</word>
|
||||
<word key="timezone_offset_4.5" js="0">[GMT + 4:30] Afghanistan Time</word>
|
||||
<word key="timezone_offset_5" js="0">[GMT + 5] Pakistan Standard Time</word>
|
||||
<word key="timezone_offset_5.5" js="0">[GMT + 5:30] Indian Standard Time</word>
|
||||
<word key="timezone_offset_5.75" js="0">[GMT + 5:45] Nepal Time</word>
|
||||
<word key="timezone_offset_6" js="0">[GMT + 6] Bangladesh Time</word>
|
||||
<word key="timezone_offset_6.5" js="0">[GMT + 6:30] Myanmar Time</word>
|
||||
<word key="timezone_offset_7" js="0">[GMT + 7] Indochina Time</word>
|
||||
<word key="timezone_offset_8" js="0">[GMT + 8] Chinese Standard Time</word>
|
||||
<word key="timezone_offset_9" js="0">[GMT + 9] Japan Standard Time</word>
|
||||
<word key="timezone_offset_9.5" js="0">[GMT + 9:30] Australian Central Standard Time</word>
|
||||
<word key="timezone_offset_10" js="0">[GMT + 10] Australian Eastern Standard Time</word>
|
||||
<word key="timezone_offset_10.5" js="0">[GMT + 10:30] Lord Howe Standard Time</word>
|
||||
<word key="timezone_offset_11" js="0">[GMT + 11] Solomon Island Time</word>
|
||||
<word key="timezone_offset_11.5" js="0">[GMT + 11:30] Norfolk Island Time</word>
|
||||
<word key="timezone_offset_12" js="0">[GMT + 12] New Zealand Time</word>
|
||||
<word key="timezone_offset_12.75" js="0">[GMT + 12:45] Chatham Islands Time</word>
|
||||
<word key="timezone_offset_13" js="0">[GMT + 13] Phoenix Islands Time</word>
|
||||
<word key="timezone_offset_14" js="0">[GMT + 14] Line Island Time</word>
|
||||
<word key="task__icalendar" js="0">Checks iCalendar feeds for new events and imports into IP.Calendar.</word>
|
||||
<word key="digest_area_calendar" js="0">Events</word>
|
||||
<word key="x_created_event_in" js="0">%s posted an event in %s</word>
|
||||
<word key="x_commented_event" js="0">%s commented on an event</word>
|
||||
<word key="digest_event_on" js="0">Event on</word>
|
||||
<word key="digest_users_going" js="0">{# [1:user][?:users]} going</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>
|
||||
<word key="x_yearly" js="1">{# [1:year][?:years]}</word>
|
||||
<word key="every_x" js="1">Every {{period}}</word>
|
||||
<word key="x_times" js="1">{# [1:time][?:times]}</word>
|
||||
<word key="until" js="1">until {{date}}</word>
|
||||
<word key="with_end" js="1">{{interval}}, {{endAfter}}</word>
|
||||
<word key="MO" js="1">Monday</word>
|
||||
<word key="TU" js="1">Tuesday</word>
|
||||
<word key="WE" js="1">Wednesday</word>
|
||||
<word key="TH" js="1">Thursday</word>
|
||||
<word key="FR" js="1">Friday</word>
|
||||
<word key="SA" js="1">Saturday</word>
|
||||
<word key="SU" js="1">Sunday</word>
|
||||
<word key="one_day" js="1">on {{first}}</word>
|
||||
<word key="multiple_day" js="1">on {{days}} and {{last}}</word>
|
||||
<word key="week_string" js="1">{{week}} {{days}}</word>
|
||||
<word key="doesnt_repeat" js="1">Doesn't repeat</word>
|
||||
<word key="single_not_allday" js="1"><![CDATA[On <strong>{{startDate}}</strong>, from <strong>{{startTime}}</strong> to <strong>{{endTime}}</strong>]]></word>
|
||||
<word key="single_allday" js="1"><![CDATA[<strong>{{startDate}}</strong> (all day)]]></word>
|
||||
<word key="not_single_not_allday" js="1"><![CDATA[From <strong>{{startDate}}</strong> at <strong>{{startTime}}</strong> until <strong>{{endDate}}</strong> at <strong>{{endTime}}</strong>]]></word>
|
||||
<word key="not_single_allday" js="1"><![CDATA[From <strong>{{startDate}}</strong> to <strong>{{endDate}}</strong>]]></word>
|
||||
<word key="select_time" js="1">(select time)</word>
|
||||
</app>
|
||||
</language>
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"admin": {
|
||||
"calendars": {
|
||||
"default_controller": null,
|
||||
"protected": 0
|
||||
}
|
||||
},
|
||||
"front": {
|
||||
"calendar": {
|
||||
"default_controller": "view",
|
||||
"protected": false
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,30 @@
|
||||
[
|
||||
{
|
||||
"key": "calendar_date_format",
|
||||
"default": "d_lm_y"
|
||||
},
|
||||
{
|
||||
"key": "calendar_date_format_custom",
|
||||
"default": ""
|
||||
},
|
||||
{
|
||||
"key": "calendar_default_view",
|
||||
"default": "month"
|
||||
},
|
||||
{
|
||||
"key": "calendar_rss_feed",
|
||||
"default": "1"
|
||||
},
|
||||
{
|
||||
"key": "calendar_rss_feed_days",
|
||||
"default": "30"
|
||||
},
|
||||
{
|
||||
"key": "ipb_calendar_mon",
|
||||
"default": "0"
|
||||
},
|
||||
{
|
||||
"key": "show_bday_calendar",
|
||||
"default": "1"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1 @@
|
||||
{"icalendar":"P0Y0M0DT4H0M0S"}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -0,0 +1,59 @@
|
||||
{
|
||||
"32000": "3.2.0 Beta 1",
|
||||
"32001": "3.2.0 Beta 2",
|
||||
"32003": "3.2.0",
|
||||
"32004": "3.2.1",
|
||||
"32005": "3.2.2",
|
||||
"33000": "3.3.0",
|
||||
"33001": "3.3.1",
|
||||
"33002": "3.3.2",
|
||||
"33003": "3.3.3",
|
||||
"33004": "3.3.4",
|
||||
"40000": "4.0.0",
|
||||
"100000": "4.0.0 Beta 0",
|
||||
"100001": "4.0.0 Beta 1",
|
||||
"100002": "4.0.0 Beta 2",
|
||||
"100003": "4.0.0 Beta 3",
|
||||
"100004": "4.0.0 Beta 3a",
|
||||
"100005": "4.0.0 Beta 4",
|
||||
"100006": "4.0.0 Beta 4a",
|
||||
"100007": "4.0.0 Beta 4b",
|
||||
"100008": "4.0.0 Beta 5",
|
||||
"100009": "4.0.0 Beta 5a",
|
||||
"100010": "4.0.0 Beta 6",
|
||||
"100011": "4.0.0 Beta 7",
|
||||
"100012": "4.0.0 Beta 7a",
|
||||
"100013": "4.0.0 Beta 8",
|
||||
"100014": "4.0.0 RC1",
|
||||
"100015": "4.0.0 RC2",
|
||||
"100016": "4.0.0 RC3",
|
||||
"100017": "4.0.0 RC4",
|
||||
"100018": "4.0.0 RC5",
|
||||
"100019": "4.0.0 RC5a",
|
||||
"100020": "4.0.0 RC6",
|
||||
"100021": "4.0.0 RC7",
|
||||
"100022": "4.0.0 RC7a",
|
||||
"100023": "4.0.0",
|
||||
"100024": "4.0.1",
|
||||
"100025": "4.0.2",
|
||||
"100026": "4.0.3",
|
||||
"100027": "4.0.4",
|
||||
"100028": "4.0.5",
|
||||
"100029": "4.0.5.1",
|
||||
"100030": "4.0.6",
|
||||
"100031": "4.0.6.1",
|
||||
"100032": "4.0.7",
|
||||
"100033": "4.0.8",
|
||||
"100034": "4.0.8.1",
|
||||
"100035": "4.0.9",
|
||||
"100036": "4.0.9.1",
|
||||
"100037": "4.0.9.2",
|
||||
"100038": "4.0.10",
|
||||
"100039": "4.0.10.1",
|
||||
"100040": "4.0.10.2",
|
||||
"100041": "4.0.11",
|
||||
"100042": "4.0.12",
|
||||
"100043": "4.0.12.1",
|
||||
"100044": "4.0.13",
|
||||
"100045": "4.0.13.1"
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"todaysBirthdays":{"class":"\\IPS\\Widget\\StaticCache","restrict":[],"default_area":"","allow_reuse":false,"menu_style":"menu","embeddable":true},"upcomingEvents":{"class":"\\IPS\\Widget\\PermissionCache","restrict":[],"default_area":"","allow_reuse":false,"menu_style":"menu","embeddable":true},"recentReviews":{"class":"\\IPS\\Widget\\PermissionCache","restrict":[],"default_area":"","allow_reuse":false,"menu_style":"menu","embeddable":true}}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Announcements Extension: Calendar
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Calendar
|
||||
* @since 29 Apr 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\extensions\core\Announcements;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Announcements Extension
|
||||
*/
|
||||
class _Calendars
|
||||
{
|
||||
public static $idField = "id";
|
||||
|
||||
public static $controllers = array();
|
||||
|
||||
/**
|
||||
* Get Setting Field
|
||||
*
|
||||
* @param \IPS\core\Announcements\Announcement $announcement
|
||||
* @return Form element
|
||||
*/
|
||||
public function getSettingField( $announcement )
|
||||
{
|
||||
return new \IPS\Helpers\Form\Node( 'announce_calendars', ( $announcement AND $announcement->ids ) ? explode( ",", $announcement->ids ) : 0, FALSE, array( 'class' => 'IPS\calendar\Calendar', 'zeroVal' => 'any', 'multiple' => TRUE ), NULL, NULL, NULL, 'announce_calendars' );
|
||||
}
|
||||
}
|
||||
Whitespace-only changes.
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Content Router extension: Calendar
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Calendar
|
||||
* @since 7 Jan 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\extensions\core\ContentRouter;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Content Router extension: Calendar
|
||||
*/
|
||||
class _Calendar
|
||||
{
|
||||
/**
|
||||
* @brief Content Item Classes
|
||||
*/
|
||||
public $classes = array( 'IPS\calendar\Event' );
|
||||
}
|
||||
Whitespace-only changes.
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Create Menu Extension
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Calendar
|
||||
* @since 23 Dec 2013
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\extensions\core\CreateMenu;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Menu Extension
|
||||
*/
|
||||
class _Event
|
||||
{
|
||||
/**
|
||||
* Get Items
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getItems()
|
||||
{
|
||||
if ( \IPS\calendar\Calendar::canOnAny( 'add' ) )
|
||||
{
|
||||
return array( 'event' => array( 'link' => \IPS\Http\Url::internal( "app=calendar&module=calendar&controller=submit&_new=1", 'front', 'calendar_submit' ) ) );
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
}
|
||||
Whitespace-only changes.
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Editor Extension: Event text
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Calendar
|
||||
* @since 7 Jan 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\extensions\core\EditorLocations;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Editor Extension: Calendar event text and comments
|
||||
*/
|
||||
class _Calendar
|
||||
{
|
||||
/**
|
||||
* Can we use HTML in this editor?
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @return bool|null NULL will cause the default value (based on the member's permissions) to be used, and is recommended in most cases. A boolean value will override that.
|
||||
*/
|
||||
public function canUseHtml( $member )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can we use attachments in this editor?
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @return bool|null NULL will cause the default value (based on the member's permissions) to be used, and is recommended in most cases. A boolean value will override that.
|
||||
*/
|
||||
public function canAttach( $member )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Permission check for attachments
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @param int|null $id1 Primary ID
|
||||
* @param int|null $id2 Secondary ID
|
||||
* @param string|null $id3 Arbitrary data
|
||||
* @return bool
|
||||
*/
|
||||
public function attachmentPermissionCheck( $member, $id1, $id2, $id3 )
|
||||
{
|
||||
try
|
||||
{
|
||||
$event = \IPS\calendar\Event::load( $id1 );
|
||||
return $event->canView( $member );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attachment lookup
|
||||
*
|
||||
* @param int|null $id1 Primary ID
|
||||
* @param int|null $id2 Secondary ID
|
||||
* @param string|null $id3 Arbitrary data
|
||||
* @return \IPS\calendar\Event\Review|\IPS\calendar\Event\Comment|\IPS\calendar\Event
|
||||
* @throws \LogicException
|
||||
*/
|
||||
public function attachmentLookup( $id1, $id2, $id3 )
|
||||
{
|
||||
if ( $id2 )
|
||||
{
|
||||
if ( $id3 === 'review' )
|
||||
{
|
||||
return \IPS\calendar\Event\Review::load( $id2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
return \IPS\calendar\Event\Comment::load( $id2 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return \IPS\calendar\Event::load( $id1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
Whitespace-only changes.
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief File Storage Extension: Events
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Calendar
|
||||
* @since 13 Jan 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\extensions\core\FileStorage;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* File Storage Extension: Events
|
||||
*/
|
||||
class _Events
|
||||
{
|
||||
/**
|
||||
* Count stored files
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return \IPS\Db::i()->select( 'COUNT(*)', 'calendar_events', 'event_cover_photo IS NOT NULL' )->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Move stored files
|
||||
*
|
||||
* @param int $offset This will be sent starting with 0, increasing to get all files stored by this extension
|
||||
* @param int $storageConfiguration New storage configuration ID
|
||||
* @param int|NULL $oldConfiguration Old storage configuration ID
|
||||
* @throws \Underflowexception When file record doesn't exist. Indicating there are no more files to move
|
||||
* @return void
|
||||
*/
|
||||
public function move( $offset, $storageConfiguration, $oldConfiguration=NULL )
|
||||
{
|
||||
$record = \IPS\Db::i()->select( '*', 'calendar_events', 'event_cover_photo IS NOT NULL', 'event_id', array( $offset, 1 ) )->first();
|
||||
|
||||
try
|
||||
{
|
||||
$file = \IPS\File::get( $oldConfiguration ?: 'calendar_Events', $record['event_cover_photo'] )->move( $storageConfiguration );
|
||||
|
||||
if ( (string) $file != $record['event_cover_photo'] )
|
||||
{
|
||||
\IPS\Db::i()->update( 'calendar_events', array( 'event_cover_photo' => (string) $file ), array( 'event_id=?', $record['event_id'] ) );
|
||||
}
|
||||
}
|
||||
catch( \Exception $e )
|
||||
{
|
||||
/* Any issues are logged and the \IPS\Db::i()->update not run as the exception is thrown */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix all URLs
|
||||
*
|
||||
* @param int $offset This will be sent starting with 0, increasing to get all files stored by this extension
|
||||
* @return void
|
||||
*/
|
||||
public function fixUrls( $offset )
|
||||
{
|
||||
$record = \IPS\Db::i()->select( '*', 'calendar_events', 'event_cover_photo IS NOT NULL', 'event_id', array( $offset, 1 ) )->first();
|
||||
|
||||
if ( $new = \IPS\File::repairUrl( $record['event_cover_photo'] ) )
|
||||
{
|
||||
\IPS\Db::i()->update( 'calendar_events', array( 'event_cover_photo' => $new ), array( 'event_id=?', $record['event_id'] ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a file is valid
|
||||
*
|
||||
* @param \IPS\Http\Url $file The file to check
|
||||
* @return bool
|
||||
*/
|
||||
public function isValidFile( $file )
|
||||
{
|
||||
try
|
||||
{
|
||||
$record = \IPS\Db::i()->select( '*', 'calendar_events', array( 'event_cover_photo=?', (string) $file ) )->first();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all stored files
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
foreach( \IPS\Db::i()->select( '*', 'calendar_events', 'event_cover_photo IS NOT NULL' ) as $event )
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\File::get( 'calendar_Events', $event['event_cover_photo'] )->delete();
|
||||
}
|
||||
catch( \Exception $e ){}
|
||||
}
|
||||
}
|
||||
}
|
||||
Whitespace-only changes.
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Front Navigation Extension: Calendar
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Calendar
|
||||
* @since 23 Dec 2013
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\extensions\core\FrontNavigation;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Front Navigation Extension: Calendar
|
||||
*/
|
||||
class _Calendar
|
||||
{
|
||||
/**
|
||||
* Can access?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function canView()
|
||||
{
|
||||
return !\IPS\Application::load('calendar')->hide_tab and \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'calendar', 'calendar' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Title
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function title()
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('frontnavigation_calendar');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Link
|
||||
*
|
||||
* @return \IPS\Http\Url
|
||||
*/
|
||||
public function link()
|
||||
{
|
||||
return \IPS\Http\Url::internal( "app=calendar&module=calendar&controller=view", 'front', 'calendar' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Active?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function active()
|
||||
{
|
||||
return \IPS\Dispatcher::i()->application->directory === 'calendar';
|
||||
}
|
||||
|
||||
/**
|
||||
* Children
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function children()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
}
|
||||
Whitespace-only changes.
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief ACP Live Search Extension
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Calendar
|
||||
* @since 08 Apr 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\extensions\core\LiveSearch;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ACP Live Search Extension
|
||||
*/
|
||||
class _Calendars
|
||||
{
|
||||
/**
|
||||
* Check we have access
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function hasAccess()
|
||||
{
|
||||
/* Check Permissions */
|
||||
return \IPS\Member::loggedIn()->hasAcpRestriction( 'calendar', 'calendars', 'calendars_manage' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the search results
|
||||
*
|
||||
* @param string Search Term
|
||||
* @return array Array of results
|
||||
*/
|
||||
public function getResults( $searchTerm )
|
||||
{
|
||||
/* Init */
|
||||
$results = array();
|
||||
$searchTerm = mb_strtolower( $searchTerm );
|
||||
|
||||
/* Start with categories */
|
||||
if( $this->hasAccess() )
|
||||
{
|
||||
/* Perform the search */
|
||||
$calendars = \IPS\Db::i()->select(
|
||||
"*",
|
||||
'calendar_calendars',
|
||||
array( "word_custom LIKE CONCAT( '%', ?, '%' ) AND lang_id=?", $searchTerm, \IPS\Member::loggedIn()->language()->id ),
|
||||
NULL,
|
||||
NULL
|
||||
)->join(
|
||||
'core_sys_lang_words',
|
||||
"word_key=CONCAT( 'calendar_calendar_', cal_id )"
|
||||
);
|
||||
|
||||
/* Format results */
|
||||
foreach ( $calendars as $calendar )
|
||||
{
|
||||
$calendar = \IPS\calendar\Calendar::constructFromData( $calendar );
|
||||
|
||||
$results[] = \IPS\Theme::i()->getTemplate( 'livesearch', 'calendar', 'admin' )->calendar( $calendar );
|
||||
}
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
}
|
||||
Whitespace-only changes.
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Member Sync
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Calendar
|
||||
* @since 7 Jan 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\extensions\core\MemberSync;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Member Sync
|
||||
*/
|
||||
class _Calendar
|
||||
{
|
||||
/**
|
||||
* Member is merged with another member
|
||||
*
|
||||
* @param \IPS\Member $member Member being kept
|
||||
* @param \IPS\Member $member2 Member being removed
|
||||
* @return void
|
||||
*/
|
||||
public function onMerge( $member, $member2 )
|
||||
{
|
||||
\IPS\Db::i()->update( 'calendar_event_rsvp', array( 'rsvp_member_id' => $member->member_id ), array( 'rsvp_member_id=?', $member2->member_id ), array(), NULL, \IPS\Db::IGNORE );
|
||||
\IPS\Db::i()->update( 'calendar_import_feeds', array( 'feed_member_id' => $member->member_id ), array( 'feed_member_id=?', $member2->member_id ) );
|
||||
\IPS\Db::i()->update( 'calendar_events', array( 'event_approved_by' => $member->member_id ), array( 'event_approved_by=?', $member2->member_id ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Member is deleted
|
||||
*
|
||||
* @param $member \IPS\Member The member
|
||||
* @return void
|
||||
*/
|
||||
public function onDelete( $member )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'calendar_event_rsvp', array( 'rsvp_member_id=?', $member->member_id ) );
|
||||
\IPS\Db::i()->update( 'calendar_import_feeds', array( 'feed_member_id' => 0 ), array( 'feed_member_id=?', $member->member_id ) );
|
||||
\IPS\Db::i()->update( 'calendar_events', array( 'event_approved_by' => 0 ), array( 'event_approved_by=?', $member->member_id ) );
|
||||
}
|
||||
}
|
||||
Whitespace-only changes.
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Permissions
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage
|
||||
* @since 16 Apr 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\extensions\core\Permissions;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Permissions
|
||||
*/
|
||||
class _Permissions
|
||||
{
|
||||
/**
|
||||
* Get node classes
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getNodeClasses()
|
||||
{
|
||||
return array(
|
||||
'IPS\calendar\Calendar' => function( $current, $group )
|
||||
{
|
||||
$rows = array();
|
||||
|
||||
foreach( \IPS\calendar\Calendar::roots( NULL ) AS $calendar )
|
||||
{
|
||||
\IPS\calendar\Calendar::populatePermissionMatrix( $rows, $calendar, $group, $current );
|
||||
}
|
||||
|
||||
return $rows;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Calendars
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Calendar
|
||||
* @since 18 Dec 2013
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\modules\admin\calendars;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calendars
|
||||
*/
|
||||
class _calendars extends \IPS\Node\Controller
|
||||
{
|
||||
/**
|
||||
* Node Class
|
||||
*/
|
||||
protected $nodeClass = 'IPS\calendar\Calendar';
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'calendars_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add/Edit Form
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function form()
|
||||
{
|
||||
parent::form();
|
||||
|
||||
if ( \IPS\Request::i()->id )
|
||||
{
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('edit_calendar') . ': ' . \IPS\Output::i()->title;
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('add_calendar');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,407 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief iCalendar feed management
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Calendar
|
||||
* @since 19 Dec 2013
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\modules\admin\calendars;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* iCalendar feed management
|
||||
*/
|
||||
class _ical extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'calendar_feeds_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Manage
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
{
|
||||
/* Create the table */
|
||||
$table = new \IPS\Helpers\Table\Db( 'calendar_import_feeds', \IPS\Http\Url::internal( 'app=calendar&module=calendars&controller=ical' ) );
|
||||
$table->langPrefix = 'ical_';
|
||||
|
||||
/* Column stuff */
|
||||
$table->include = array( 'feed_title', 'feed_added', 'feed_lastupdated', 'feed_calendar_id' );
|
||||
$table->mainColumn = 'feed_title';
|
||||
|
||||
/* Sort stuff */
|
||||
$table->sortBy = $table->sortBy ?: 'feed_title';
|
||||
$table->sortDirection = $table->sortDirection ?: 'asc';
|
||||
|
||||
/* Search */
|
||||
$table->quickSearch = 'feed_title';
|
||||
$table->advancedSearch = array(
|
||||
'feed_title' => \IPS\Helpers\Table\SEARCH_CONTAINS_TEXT,
|
||||
'feed_url' => \IPS\Helpers\Table\SEARCH_CONTAINS_TEXT,
|
||||
'feed_calendar_id' => array( \IPS\Helpers\Table\SEARCH_NODE, array(
|
||||
'class' => '\IPS\calendar\Calendar',
|
||||
'zeroVal' => 'any'
|
||||
) ),
|
||||
'feed_added' => \IPS\Helpers\Table\SEARCH_DATE_RANGE,
|
||||
'feed_lastupdated' => \IPS\Helpers\Table\SEARCH_DATE_RANGE,
|
||||
);
|
||||
|
||||
/* Formatters */
|
||||
$table->parsers = array(
|
||||
'feed_added' => function( $val, $row )
|
||||
{
|
||||
$date = \IPS\DateTime::ts( $val );
|
||||
|
||||
return $date->localeDate() . ' ' . $date->localeTime( FALSE ) ;
|
||||
},
|
||||
'feed_lastupdated' => function( $val, $row )
|
||||
{
|
||||
$date = \IPS\DateTime::ts( $val );
|
||||
|
||||
return $date->localeDate() . ' ' . $date->localeTime( FALSE ) ;
|
||||
},
|
||||
'feed_calendar_id' => function( $val, $row )
|
||||
{
|
||||
try
|
||||
{
|
||||
return \IPS\calendar\Calendar::load( $val )->_title;
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
{
|
||||
return '';
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
/* Row buttons */
|
||||
$table->rowButtons = function( $row )
|
||||
{
|
||||
$return = array( 'update' => array(
|
||||
'icon' => 'refresh',
|
||||
'title' => 'update_ical',
|
||||
'link' => \IPS\Http\Url::internal( 'app=calendar&module=calendars&controller=ical&do=refresh&id=' ) . $row['feed_id'],
|
||||
'hotkey' => 'r'
|
||||
) );
|
||||
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'calendar', 'ical', 'calendar_feeds_edit' ) )
|
||||
{
|
||||
$return['edit'] = array(
|
||||
'icon' => 'pencil',
|
||||
'title' => 'edit',
|
||||
'link' => \IPS\Http\Url::internal( 'app=calendar&module=calendars&controller=ical&do=edit&id=' ) . $row['feed_id'],
|
||||
'hotkey' => 'e'
|
||||
);
|
||||
}
|
||||
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'calendar', 'ical', 'calendar_feeds_delete' ) )
|
||||
{
|
||||
$return['delete'] = array(
|
||||
'icon' => 'times-circle',
|
||||
'title' => 'delete',
|
||||
'link' => \IPS\Http\Url::internal( 'app=calendar&module=calendars&controller=ical&do=delete&id=' ) . $row['feed_id'],
|
||||
'data' => array( 'delete' => '' ),
|
||||
);
|
||||
}
|
||||
|
||||
return $return;
|
||||
};
|
||||
|
||||
/* Root buttons */
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'calendar', 'ical', 'calendar_feeds_add' ) )
|
||||
{
|
||||
$table->rootButtons = array(
|
||||
'add' => array(
|
||||
'icon' => 'plus',
|
||||
'title' => 'calendar_feeds_add',
|
||||
'link' => \IPS\Http\Url::internal( 'app=calendar&module=calendars&controller=ical&do=add' ),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('calendar_feeds_add') )
|
||||
),
|
||||
'upload' => array(
|
||||
'icon' => 'upload',
|
||||
'title' => 'calendar_feeds_upload',
|
||||
'link' => \IPS\Http\Url::internal( 'app=calendar&module=calendars&controller=ical&do=upload' ),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('calendar_feeds_upload') )
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/* Display */
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('ical_title');
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core' )->block( 'title', (string) $table );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add iCalendar feed to import
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
/* Check permissions */
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'calendar_feeds_add' );
|
||||
|
||||
/* Page title */
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('calendar_feeds_add');
|
||||
|
||||
/* Build the form */
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'feed_title', NULL, TRUE ) );
|
||||
$form->add( new \IPS\Helpers\Form\Url( 'feed_url', NULL, TRUE, array( 'allowedProtocols' => array( 'http', 'https', 'webcal', 'webcals' ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'feed_calendar_id', NULL, TRUE, array( 'class' => 'IPS\calendar\Calendar', 'url' => \IPS\Http\Url::internal( 'app=calendar&module=calendars&controller=ical&do=add', 'admin' ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Member( 'feed_member_id', NULL, TRUE, array() ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'feed_allow_rsvp', NULL, FALSE ) );
|
||||
|
||||
/* Handle submissions */
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
$values['feed_url'] = str_replace( '#', '%23', $values['feed_url'] ); // Google Calendar links include a # in the URL, which both cURL and sockets will ignore :\
|
||||
|
||||
try
|
||||
{
|
||||
\IPS\calendar\Icalendar\ICSParser::isValid( \IPS\Http\Url::external( str_replace( array( 'webcal://', 'webcals://' ), array( 'http://', 'https://' ), $values['feed_url'] ) )->request()->get() );
|
||||
}
|
||||
catch( \Exception $e )
|
||||
{
|
||||
$form->error = ( $e instanceof \UnexpectedValueException ) ? \IPS\Member::loggedIn()->language()->addToStack('ical_error_' . $e->getMessage()) : $e->getMessage();
|
||||
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('global', 'core')->block('calendar_feeds_add', $form, FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Insert the new record */
|
||||
$feed = new \IPS\calendar\Icalendar;
|
||||
$feed->title = $values['feed_title'];
|
||||
$feed->url = $values['feed_url'];
|
||||
$feed->calendar_id = $values['feed_calendar_id']->_id;
|
||||
$feed->member_id = $values['feed_member_id']->member_id;
|
||||
$feed->allow_rsvp = $values['feed_allow_rsvp'];
|
||||
$feed->save();
|
||||
|
||||
/* Admin log */
|
||||
\IPS\Session::i()->log( 'acplog__icalfeed_created', array( $feed->title => FALSE ) );
|
||||
|
||||
/* Grab the feed events */
|
||||
$feed->refresh();
|
||||
|
||||
/* Redirect */
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=calendar&module=calendars&controller=ical' ), 'saved' );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core' )->block( 'calendar_feeds_add', $form, FALSE );
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload iCalendar file
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function upload()
|
||||
{
|
||||
/* Check permissions */
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'calendar_feeds_add' );
|
||||
|
||||
/* Build the form */
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->add( new \IPS\Helpers\Form\Upload( 'feed_file', NULL, TRUE, array( 'temporary' => TRUE ) ) );
|
||||
|
||||
/* Init */
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'feed_calendar_id', NULL, TRUE, array(
|
||||
'url' => \IPS\Http\Url::internal( 'app=calendar&module=calendars&controller=ical&do=upload' ),
|
||||
'class' => 'IPS\calendar\Calendar',
|
||||
) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Member( 'feed_member_id', NULL, TRUE ) );
|
||||
|
||||
/* Handle submissions */
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
/* Import the events */
|
||||
try
|
||||
{
|
||||
$icsParser = new \IPS\calendar\Icalendar\ICSParser;
|
||||
$count = $icsParser->parse( \file_get_contents( $values['feed_file'] ), $values['feed_calendar_id'], $values['feed_member_id'] );
|
||||
}
|
||||
catch( \UnexpectedValueException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( $e->getMessage(), '1L169/4', 403, '' );
|
||||
}
|
||||
|
||||
/* Admin log */
|
||||
\IPS\Session::i()->log( 'acplog__ical_uploaded', array( $count['imported'] => FALSE, $count['skipped'] => FALSE ) );
|
||||
|
||||
/* Redirect */
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=calendar&module=calendars&controller=ical' ), 'feed_uploaded' );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('calendar_feeds_add');
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core' )->block( 'calendar_feeds_add', $form, FALSE );
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit iCalendar feed
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
/* Check permissions */
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'calendar_feeds_edit' );
|
||||
|
||||
/* Get existing feed */
|
||||
try
|
||||
{
|
||||
$feed = \IPS\calendar\Icalendar::load( \IPS\Request::i()->id );
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'feed_not_found', '2L169/2', 404, '' );
|
||||
}
|
||||
|
||||
/* Build the form */
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'feed_title', $feed->title, TRUE ) );
|
||||
$form->add( new \IPS\Helpers\Form\Url( 'feed_url', $feed->url, TRUE, array( 'allowedProtocols' => array( 'http', 'https', 'webcal', 'webcals' ) ) ) );
|
||||
|
||||
$options = array();
|
||||
|
||||
foreach( \IPS\calendar\Calendar::roots() as $calendar )
|
||||
{
|
||||
$options[ $calendar->id ] = $calendar->_title;
|
||||
}
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'feed_calendar_id', $feed->calendar_id, TRUE, array( 'options' => $options, 'parse' => 'normal' ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Member( 'feed_member_id', \IPS\Member::load( $feed->member_id )->name, TRUE ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'feed_allow_rsvp', $feed->allow_rsvp, FALSE ) );
|
||||
|
||||
/* Handle submissions */
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
$values['feed_url'] = str_replace( '#', '%23', $values['feed_url'] ); // Google Calendar links include a # in the URL, which both cURL and sockets will ignore :\
|
||||
|
||||
try
|
||||
{
|
||||
\IPS\calendar\Icalendar\ICSParser::isValid( \IPS\Http\Url::external( str_replace( array( 'webcal://', 'webcals://' ), array( 'http://', 'https://' ), $values['feed_url'] ) )->request()->get() );
|
||||
}
|
||||
catch( \Exception $e )
|
||||
{
|
||||
$form->error = ( $e instanceof \UnexpectedValueException ) ? \IPS\Member::loggedIn()->language()->addToStack('ical_error_' . $e->getMessage()) : $e->getMessage();
|
||||
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('global', 'core')->block('calendar_feeds_add', $form, FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Insert the new record */
|
||||
$feed->title = $values['feed_title'];
|
||||
$feed->url = $values['feed_url'];
|
||||
$feed->calendar_id = $values['feed_calendar_id'];
|
||||
$feed->member_id = $values['feed_member_id']->member_id;
|
||||
$feed->allow_rsvp = $values['feed_allow_rsvp'];
|
||||
$feed->save();
|
||||
|
||||
/* Admin log */
|
||||
\IPS\Session::i()->log( 'acplog__icalfeed_updated', array( $feed->title => FALSE ) );
|
||||
|
||||
/* Grab the feed events */
|
||||
$feed->refresh();
|
||||
|
||||
/* Redirect */
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=calendar&module=calendars&controller=ical' ), 'saved' );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->title = $feed->title;
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core' )->block( $feed->title, $form, FALSE );
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete iCalendar feed
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
/* Check permissions */
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'calendar_feeds_delete' );
|
||||
|
||||
/* Build the form */
|
||||
$form = new \IPS\Helpers\Form( 'form', 'delete' );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'keep_events', TRUE, FALSE ) );
|
||||
|
||||
/* Handle submissions */
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
/* Delete the feed */
|
||||
try
|
||||
{
|
||||
$feed = \IPS\calendar\Icalendar::load( \IPS\Request::i()->id );
|
||||
|
||||
if( !$values['keep_events'] )
|
||||
{
|
||||
$feed->deleteFeedEvents();
|
||||
}
|
||||
|
||||
$feed->delete();
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'feed_not_found', '2L169/3', 404, '' );
|
||||
}
|
||||
|
||||
/* Admin log */
|
||||
\IPS\Session::i()->log( 'acplog__icalfeed_deleted', array( $feed->title => FALSE ) );
|
||||
|
||||
/* Redirect */
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=calendar&module=calendars&controller=ical' ), 'deleted' );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('delete');
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core' )->block( 'delete', $form, FALSE );
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh iCalendar feed
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function refresh()
|
||||
{
|
||||
/* Refresh the feed */
|
||||
try
|
||||
{
|
||||
$count = \IPS\calendar\Icalendar::load( \IPS\Request::i()->id )->refresh();
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'feed_not_found', '2L169/1', 404, '' );
|
||||
}
|
||||
catch( \UnexpectedValueException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'ical_error_' . $e->getMessage(), '4L169/5', 500, '' );
|
||||
}
|
||||
|
||||
/* Admin log */
|
||||
\IPS\Session::i()->log( 'acplog__icalfeed_refreshed', array( $count['imported'] => FALSE, $count['skipped'] => FALSE ) );
|
||||
|
||||
/* Redirect */
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=calendar&module=calendars&controller=ical' ), 'feed_refreshed' );
|
||||
}
|
||||
}
|
||||
Whitespace-only changes.
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Settings
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Calendar
|
||||
* @since 18 Dec 2013
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\modules\admin\calendars;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Settings
|
||||
*/
|
||||
class _settings extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'settings_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Manage Settings
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
{
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('settings');
|
||||
|
||||
$form = new \IPS\Helpers\Form;
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'calendar_default_view', \IPS\Settings::i()->calendar_default_view, TRUE, array( 'options' => array( 'month' => 'cal_df_month', 'week' => 'cal_df_week', 'day' => 'cal_df_day', 'stream' => 'cal_df_stream' ) ) ) );
|
||||
|
||||
$options = array_combine( array_keys( \IPS\calendar\Date::$dateFormats ), array_map( function( $val ){ return "calendar_df_" . $val; }, array_keys( \IPS\calendar\Date::$dateFormats ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'calendar_date_format', \IPS\Settings::i()->calendar_date_format, TRUE, array( 'options' => $options, 'unlimited' => '-1', 'unlimitedLang' => "calendar_custom_df", 'unlimitedToggles' => array( 'calendar_date_format_custom' ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'calendar_date_format_custom', \IPS\Settings::i()->calendar_date_format_custom, FALSE, array(), NULL, NULL, NULL, 'calendar_date_format_custom' ) );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'show_bday_calendar', \IPS\Settings::i()->show_bday_calendar ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'ipb_calendar_mon', \IPS\Settings::i()->ipb_calendar_mon ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'calendar_rss_feed', \IPS\Settings::i()->calendar_rss_feed, FALSE, array( 'togglesOn' => array( 'calendar_rss_feed_days' ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'calendar_rss_feed_days', \IPS\Settings::i()->calendar_rss_feed_days, FALSE, array( 'unlimited' => -1 ), NULL, NULL, NULL, 'calendar_rss_feed_days' ) );
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
if( $values['calendar_date_format'] == -1 AND !$values['calendar_date_format_custom'] )
|
||||
{
|
||||
$form->error = \IPS\Member::loggedIn()->language()->addToStack('calendar_no_date_format');
|
||||
\IPS\Output::i()->output = $form;
|
||||
return;
|
||||
}
|
||||
|
||||
$form->saveAsSettings();
|
||||
|
||||
/* Clear guest page caches */
|
||||
\IPS\Data\Cache::i()->clearAll();
|
||||
|
||||
\IPS\Session::i()->log( 'acplogs__calendar_settings' );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->output = $form;
|
||||
}
|
||||
}
|
||||
Whitespace-only changes.
@@ -0,0 +1,242 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief View Event Controller
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Calendar
|
||||
* @since 14 Jan 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\modules\front\calendar;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* View Event Controller
|
||||
*/
|
||||
class _event extends \IPS\Content\Controller
|
||||
{
|
||||
/**
|
||||
* [Content\Controller] Class
|
||||
*/
|
||||
protected static $contentModel = 'IPS\calendar\Event';
|
||||
|
||||
/**
|
||||
* Init
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
\IPS\calendar\Calendar::addCss();
|
||||
|
||||
try
|
||||
{
|
||||
$this->event = \IPS\calendar\Event::load( \IPS\Request::i()->id );
|
||||
|
||||
if ( !$this->event->canView( \IPS\Member::loggedIn() ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2L179/1', 404, '' );
|
||||
}
|
||||
|
||||
if ( $this->event->cover_photo )
|
||||
{
|
||||
\IPS\Output::i()->metaTags['og:image'] = \IPS\File::get( 'calendar_Events', $this->event->cover_photo )->url;
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2L179/2', 404, '' );
|
||||
}
|
||||
|
||||
/* We want to present the same breadcrumb structure as the rest of the calendar */
|
||||
\IPS\Output::i()->breadcrumb['module'] = array( \IPS\Http\Url::internal( "app=calendar&module=calendar&controller=view", 'front', 'calendar' ), \IPS\Member::loggedIn()->language()->addToStack('module__calendar_calendar') );
|
||||
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* View Event
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
{
|
||||
/* Init */
|
||||
parent::manage();
|
||||
|
||||
/* Fetch RSVP data and pass to template */
|
||||
try
|
||||
{
|
||||
$attendees = $this->event->attendees();
|
||||
}
|
||||
catch( \BadMethodCallException $e )
|
||||
{
|
||||
$attendees = array( 0 => array(), 1 => array(), 2 => array() );
|
||||
}
|
||||
|
||||
/* Sort out comments and reviews */
|
||||
$tabs = $this->event->commentReviewTabs();
|
||||
$_tabs = array_keys( $tabs );
|
||||
$tab = isset( \IPS\Request::i()->tab ) ? \IPS\Request::i()->tab : array_shift( $_tabs );
|
||||
$activeTabContents = $this->event->commentReviews( $tab );
|
||||
|
||||
if ( count( $tabs ) > 1 )
|
||||
{
|
||||
$commentsAndReviews = count( $tabs ) ? \IPS\Theme::i()->getTemplate( 'global', 'core' )->tabs( $tabs, $tab, $activeTabContents, $this->event->url(), 'tab', FALSE, TRUE ) : NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
$commentsAndReviews = $activeTabContents;
|
||||
}
|
||||
|
||||
if ( \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->output = $activeTabContents;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Online User Location */
|
||||
\IPS\Session::i()->setLocation( $this->event->url(), $this->event->onlineListPermissions(), 'loc_calendar_viewing_event', array( $this->event->title => FALSE ) );
|
||||
|
||||
/* Display */
|
||||
//\IPS\Output::i()->sidebar['contextual'] = \IPS\Theme::i()->getTemplate( 'view' )->eventSidebar( $this->event, $attendees );
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'view' )->view( $this->event, $commentsAndReviews, $attendees );
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a small version of the calendar as a "hovercard"
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function hovercard()
|
||||
{
|
||||
/* Figure out our date object */
|
||||
$date = NULL;
|
||||
|
||||
if( \IPS\Request::i()->sd )
|
||||
{
|
||||
$dateBits = explode( '-', \IPS\Request::i()->sd );
|
||||
|
||||
if( count( $dateBits ) === 3 )
|
||||
{
|
||||
$date = \IPS\calendar\Date::getDate( $dateBits[0], $dateBits[1], $dateBits[2] );
|
||||
}
|
||||
}
|
||||
|
||||
if( $date === NULL )
|
||||
{
|
||||
$date = \IPS\calendar\Date::getDate();
|
||||
}
|
||||
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'view' )->eventBlock( $this->event, $date );
|
||||
}
|
||||
|
||||
/**
|
||||
* Download file - Show terms and file selection
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function download()
|
||||
{
|
||||
$feed = new \IPS\calendar\Icalendar\ICSParser;
|
||||
$feed->addEvent( $this->event );
|
||||
|
||||
$ics = $feed->buildICalendarFeed( $this->event->container() );
|
||||
|
||||
\IPS\Output::i()->sendHeader( "Content-type: text/calendar; charset=UTF-8" );
|
||||
\IPS\Output::i()->sendHeader( 'Content-Disposition: inline; filename=calendarEvents.ics' );
|
||||
|
||||
\IPS\Member::loggedIn()->language()->parseOutputForDisplay( $ics );
|
||||
print $ics;
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Download RSVP attendee list
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function downloadRsvp()
|
||||
{
|
||||
$output = \IPS\Theme::i()->getTemplate( 'view' )->attendees( $this->event );
|
||||
\IPS\Member::loggedIn()->language()->parseOutputForDisplay( $output );
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->blankTemplate( $output ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* RSVP for event
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function rsvp()
|
||||
{
|
||||
if( !$this->event->can('rsvp') )
|
||||
{
|
||||
\IPS\Output::i()->error( 'rsvp_error', '2L179/3', 403, '' );
|
||||
}
|
||||
|
||||
/* We delete either way at this point, because even if we select a different action we have to remove any existing RSVP preference */
|
||||
\IPS\Db::i()->delete( 'calendar_event_rsvp', array( 'rsvp_event_id=? AND rsvp_member_id=?', $this->event->id, \IPS\Member::loggedIn()->member_id ) );
|
||||
|
||||
if( \IPS\Request::i()->action == 'leave' )
|
||||
{
|
||||
$message = 'rsvp_not_going';
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Figure out the action */
|
||||
switch( \IPS\Request::i()->action )
|
||||
{
|
||||
case 'yes':
|
||||
$_go = \IPS\calendar\Event::RSVP_YES;
|
||||
break;
|
||||
|
||||
case 'maybe':
|
||||
$_go = \IPS\calendar\Event::RSVP_MAYBE;
|
||||
break;
|
||||
|
||||
case 'no':
|
||||
default:
|
||||
\IPS\Request::i()->action = 'no';
|
||||
$_go = \IPS\calendar\Event::RSVP_NO;
|
||||
break;
|
||||
}
|
||||
|
||||
/* If there is a limit applied there are more rules */
|
||||
if( $this->event->rsvp_limit > 0 )
|
||||
{
|
||||
/* We do not accept "maybe" in this case */
|
||||
if( $_go === \IPS\calendar\Event::RSVP_MAYBE )
|
||||
{
|
||||
\IPS\Output::i()->error( 'rsvp_limit_nomaybe', '3L179/4', 403, '' );
|
||||
}
|
||||
|
||||
/* And we have to actually check the limit */
|
||||
if( count( $this->event->attendees[1] ) >= $this->event->rsvp_limit )
|
||||
{
|
||||
\IPS\Output::i()->error( 'rsvp_limit_reached', '3L179/5', 403, '' );
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Db::i()->insert( 'calendar_event_rsvp', array(
|
||||
'rsvp_event_id' => $this->event->id,
|
||||
'rsvp_member_id' => \IPS\Member::loggedIn()->member_id,
|
||||
'rsvp_date' => time(),
|
||||
'rsvp_response' => (int) $_go
|
||||
) );
|
||||
|
||||
$message = 'rsvp_selection_' . \IPS\Request::i()->action;
|
||||
}
|
||||
|
||||
\IPS\Output::i()->redirect( $this->event->url(), $message );
|
||||
}
|
||||
}
|
||||
Whitespace-only changes.
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Submit Event Controller
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Calendar
|
||||
* @since 8 Jan 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\modules\front\calendar;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit Event Controller
|
||||
*/
|
||||
class _submit extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
/**
|
||||
* Submit Event
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
{
|
||||
/* Display */
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'submit_event' );
|
||||
\IPS\Output::i()->sidebar['enabled'] = FALSE;
|
||||
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->addToStack( 'add_cal_event_header' ) );
|
||||
|
||||
$calendar = NULL;
|
||||
if ( isset( \IPS\Request::i()->calendar ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$calendar = \IPS\calendar\Calendar::loadAndCheckPerms( \IPS\Request::i()->calendar );
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
}
|
||||
$form = \IPS\calendar\Event::create( $calendar );
|
||||
|
||||
if ( \IPS\calendar\Event::moderateNewItems( \IPS\Member::loggedIn() ) )
|
||||
{
|
||||
$form = \IPS\Theme::i()->getTemplate( 'forms', 'core' )->modQueueMessage( \IPS\Member::loggedIn()->warnings( 5, NULL, 'mq' ), \IPS\Member::loggedIn()->mod_posts ) . $form;
|
||||
}
|
||||
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'front_submit.js', 'calendar', 'front' ) );
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'submit' )->submitPage( $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'submit', 'calendar' ) ), 'submitForm' ) ) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,616 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Calendar Views
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Calendar
|
||||
* @since 23 Dec 2013
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\modules\front\calendar;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calendar Views
|
||||
*/
|
||||
class _view extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
/**
|
||||
* @brief Calendar we are viewing
|
||||
*/
|
||||
protected $_calendar = NULL;
|
||||
|
||||
/**
|
||||
* @brief Date object for the current day
|
||||
*/
|
||||
protected $_today = NULL;
|
||||
|
||||
/**
|
||||
* Route
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
{
|
||||
/* We aren't showing a sidebar in Calendar */
|
||||
\IPS\Output::i()->sidebar['enabled'] = FALSE;
|
||||
\IPS\calendar\Calendar::addCss();
|
||||
|
||||
/* Show the RSS link */
|
||||
if ( \IPS\Settings::i()->calendar_rss_feed )
|
||||
{
|
||||
$urls = $this->_downloadLinks();
|
||||
\IPS\Output::i()->rssFeeds['calendar_rss_title'] = $urls['rss'];
|
||||
}
|
||||
|
||||
/* Is there only one calendar? */
|
||||
$roots = \IPS\calendar\Calendar::roots();
|
||||
if ( count( $roots ) == 1 AND !isset( \IPS\Request::i()->id ) )
|
||||
{
|
||||
$roots = array_shift( $roots );
|
||||
$this->_calendar = \IPS\calendar\Calendar::loadAndCheckPerms( $roots->_id );
|
||||
}
|
||||
|
||||
/* Are we viewing a specific calendar only? */
|
||||
if( \IPS\Request::i()->id )
|
||||
{
|
||||
try
|
||||
{
|
||||
$this->_calendar = \IPS\calendar\Calendar::loadAndCheckPerms( \IPS\Request::i()->id );
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2L182/2', 404, '' );
|
||||
}
|
||||
}
|
||||
|
||||
if( $this->_calendar !== NULL AND $this->_calendar->_id )
|
||||
{
|
||||
\IPS\Output::i()->contextualSearchOptions[ \IPS\Member::loggedIn()->language()->addToStack( 'search_contextual_item', FALSE, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->addToStack( 'calendar' ) ) ) ) ] = array( 'type' => 'calendar_event', 'nodes' => $this->_calendar->_id );
|
||||
}
|
||||
|
||||
$this->_today = \IPS\calendar\Date::getDate();
|
||||
|
||||
/* Get the date jumper - do this first in case we need to redirect */
|
||||
$jump = $this->_jump();
|
||||
|
||||
/* If there is a view requested in the URL, use it */
|
||||
if( isset( \IPS\Request::i()->view ) )
|
||||
{
|
||||
if( method_exists( $this, '_view' . ucwords( \IPS\Request::i()->view ) ) )
|
||||
{
|
||||
$method = "_view" . ucwords( \IPS\Request::i()->view );
|
||||
$this->$method( $jump );
|
||||
}
|
||||
else
|
||||
{
|
||||
$method = "_view" . ucwords( \IPS\Settings::i()->calendar_default_view );
|
||||
$this->$method( $jump );
|
||||
}
|
||||
}
|
||||
/* Otherwise use ACP default preference */
|
||||
else
|
||||
{
|
||||
$method = "_view" . ucwords( \IPS\Settings::i()->calendar_default_view );
|
||||
$this->$method( $jump, iterator_to_array( \IPS\calendar\Event::featured( 4, '_rand' ) ) );
|
||||
}
|
||||
|
||||
/* Online User Location */
|
||||
if ($this->_calendar)
|
||||
{
|
||||
\IPS\Session::i()->setLocation( $this->_calendar->url(), array(), 'loc_calendar_viewing_calendar', array( "calendar_calendar_{$this->_calendar->id}" => TRUE ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Session::i()->setLocation( \IPS\Http\Url::internal( 'app=calendar', 'front', 'view' ), array(), 'loc_calendar_viewing_calendar_all' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show month view
|
||||
*
|
||||
* @param \IPS\Helpers\Form $jump Calendar jump
|
||||
* @param array $featured Featured events (only populated for the ACP-specified default view)
|
||||
* @return void
|
||||
*/
|
||||
protected function _viewMonth( $jump, $featured=array() )
|
||||
{
|
||||
/* Get the calendars we can view */
|
||||
$calendars = \IPS\calendar\Calendar::roots();
|
||||
|
||||
/* Get the month data */
|
||||
$day = NULL;
|
||||
|
||||
if( ( !\IPS\Request::i()->y OR \IPS\Request::i()->y == $this->_today->year ) AND ( !\IPS\Request::i()->m OR \IPS\Request::i()->m == $this->_today->mon ) )
|
||||
{
|
||||
$day = $this->_today->mday;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$date = \IPS\calendar\Date::getDate( \IPS\Request::i()->y ?: NULL, \IPS\Request::i()->m ?: NULL, $day );
|
||||
}
|
||||
catch( \Exception $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'error_bad_date', '3L182/3', 403, '' );
|
||||
}
|
||||
|
||||
/* Get birthdays */
|
||||
$birthdays = ( $this->_calendar === NULL OR count( $calendars ) == 1 ) ? $date->getBirthdays() : array();
|
||||
|
||||
/* Get the events within this range */
|
||||
$events = \IPS\calendar\Event::retrieveEvents(
|
||||
\IPS\calendar\Date::getDate( $date->firstDayOfMonth('year'), $date->firstDayOfMonth('mon'), $date->firstDayOfMonth('mday') ),
|
||||
\IPS\calendar\Date::getDate( $date->lastDayOfMonth('year'), $date->lastDayOfMonth('mon'), $date->lastDayOfMonth('mday'), 23, 59, 59 ),
|
||||
$this->_calendar
|
||||
);
|
||||
|
||||
/* If there are no events, tell search engines not to index the page but do NOT tell them not to follow links */
|
||||
if( count($events) === 0 )
|
||||
{
|
||||
\IPS\Output::i()->metaTags['robots'] = 'noindex';
|
||||
}
|
||||
|
||||
/* Display */
|
||||
/* @see http://community.invisionpower.com/4bugtrack/follow-button-adds-meta-title-and-link-tags-r3209/ */
|
||||
$output = \IPS\Theme::i()->getTemplate( 'browse' )->calendarMonth( $calendars, $date, $featured, $birthdays, $events, $this->_today, $this->_calendar, $jump );
|
||||
|
||||
if( \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( $output, 200, 'text/html', \IPS\Output::i()->httpHeaders );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'front_browse.js', 'calendar', 'front' ) );
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('cal_month_title', FALSE, array( 'sprintf' => array( $date->monthName, $date->year ) ) );
|
||||
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'browse' )->calendarWrapper(
|
||||
$output,
|
||||
$calendars,
|
||||
$this->_calendar,
|
||||
$jump,
|
||||
$date,
|
||||
$featured,
|
||||
$this->_downloadLinks()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show week view
|
||||
*
|
||||
* @param \IPS\Helpers\Form $jump Calendar jump
|
||||
* @param array $featured Featured events (only populated for the ACP-specified default view)
|
||||
* @return void
|
||||
*/
|
||||
protected function _viewWeek( $jump, $featured=array() )
|
||||
{
|
||||
/* Get the calendars we can view */
|
||||
$calendars = \IPS\calendar\Calendar::roots();
|
||||
|
||||
/* Get the month data */
|
||||
$week = \IPS\Request::i()->w ? explode( '-', \IPS\Request::i()->w ) : NULL;
|
||||
try
|
||||
{
|
||||
$date = \IPS\calendar\Date::getDate( isset( $week[0] ) ? $week[0] : NULL, isset( $week[1] ) ? $week[1] : NULL, isset( $week[2] ) ? $week[2] : NULL );
|
||||
}
|
||||
catch( \Exception $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'error_bad_date', '3L182/4', 403, '' );
|
||||
}
|
||||
|
||||
$nextWeek = $date->adjust( '+1 week' );
|
||||
$lastWeek = $date->adjust( '-1 week' );
|
||||
|
||||
/* Get the days of the week - we do this in PHP to help keep template a little cleaner */
|
||||
$days = array();
|
||||
|
||||
for( $i = 0; $i < 7; $i++ )
|
||||
{
|
||||
$days[] = \IPS\calendar\Date::getDate( $date->firstDayOfWeek('year'), $date->firstDayOfWeek('mon'), $date->firstDayOfWeek('mday') )->adjust( $i . ' days' );
|
||||
}
|
||||
|
||||
/* Get birthdays */
|
||||
$birthdays = ( $this->_calendar === NULL OR count( $calendars ) == 1 ) ? $date->getBirthdays() : array();
|
||||
|
||||
/* Get the events within this range */
|
||||
$events = \IPS\calendar\Event::retrieveEvents(
|
||||
\IPS\calendar\Date::getDate( $date->firstDayOfWeek('year'), $date->firstDayOfWeek('mon'), $date->firstDayOfWeek('mday') ),
|
||||
\IPS\calendar\Date::getDate( $date->lastDayOfWeek('year'), $date->lastDayOfWeek('mon'), $date->lastDayOfWeek('mday'), 23, 59, 59 ),
|
||||
$this->_calendar
|
||||
);
|
||||
|
||||
/* If there are no events, tell search engines not to index the page but do NOT tell them not to follow links */
|
||||
if( count($events) === 0 )
|
||||
{
|
||||
\IPS\Output::i()->metaTags['robots'] = 'noindex';
|
||||
}
|
||||
|
||||
/* Display */
|
||||
/* @see http://community.invisionpower.com/4bugtrack/follow-button-adds-meta-title-and-link-tags-r3209/ */
|
||||
$output = \IPS\Theme::i()->getTemplate( 'browse' )->calendarWeek( $calendars, $date, $featured, $birthdays, $events, $nextWeek, $lastWeek, $days, $this->_today, $this->_calendar, $jump );
|
||||
|
||||
if( \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( $output, 200, 'text/html', \IPS\Output::i()->httpHeaders );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('cal_week_title', FALSE, array( 'sprintf' => array(
|
||||
$date->firstDayOfWeek('monthNameShort'),
|
||||
$date->firstDayOfWeek('mday'),
|
||||
$date->firstDayOfWeek('year'),
|
||||
$date->lastDayOfWeek('monthNameShort'),
|
||||
$date->lastDayOfWeek('mday'),
|
||||
$date->lastDayOfWeek('year')
|
||||
) ) );
|
||||
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'browse' )->calendarWrapper(
|
||||
$output,
|
||||
$calendars,
|
||||
$this->_calendar,
|
||||
$jump,
|
||||
$date,
|
||||
$featured,
|
||||
$this->_downloadLinks()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show day view
|
||||
*
|
||||
* @param \IPS\Helpers\Form $jump Calendar jump
|
||||
* @param array $featured Featured events (only populated for the ACP-specified default view)
|
||||
* @return void
|
||||
*/
|
||||
protected function _viewDay( $jump, $featured=array() )
|
||||
{
|
||||
/* Get the calendars we can view */
|
||||
$calendars = \IPS\calendar\Calendar::roots();
|
||||
|
||||
/* Get the month data */
|
||||
try
|
||||
{
|
||||
$date = \IPS\calendar\Date::getDate( \IPS\Request::i()->y ?: NULL, \IPS\Request::i()->m ?: NULL, \IPS\Request::i()->d ?: NULL );
|
||||
}
|
||||
catch( \Exception $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'error_bad_date', '3L182/5', 403, '' );
|
||||
}
|
||||
|
||||
$tomorrow = $date->adjust( '+1 day' );
|
||||
$yesterday = $date->adjust( '-1 day' );
|
||||
|
||||
if( $date->mon == 2 AND $date->year == 2014 AND $date->mday == 12 AND \IPS\Request::i()->event == 'easter' )
|
||||
{
|
||||
\IPS\Output::i()->sendHeader( base64_decode( "Q29udGVudC10eXBlOiBpbWFnZS9qcGVn" ) );
|
||||
\IPS\Output::i()->sendHeader( base64_decode( "Q29udGVudC1EaXNwb3NpdGlvbjogaW5saW5lOyBmaWxlbmFtZT1lYXN0ZXIuanBn" ) );
|
||||
|
||||
print $this->_event();
|
||||
exit;
|
||||
}
|
||||
|
||||
/* Get birthdays */
|
||||
$birthdays = ( $this->_calendar === NULL OR count( $calendars ) == 1 ) ? $date->getBirthdays( TRUE ) : array();
|
||||
|
||||
/* Get the events within this range */
|
||||
$events = \IPS\calendar\Event::retrieveEvents( $date, $date, $this->_calendar );
|
||||
|
||||
$dayEvents = array_fill( 0, 23, array() );
|
||||
$dayEvents['allDay'] = array();
|
||||
$dayEvents['count'] = 0;
|
||||
|
||||
foreach( $events as $day => $_events )
|
||||
{
|
||||
foreach( $_events as $type => $event )
|
||||
{
|
||||
foreach( $event as $_event )
|
||||
{
|
||||
$dayEvents['count']++;
|
||||
|
||||
if( $_event->all_day )
|
||||
{
|
||||
$dayEvents['allDay'][ $_event->id ] = $_event;
|
||||
}
|
||||
else
|
||||
{
|
||||
$dayEvents[ $_event->_start_date->hours ][ $_event->id ] = $_event;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If there are no events, tell search engines not to index the page but do NOT tell them not to follow links */
|
||||
if( $dayEvents['count'] === 0 )
|
||||
{
|
||||
\IPS\Output::i()->metaTags['robots'] = 'noindex';
|
||||
}
|
||||
|
||||
/* Display */
|
||||
/* @see http://community.invisionpower.com/4bugtrack/follow-button-adds-meta-title-and-link-tags-r3209/ */
|
||||
$output = \IPS\Theme::i()->getTemplate( 'browse' )->calendarDay( $calendars, $date, $featured, $birthdays, $dayEvents, $tomorrow, $yesterday, $this->_today, $this->_calendar, $jump );
|
||||
|
||||
if( \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( $output, 200, 'text/html', \IPS\Output::i()->httpHeaders );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('cal_month_day', FALSE, array( 'sprintf' => array( $date->monthName, $date->mday, $date->year ) ) );
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'browse' )->calendarWrapper(
|
||||
$output,
|
||||
$calendars,
|
||||
$this->_calendar,
|
||||
$jump,
|
||||
$date,
|
||||
$featured,
|
||||
$this->_downloadLinks()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stream per page
|
||||
*/
|
||||
public $streamPerPage = 50;
|
||||
|
||||
/**
|
||||
* Show stream view
|
||||
*
|
||||
* @param \IPS\Helpers\Form $jump Calendar jump
|
||||
* @param array $featured Featured events (only populated for the ACP-specified default view)
|
||||
* @return void
|
||||
*/
|
||||
protected function _viewStream( $jump, $featured=array() )
|
||||
{
|
||||
/* Get the calendars we can view */
|
||||
$calendars = \IPS\calendar\Calendar::roots();
|
||||
|
||||
/* Get the month data */
|
||||
$day = NULL;
|
||||
|
||||
if( ( !\IPS\Request::i()->y OR \IPS\Request::i()->y == $this->_today->year ) AND ( !\IPS\Request::i()->m OR \IPS\Request::i()->m == $this->_today->mon ) )
|
||||
{
|
||||
$day = $this->_today->mday;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$date = \IPS\calendar\Date::getDate( \IPS\Request::i()->y ?: NULL, \IPS\Request::i()->m ?: NULL, $day );
|
||||
}
|
||||
catch( \InvalidArgumentException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'error_bad_date', '3L182/6', 403, '' );
|
||||
}
|
||||
|
||||
/* Get the events within this range */
|
||||
$events = \IPS\calendar\Event::retrieveEvents(
|
||||
\IPS\calendar\Date::getDate( $date->firstDayOfMonth('year'), $date->firstDayOfMonth('mon'), $date->firstDayOfMonth('mday') ),
|
||||
\IPS\calendar\Date::getDate( $date->lastDayOfMonth('year'), $date->lastDayOfMonth('mon'), $date->lastDayOfMonth('mday'), 23, 59, 59 ),
|
||||
$this->_calendar,
|
||||
NULL,
|
||||
FALSE
|
||||
);
|
||||
|
||||
/* Pagination */
|
||||
$pagination = array(
|
||||
'page' => ( isset( \IPS\Request::i()->page ) ) ? \IPS\Request::i()->page : 1,
|
||||
'pages' => ( count( $events ) > 0 ) ? ceil( count( $events ) / $this->streamPerPage ) : 1,
|
||||
'limit' => $this->streamPerPage
|
||||
);
|
||||
|
||||
if( $pagination['page'] < 1 )
|
||||
{
|
||||
$pagination['page'] = 1;
|
||||
}
|
||||
|
||||
/* If there are no events, tell search engines not to index the page but do NOT tell them not to follow links */
|
||||
if( count($events) === 0 )
|
||||
{
|
||||
\IPS\Output::i()->metaTags['robots'] = 'noindex';
|
||||
}
|
||||
else
|
||||
{
|
||||
$events = array_slice( $events, ( $pagination['page'] - 1 ) * $this->streamPerPage, $this->streamPerPage );
|
||||
}
|
||||
|
||||
/* Display */
|
||||
/* @see http://community.invisionpower.com/4bugtrack/follow-button-adds-meta-title-and-link-tags-r3209/ */
|
||||
$output = \IPS\Theme::i()->getTemplate( 'browse' )->calendarStream( $calendars, $date, $featured, $events, $this->_calendar, $jump, $pagination );
|
||||
|
||||
if( \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( $output, 200, 'text/html', \IPS\Output::i()->httpHeaders );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'cal_month_stream_title', FALSE, array( 'sprintf' => array( $date->monthName, $date->year ) ) );
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'browse' )->calendarWrapper(
|
||||
$output,
|
||||
$calendars,
|
||||
$this->_calendar,
|
||||
$jump,
|
||||
$date,
|
||||
$featured,
|
||||
$this->_downloadLinks()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate keyed links for RSS/iCal download
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function _downloadLinks()
|
||||
{
|
||||
$downloadLinks = array( 'iCalCalendar' => '', 'iCalAll' => \IPS\Http\Url::internal( 'app=calendar&module=calendar&controller=view&do=download', 'front', 'calendar_icaldownload' ), 'rss' => \IPS\Http\Url::internal( 'app=calendar&module=calendar&controller=view&do=rss', 'front', 'calendar_rss' ) );
|
||||
|
||||
if( $this->_calendar )
|
||||
{
|
||||
$downloadLinks['iCalCalendar'] = \IPS\Http\Url::internal( 'app=calendar&module=calendar&controller=view&id=' . $this->_calendar->id . '&do=download', 'front', 'calendar_calicaldownload', $this->_calendar->title_seo );
|
||||
}
|
||||
|
||||
if ( \IPS\Member::loggedIn()->member_id )
|
||||
{
|
||||
if ( !\IPS\Member::loggedIn()->members_pass_salt )
|
||||
{
|
||||
\IPS\Member::loggedIn()->members_pass_salt = \IPS\Member::loggedIn()->generateSalt();
|
||||
\IPS\Member::loggedIn()->save();
|
||||
}
|
||||
|
||||
$key = md5( ( \IPS\Member::loggedIn()->members_pass_hash ?: \IPS\Member::loggedIn()->email ) . \IPS\Member::loggedIn()->members_pass_salt );
|
||||
|
||||
if( $this->_calendar )
|
||||
{
|
||||
$downloadLinks['iCalCalendar'] = $downloadLinks['iCalCalendar']->setQueryString( array( 'member' => \IPS\Member::loggedIn()->member_id , 'key' => $key ) );
|
||||
}
|
||||
$downloadLinks['iCalAll'] = $downloadLinks['iCalAll']->setQueryString( array( 'member' => \IPS\Member::loggedIn()->member_id , 'key' => $key ) );
|
||||
$downloadLinks['rss'] = $downloadLinks['rss']->setQueryString( array( 'member' => \IPS\Member::loggedIn()->member_id , 'key' => $key ) );
|
||||
}
|
||||
|
||||
return $downloadLinks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return jump form and redirect if appropriate
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function _jump()
|
||||
{
|
||||
/* Build the form */
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->add( new \IPS\Helpers\Form\Date( 'jump_to', $this->_today, TRUE, array(), NULL, NULL, NULL, 'jump_to' ) );
|
||||
|
||||
if( $values = $form->values() )
|
||||
{
|
||||
\IPS\Request::i()->view = 'day';
|
||||
|
||||
if( \IPS\Request::i()->goto )
|
||||
{
|
||||
\IPS\Request::i()->y = null;
|
||||
\IPS\Request::i()->m = null;
|
||||
\IPS\Request::i()->d = null;
|
||||
\IPS\Request::i()->w = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Request::i()->y = $values['jump_to']->format('Y');
|
||||
\IPS\Request::i()->m = $values['jump_to']->format('m');
|
||||
\IPS\Request::i()->d = $values['jump_to']->format('j');
|
||||
}
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an event
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function _event()
|
||||
{
|
||||
return base64_decode( "/9j/4AAQSkZJRgABAgAAZABkAAD/7AARRHVja3kAAQAEAAAAFAAA/+4ADkFkb2JlAGTAAAAAAf/bAIQAEg4ODhAOFRAQFR4UERQeIxoVFRojIhkZGhkZIiceIyEhIx4nJy4wMzAuJz4+QUE+PkFBQUFBQUFBQUFBQUFBQQEUFBQW" .
|
||||
"GRYbFxcbGhYaFhohGh0dGiExISEkISExPi0nJycnLT44OzMzMzs4QUE+PkFBQUFBQUFBQUFBQUFBQUFB/8AAEQgBgwK8AwEiAAIRAQMRAf/EAJsAAQEAAwEBAQAAAAAAAAAAAAABAgMGBAUHAQEBAQEBAAAAAAAAAAAAAAAAAQMCBBAAAgEBBgIGCAQGAw" .
|
||||
"EAAwEAAAERAiExQVEDBBITYXGBkTIFodEiQlIzFBWxYiNTwXKSQyQ0ggYW8OHxwmMRAQABAgMHAgYCAwEAAAAAAAABEQJREhMhMUFhcTIDUhSBkSJCM0NygvBiBKH/2gAMAwEAAhEDEQA/AOPAM9OGmLYrKzNGMCDckiwjvT5pnaIZYN3ChCGnzMzTBYZt" .
|
||||
"sFg0uZna7SzUZlsGkZ2KrrVxVq6ixZYsJYNKF1JZc/VzZHr6jvbFghE0YXUli66nmSWZwiwi6SZ5a7RabIQhF0kzy1wxDNsIQoGkZ5aoYhm2EIQ0jPLVDLws22CwaUGaWrhYirM2iwulBnlrh5oQ8zZYBowZ5a4eaHC8zYC6MJnlr4WOB5myUJQ0oM8tfA" .
|
||||
"8xwdJtlCwulBnlq4OkvAs/QZzYVsaVqZ5a+BZjlrMzkSXRtM8sOX0l5azLImwujameU5azY5azZZHEXRtTPcx5a6Ry10l4i8Q0rcDPdix5dPSXl09I4hxWl0rcDNdicujJjl0E4rBxF0rcEzXYsuXQTl0ZDiJxTA0rcDNdivLom4nLoyHEOMulbgma7E5d" .
|
||||
"Pw+kq06PhROIcQ07cCs4qqKPhReGj4UY8Q4rBp24FZxZcNHwocNPwox4hxFyW4FZZOlZLuHCsqe4xm8cRMluBWWcLJdxVGSNfEWZdhcsYG1sdTkcVWZnr7evRdCq9+lVUtZM9VPlG8dHFw2tSqZtg5pZyXa8LdWLEv4jdutrVt6aHW/arU8OR5eIsRbMJt" .
|
||||
"bLcxLzNfEExlgZpuLy34muQ2KRgM+0WZsw4ipzcKQM8BcfX8s8lr3K5mtNOnFh4/MPL9XZ6kVKaH4ajmLrJuy7Kuss73ksEqDXIk6pDlnYVxKNfEG7grZKFhrkSBskSYJy4R9jT8j16tutSUqqrk3gc3XRbv4kRM7nypHEfTfkW7i+lvrPm6+hq6Fbo1FF" .
|
||||
"Qi62d0wtJhJDZqkSVDWfsM8cno1H7LPOZz32/F1wlsdxdJ3kZKGY+PfDu5vk+jt9rRTt3utdex7lPxM+XxHQaSW78o5em51dO104m1+yI67XMPBTvdPiirRo4Loi00alNOrrOnb0vhb9lGOlp0vV4NVvTzbR9vb7Cjb1atCq4tWrTmh3EmYtN75FWy3NNL" .
|
||||
"r4ZpV7VsGGlt9XVngVivbsR7/Ka9ajduiqeBytRO437+il7Odtbp06lXFw9dgzTWn/AKU2VfK1dvraTSrpam7pNtHl+6rUqjCWfQ2mtQvL1Vufc1FwT12m3ToelvK90q+LatN1NOb1dBM07SkPKtKPLNTipXHTVEo8lGw3NalU4SlNsdR9DQrpr2OvV7vM" .
|
||||
"T7JL5jVq7fWWto0Sq0uCu+LMBEzWY5j5GpoamnSq6rE3HSa5Jq6lddbqr8Tcswk0ojZIkwkSWg2SSTCS8QGciTDiEiis5LJrkSEZyXiNcsSVWxMSa5EsDZJJMJZJCNkiTXIko2SJNaYlgbJsHEa5YlgbJsJxGEkko2cQ4jVIkqUZyOI1yJYKNk2DiNckkq" .
|
||||
"UbOIcRrliQUbOInEayyCjORxGABRnxDiMAKlGfFaJMAKlGciTWJBRskcRgBUozkcRgBVaNnFYxxGvAEKNnEVVWmsAdNToae509rqakwtNqzHgZ6t3vadtSnwt6kpJT7J8nSevX5bpVbdvmaVbVl8M1UaG/19xRVrqppNS3gYZaztnZFdjroy861XVuKE7H" .
|
||||
"TQp7bT5fEerzOvj3mo8nw/02HjNbdlsdHPFlxBVGBUdCyOIxBBnxH0/KFs6ten6httuKaUrJ6T5R6dlXTRudOupxSmm2c3Vm2Vje7Dfeb6OwdOnwuptSkrEkXX3O13Gwevq0zpNT0nN+d7rR3G4oq0quJKmGz0Vb7bfaFocf6seE88eLZbMVrM7XWbe+Ru" .
|
||||
"KtHm1cmeXhN5p4gyHpcLxFdVxiALxDiIArJVNHvW+31WgtJcXCrU1J89H09DzjV0dJadOnQ0lEtWnF0btmYhr09XfutQ65npPd55qTpaCqjmx7Roq893MRTRRT0pHzdbX1Nat16jmpnMWzN0TMRFFmYpRr4hJCGiJW7DUbKrjWZT3wvBsZjTeZ1XswpvMf" .
|
||||
"Hvh3czN233Ott9RV6VTpqRpKeuldjN9N+bamo069LTdXxum0+hqbbX3OtTWtV010pRXYqX/LBzhnzdVXVOzpOZsw2FXQ6u23dVM8+lKp8LhJPtgw23l+40VUtPXS4nEXp9Z8DmV3cT7yrV1FdU+8mScY+RV917bj3mjo7rWVVLlqleyrDZpVbvQ3T0lopb" .
|
||||
"duKlHsunOTnXXU3LbnM2PdbmqngepU6cpE+OeRV9qvS49fX09pqqjRTXs4WmPDu9PSq06NeVQm4cYdZ8NV1K5tF5lebtLk5hXVVVU6qnNTvZiAd0ApCwKABAFAAAooCwxDFAGIhjhZaIAvC8hwvIUWrEGXC8icNWRaIgLwvIcLyFCqAvDVNw4KshQqgMuC" .
|
||||
"rIcFWQoVYkM+CrInLryLRKwwBly64uHKryLQrDAGfLqyHLqyFCsMGQ2cuuLhyq8hRKw1gz5deReVUKSVhrBs5VQ5VQpJWMWsGzlVDlVQKSVhrBt5NU4E5VQpJWGsGzlVF5NRKSVjFrBs5VQ5NRaSVhrBt5LzHJ6SUkzQ1A28npHJ6RSTNDUU2cp5l5TzLS" .
|
||||
"TNDUU2cp5jlxiKJmgo1tXTUUVulPBMy+o1379XeRafSXl2kyxgZmttu13kg28tZl5azLQzQ0QVXm3loctTeSi5oaYEG7lLMctChmhqCNvLpHAhQrDWINvAshwIUKtMCDdwIcCIVaRBv5dI4KciUMzRBYN3BTkThWQoVaoLBt4UOFZAq0wINvCshwrIFWmC" .
|
||||
"G50onCiFXnruNZ6NRLhNBlP5LXddkttXifWY6a9pmVXiZNLxsx8fdHV3fxbuFDhWRmkbtLbaupRXXQpp0/F2nt2Q89Xn4VkOFZHufl25VdFLptrp4qeo8vC0IpJta+EQj06O01dZVuhSqFxPqNXC8i7EqwjoHCZ8LvgcLxLQqw4bRBvo2+pXp1alK9mi1m" .
|
||||
"Doqi4bCrCCxDMuG83bbbV7jWWlR4nd2DZBV5oRYPXr7SrRVtVNTbupcmOlttTUVbpXgXE0NlKjzqm24cMGx0tOHlieh7HXW3e4ajTlQNkFXkdN4i89r8u1lovVmm7i4J9qMzzU0OqpUq+qxIRSd3A2tcJqcg1ee/U8t1NPSdfFTU1HFTS5dPWNTy3Xo0nq" .
|
||||
"OHCTqpT9qnrFbcTa8MfgImk9dez1dPRp16o4arFmXT2OrXtqtdQqaVjey1jHkbXki/qCVq6jOLV0oxS8JaJVi1Yhiukya9ldYS8JaJVilcTDqZlF3WWLH1loVR3rrI1Z2mxpWGMWPoYoVSPER2szi/qI1ZZkKFUaUtdAi7qM4t7CRcWiVYRZ2iIgyj2e0R" .
|
||||
"YusUKseG/rDVr6jJrxFi3sFCrBKzsJFq6jYlZ2EStQKtcWdpYtZlw2dpXTa0KFWEXldNqM48Q4bUCrXFk9Ialdpnw2dpWrLMwVYcN5IuNjpUskRAKtcSyxeZpWki8FWMXFRnBIsIVYQVq0yixiAVYRYEjKLAKFUgkWmcSxAKsYIlYZwSLCFWMFgyStCQWr" .
|
||||
"GBCMsQkQqxLwoygRBBhAaMsBAVgMDKCQCqBosAKhSoQQSBBlAwIMRBkIIMYEFgBWMEM4ICrFohkSCDRreE8+B6dbwnmwMp/Jb0d/bLbV4mNL5parzHT+aefx746tb+PR6kfT8prpWvVpVeHVpdNt2aPnJGScWq898xWKPLE0l0NW4oejrVNp1aTdFP8ALV" .
|
||||
"YY10bZ6UOlcuE5hfifAmq1TfeXiriJcZGelhLrO6Sh8L3FMULRWm+XUotsPLqamjXVXoumhULTTTSU8UHxeOuIliXngWPFxqmfk+9qUbd7dKmlOjhTTsv67zLW09u6KHWqaaFVT7Li7oaOfmqImwrqbiWXSn1Gfk6CvidOtTVwU6TSVDUXSXX5GnoVVRTU" .
|
||||
"9N0um6GsYRz3FVETYOJuLewaW3eZ+T7G70tCnS4dGlOvdNOn8tOXeefy5Lb+YUqtr2ZTc2XHjq3GpU6G6vAop6INfE25bttOosmkxM70zbaw+tt9xo6u6iqimm/haxfae2l0KutUular03e1fNhzivWZkm7LST4q8SL3t8xu0uN0vW4Xx8PoLo6ifl+vTV" .
|
||||
"VbNPCmeB2q12lSu6UdZNkRzqldr6tOk9LaOqmqmvV1Kbap8NOSR4K9tXpamkqmk60n1TmalNlryMnVW2qqm6nN7ZYtmOO8m6vB9XVoo2+jwaVSrmHq1tqXGCM9bU0lVr69OoqqdajhopV8nxsUFNhzp81zcnro1KPoqdOpy1qTGMQe76rY6mnq0p1U/p8N" .
|
||||
"NFkdh8ZJ9zKl7RZ8cTx41TNLCPCErKehmceF9JIs7TRywav6wlYuhmyyX1ksjtKMHYu0rvqM3c10khe0NiMWrOqCunxFs4X1oyi/pAwi3sEez2Gapc9hVRVFhRrx7CJWUm3gqlWYWkVFVljvyCNcWOcyRYus28uuHY7xy6+G535DYMHT4glb2Gzgq9qx9x" .
|
||||
"OGqV7LuyGwa0vwKl4TNU1T4XdkFS1w2Ndg2DCLH1hr2mZxVwt8LvyDpfFc8MAMI8RUrUZ8LmqxxGQVNUqxjYNbXs9oiV2mx6dUXYjl1RdiNg1tXki43cuqXYOTVNLgmwq0RaWLGbeVVxWL0jl1w7Mc0KwVaoh9giztNr0658PpJy64jh9KA1NWdpYt7DPg" .
|
||||
"r4bsc0Xgrl2fgBriURqw2PTri78A9OuLgNcWiGbeXVkOXVBFq1RmDbyqhyn0CsFWrElhu5TzRHpO+URWqBBs5dWaHLeaAwtKZcurNDl1JYEWrBokGzlub0VabvkhVqgG3lrMctTf6ArShBt5f5vQOWs/QQa4CRs5dt/oHL6fQBrtEG3l9PoHL6fQRWqBBt" .
|
||||
"5fSOBEGoG3gXSOWpxCtMEg3cum+0OinpINEBo3cFPSY8FPSB49fwnn909e5ppVFk3nk90yn8trSOyWx3l0fnoe8i6ajcI8/j3x1a37p6PdTw2WIyVNvhPb5dpUVVVOpS6YjtPqcNOR7ZvpNKPJTm5/htXsl4X8PoOhVNOSMlTTkianIpzc5wuPCu4Kl2ey" .
|
||||
"u46ThU3IcKyQ1OUGXm5yHK9ldw4X8K7jpOGnJDhWSLqcoMvOXOcNTfhXcFRV8KvyOidKyQ4VkNTlBl5y57gqjwLuHKrnwruOh4VkThWQ1Jwgy85fBWlVZ7GORVoajuom3I+7w2np29K4biXeWYitIW2yJnfLm1tdW7lu/IyW017I0nZfZgdWqVkb9OlZWw" .
|
||||
"ZT/wBM+mGmjGMuO+i3Nn6VWfhwL9Hubf0ar7PZO1hWWEhWE91d6YNGMZcZ9JuJ+VV/SFs91+1VfPhdx2cIRaPdXemDRjGXG/SbrDSrvssYW03jqnl1x/KzsklYVD3V2EGjbjLjVtN3+3Xfky/Rbxpxp1X2WHYIqsge5uwg0bcZch9Fu7f06u4LYbxr5dVr" .
|
||||
"ssOvw7QsB7q/CDRtxlyX27eOf03bcPtm9lvluHYdasB6x7q/CDQt5uT+1b2I5TtuL9s3sv8ATeWB1d0E9Y91fhaaFvNyv2vfftuy+1BeV75KOW+9HV5ge6vwg0bOblPte+TX6bsvtRPte+/bed6uOsavGK6h7nycjQs5uT+17639N23Woq8q3zUPTdrzR1" .
|
||||
"UWILAe58nI0LOblvtW9t9jovL9p3s+C5ZnUesuY9z5ORoWc3LLyjeq3gwzzMl5PvLFwqFbedPgSLewe58nI0LObmfs+8iISnpL9m3jbuXadLkFex7nycjRswc19m3drstsvL9l3edNnSdHFnaV3snufJjBo2YOb+ybuImm228fZN27JpzvZ0mQxQ9x5MYN" .
|
||||
"GzBzX2Td2uaLell+ybuy2izpZ0cWdoeI9x5MTRswc2vI93MzQ8b2Psm8zoc9LOkwxF0E9x5MV0bMHN/ZN3Lc0d7L9j3UX0950WZese48mJo2YOd+xbmxOqnvL9j1/ipOhi0mA9x5MV0bMHwPsWq4TrpH2LUdjrR9/EImv5MTSswfA+xV2/qLuKvIaruau4" .
|
||||
"+7FhcbBr+TE0rMHwfsNT/uruH2Kr91f0n3SRYTW8nqXTswfDfkNUfNX9P/AOSfYav3vQfdgYk1vJ6jTswfC+wP91dxfsP/APrYug+5iQa3k9Urp24PifYceb6CryGjHVfcfawBNXyeqTJbhD4q8i0v3KmZfY9Be/VafXeBMRq3+qVyW4Q+X9l2yxqL9l2q" .
|
||||
"V9R9MNE1L/VJktwh837Ptcn3lXlG0m5959DEDUv9Urltwh4PtOzjw29YflOz+D0s9+IxJnv9UmWMIeFeU7KZ4PSx9q2XwelnuITPdjK5Ywh4X5Xsvg9LH2vZ/B6We4QM92MmWMHh+2bP4PSy/bdpHg9J7ATNdjJSMHi+3bT4C/b9p+2j1kGa7GVpGDy/Qb" .
|
||||
"X4EfM808v0tPT5umuGL0fcZ4PNX/h19a/Etl92aNvFzdEUnY4/d+BdZ5PdPZvF7PaeP3T1T+W3oxjsltV6Cs10RXov9+nrR57N8dW1+74Oh8tVtb6EfTwPmeWPxI+oj1Xd0vLG6FSKkEZRJypALBQIIMoJDAxgRYZRYCjGItIZNYgqMYR6durDzwenb3M4" .
|
||||
"v7Xdm96EjdpmFJsovPPLdp1tSvnaejQ+F1JtvqJXr1aFKWo+Ny7VZYbdTRprdNVqrpfs1LA11bOipy6nxWpucyRQavrEtZ40OhOldNRl9bTNFKpdVVU2fymz6PSlO2UlSn1GS2tCqVVrqplT/MNg0Vb3i029Oltqni/lJTvVRpUPUtbpTqdmJt+i01TwqU" .
|
||||
"rnDvRHsdF+y5iEo6i7Bs0tZ6jhUtJWSeWjVrarqqqq9l1Ky6Ee2jTVCcYsxWjQqKqFdU3PaBpe64aG1S2qEqm3kyU7mmaqlLVlj/MbuRp8NVOFSSfURbbTShSrreobB56tzqc/T4VY1VKmywzW94qZppvXE0zbRttKlqpXqUv+V5PpNKIUqLL8C7Bq191q" .
|
||||
"VadT0lZTEvGT1p+z3GqrbaVU3w4lTfBviE0SQzI/4FvYasAP+BMipW9hMgJh2hYMru7Qrl1hB3PrGL6g3eLJ7AEWdgm1dQVzGKAkXGSvZMEVXsDF49ZcWIvZYtdmAEvgO8sXCPaAxw6hFrLFnaMWBLIJZYZRYSLgqXoWSIsLiAx7CYFxJZBAxIizeRAIsG" .
|
||||
"IwGLAEwMsDF3ACYlxGAExJJcRgFCMuKZCCdAxGIiZAgd5UhFvUBBBcCYEExLiEAqAuAAhCkAQQpCKgKRoDE8Hmv+nV1r8T6B8/zb/Uq6Wjqzujq5u7ZchvPD2nk9w9W8uXWeb3D1z+WOjCOyVV6Mn8+mc0YrAzq+bR1o89u9tfuff8tf6jXQfWR8jy1frf" .
|
||||
"8WfYR6r+55Y3QyRt09Omqltu1KxGpG2ipUt9Kg4mtNjqN7KiihpS3xPBFp0pqiS6ddCpyqeIorppcxNt/Qc7drrZsFo0uHS7HKZK6KVSqqbVc5M1q00wkrE5faY1108PDSrJkRU2Gnp01J8VmC6xRoqqmqfEri83hSVKuzLzlMpWtyx9RsYV6VNOkn72Jo" .
|
||||
"rspcHpr1OJOx32Gk6trxczTgw0uBr2q0meql6NCfDqJnlelQ7YN220NNuqUc3xNK1d2zFdzfo6nFXCfEsz10YmrToooiFBuSvMJapVXFfBi7ZMVrUNNtxbFvQNSiqqpVUxKWJgtDNq1P0jYNnNpbaTlq8x59Lo4occUE5NjtvSQ5EaNWnN9s+kbAp3FNTi" .
|
||||
"IznoM3qUeLiUGt7aluq2+mCfTQ1VNqc/wLsGdGvp1UzKVtxlzKE2pUmujbcKqUzIe2XE3PTA2DZzaLXKglOtQ08LYMadvFU8VqtWRhVtW59q9y+0bEbnqUW24x2mOvq8uI95xaR6P6nFglZ1mT03Xwuq+m0bAWqo9q/oJp69Ncq5y13Er0aarZjBko0FS1" .
|
||||
"bKpba7S7Bs42tRUw4avMVqN1cDUSnFpm6U6qXkjGnSqpmrilucCC11umGlPaavqboViSdXRJsq0+OmlN2q+y8xegm5bvhNZwXYK9T9TlxY1Mkp1lVqcvC+eozq006+J4KO8wW3opr5imyyOsbBHrRU1Fk8Mlp1anXVS6YhSukr0U63VbnHSZ8tOpu2aqYY" .
|
||||
"Gla7Slr2W+GcTOjVdVVKasqTaItvTN7dKtS6TOjSSdLluLENg11azWoqfdmG+lmv6qpU1tr2lVFKN70NNp2WtzOJittpqp2P/wDY2DZQ3VRxPG0yx7BTTw08KwuLiQTINWlyGKAxwLmCvEDFXDIruJkFTAuIwEQwJiMCuZJkQTMIttpAGQzEXDMAlYTAsQ" .
|
||||
"AITApHcAI7kXAZEVMSFxAExGAGABEKR3ALYIUk4ECETAuACnQRlIAwBSASQVkZBCMoCsT53m/+r2n0WfM84f8Ajr+b+B1Z3W9XN3bLkt5geb3D0b29Hn9w9c/lhj+uVVyMtSyulmKuRdTxUnmt3trtzofLPmT+Vn2EfI8us1EfXR6797yW7mSMkiIyRwoZ" .
|
||||
"EKFIBQBiDLrBUSCQZSQCM3ba9mo37fE5v7Xdnc9VKNiMVdBksDzy2URcMiRcRQpErSqAikwkRcPdKDxA9Q9QDHsDxEqwvqAnqGPYJ/ATcETBl9RFEXhYdRVW2UFJFFlpQJkXAllglWgIvGD6y2WkzAZhXqSzb2FTtQGKKsAnaVOxBEw7S4iVD6xNsAR4lV" .
|
||||
"/YG7xKkCZFyJN1pampVoGLuLF5MCypYUwJbKFjQV4EtgsWixCwCYgWWgCfgMy4MkqGQMUMy5EmwAToK2SbgIzTry1Sk8brpN02MlSpqSTUgeKiupVrhmEnKdptq3D4qYxie03cNKiEHRTMx1EotXnetWlMXtrqglWtW6X7sUzOZ6WqYhrsJw0NXXBdjzV8" .
|
||||
"VWnoxLbvtjAtWpXptUJXRKvvPTFMdVxi6aW04npJQq83P1m6bvabXcSrUrbSudn4nrinK4kU5Cg1aerVXXwxbT4jD2XXW9R3OzqN9NCpbiZbllhNy1aB5q9apPhpuu9BjTrai4VhCvxk9TSytELIUHnWrqXvGYXUYPUrmipubG2sj19gSWRCrzU6uo6uHp" .
|
||||
"Vp6UVJLAIAQpAJYQpAIz5fnP8Ar0/zfwPqM+V538ij+b+B14++OqXdsuS3l9Jo9w3bzxI1e4eufyx/nBj+uUVyMtX3WYq7tMtTw0nmt3trtz7/AJe/1aen1H2j4nl883S6fUfcPXfv+DyW7viqRlASKjh0qRQikESEFKUSBBRAEJBlYGEYm/b4mmDdt/E+" .
|
||||
"ol/bLqzuetKWZJEStMzzy3SF6RC9JWrxmQSFkElKMmT1lEhBJF9Yi0Aku9ESVhlkRT3ASLEWPwGAQQIlcVYCwAlaFgLAlcVTKwRb2j1h3gSA1eX1h4hEhSIVpYfoGYCLewKHBcewKbAIr8Bgiq8ZAIvI7ytO0uIEi8eouYxAxwRXehFwdjQEYi8esRawI7" .
|
||||
"oEOUXAYqYAxwK1aILiwqQrSRcXMmKAmDDVgwDIJiMCkwAMO8YlxAxBbYGIGIm0rRGRUwBYHWBiVgYgQQCgY4gqGAGIKCKgGBQIQrIAIZEIIQoxAxPk+d/Io/m/gfWZ8fzv5VC6Tvx98dUv7ZcnvPEjV7hs3njRh7h6Z/NH+cGX62Cu7TPU8FJgru0z1Plo" .
|
||||
"89u9rdufd8s8el/9gfeSPgeW+LT6kdAj1374/i8kcerJFIrjJHCiMosCKRQCCwBAVIQBAWCOxSUR2G3bv231GqjirdisPRpaddL4mrDm6YpMOrYmtXpTMlaaVq+0k1BvX8DCWwXMvqIQTsKJvDxANCLRmCiRcWPxHrACPxCwED1gMh24iPxGYCLgVk9ZQ9" .
|
||||
"Yd4zDVoEzGZXiMwJiMyrAuPYBMUCrAesBiRXXFx7S+sIkXhpleIYCLyRaixeIuAkWIrVpMEVgYxZ2iL5FgzkB7oi1DAivCmF4xdoi4WSwJmJFloxAmF4YsgoEd5jgjLG8NWIghJtKxaBLAxFhQMSODPExwIqAsWhgSCYlV5MwARYsIBAUNEVCRYXAASAGA" .
|
||||
"JAEAAyFBBCFZAqHxvPH7NHafZPieee51M78XfDi/tlye7+Yuoxj2DLd/M7CR7B6Z/NH+cGf656NauNlfy0a1czZX8o88b2s7n2vLnbp9SOiRzXl1q0utfidKj13fb/F5I4/yZIyRiZpGbpSpEV5kAARUQQQigonURqUZADTymnNNTXUbNPTqqqh6jgyNmh" .
|
||||
"4iXbpdWzNYbNPbU0vilvrPSsCIyRhLZFgVYFIQSCv+AACABgUS20uZC+oBiPWA8QIV4jMNAGTMRYIvKGYZcSMBmX1BgAsBiMi4gRYFiwLAesIYjDtKTAoZhlDIpmRF9QyAmXWV3oYIPACYPrDmWBiwI7iWyVxwgCYIZgkdQB4iLewNXh3kEwKTArAmZLS5" .
|
||||
"iywCJDMDMCZDMsWogExDuFgaCpiGXEjyIEWkKQAQowAlwxAxAjDKyYkUxIygCABgQFIRUABBD4Xnv9vqf8D7rPg+fX6fUzXxd8OPJ2y5XdfN7BHsE3PzTL3Df90OPs+DSrmbKvlGtXM2P5LMI3tJ3Pr+WOzS61+J0yOX8ru030r8TqVceq7db/F5Y33fyZ" .
|
||||
"IyRikZJHCskWwhlBBIKIAUEFEASCQZQTEqJBs0fH2GDRs0fGiXbpW3fD1oyRgjO0wluswMyQXMgSJdgi4FBYEmwW+kQAT/AAASsEOwBIuAcgMwPULbCiYFzCTEAPUMAkMAhAxQSLFwESuLFxI6S4oAI/EkXFi8CtEixhr/AOksXgIvI0WCNXAZR+BErhAx" .
|
||||
"QCLA1cIDVoVMO0ZiLH1iLwDuJiLIJCkBghnYMhYAmy4O8kKBCALATaIuEJEB4jImYhSATJ0iBAFxIItIwAwJBYCmJMQLCATAQIsAEEIYgMQItJBAYECAoQQIAEiwsEgAMACCEZSBUZ8Dz7xUdTPvs57z1/qUroNPD3w48nbLltx802e4a9f5rNv9s2/b8X" .
|
||||
"H2T0edXM2/2maVibl8pmMb2k7n0/LLKdNnVU3I5Py1/p0nW0+FHqu7bf4vLG+7qzRkjGDJIzVYMgUKQCjECDAoAnSQywAGLM9LxoxMtP5itE7pW3fD1ozRiusyRg2B6i2DtIIgMAUGMS5jECAABAFgWADILAZAokFi4pMgiZFiwLAuAVAsAsBIDAqwJgVY" .
|
||||
"BDAZj1jMKWjMrGDCHqIx6hkFX1EyGPYMrAgUmAxCnrJmMO0PGwA7h6iO64AXBE7xbYTsAuBGMLi52EEtsAxQ7AILZGA7ACJaVRAYExI7i4jAKnQAAIQoIJgRllQAIALJAQQogggACoMCkYAhSYkEBYIFQAAQ5zz1/rpflR0bOb89/wBj/iv4mvh74ceTtc" .
|
||||
"xrfOZt9w063zmbvcNP2/Fz9k9HmWJtp+XUakbaPlsyje7nc+h5c/00dhQvZXUcd5a/Y7TsqPCn0Hpntt6PN913VkjJESM0cKIyEFIIigoEBUAJBGjIhRrVbqqapRvo061VxHnq0bZpbp6jKnTrdSXG4Yu3bHVtHrerDho3Uu481O2Uy6mz0pQYS1VYAAgh" .
|
||||
"QUogYGAAhQAzCCvAEtL6wIKGJEWABCoDEAgQuABjIZjAIvrJmBmFVh4h3DMIYkdyLiRhVx7CLAoyCJNhSYFxCp6w8R6yMA7hAYAZEKQAMxgLAGJLy2DECYAYAgQQqIAgmBcyBUtgYliwQBjgCggxDvKMQIEgEAIyggxGBSBQhSACFIBSCBBBCGRAqM5nz3" .
|
||||
"/ZX8qOmOY89/2exGvg72fk7XM6vzn1m73DTX819Zv93sNP2/2T7J6PLSbtPwM0q83aXgfUYu53Pb5b4f8AkdnpeCnqOM8su/5HZ6PyqepHqnst6PN913VsSMoCMjNVSLBEZICQWAUgkAogohMSwGBC0eNEMqF7aE7ljfD00mZijKTGWwUBkAFwIBEMBcCh" .
|
||||
"iAUAiAoEYYYgA8B6xAhFAYiFaHeABPWUAPWAEMykzKwo7iZlasIBSPAsEwQRSZCBFwAYokFaAmHaXMkLIPEKMYhqwReAyFyEXMkAVXIPEgggYjEBZAIsJaW4mYC0jkoeAEYKSbgoQoAxDDBAJBSAMCFAEF4AVAUhBAUAQlxQBCGTIQQhQ5CsWct5253T6D" .
|
||||
"qWcp5y/wDKr/8AsDbwd/wZ+Ttc5V819Z6MOw87+a+s9HqOv2f2Pt+Dy03m7S8L6jTTebtG59RlxdcHr8t//o7TbW6NH8qOK8ux6ztdr8jT/lR6Z7LXm+65vRkiIyOFVSUIywIqFEFAxtEFAEJaZEKiFp8S6yMtPiXWJ3LG+HqMoMUZIxlsqkBAgWi0YAoW" .
|
||||
"i2SsmJAtFoBRLYLaGAFpLQUolsBzaXAAS0MBgBmXMACMAINO0WlJjIDAPEYABaMEBgFAsCkyAhXeA7wiEzKXMCORJWQBkR3FeAwCpkUYB2EC2SFtkgEtsFtpSALRaABFIclDAlpLSu8BWLBQQQlpQBCFAAhQFQYlBBiCgDEQUAQhQRUIVgDFnI+cv/L1Ov" .
|
||||
"8Agde0cf5x/uanX/A28Hf8Gfl7XP8A919Z6Mew86+a+s9Hvdhf2R/I+2ejy03m7Rx6jSrzdo3szd8Hq8vftVdZ220X6Gn/ACo4fYeOrrO42n+vR1I9M/jteae656EZIiMjgUyIikUAKQQFSBRiCtAIhF4l1kdVMxiZU3ovBY3vSjNGvjpVkmxGMtlIoKCC" .
|
||||
"AogBYAChYQpAHQAwgAAAAAAQpCg8RmB6gAzAYC20WiWMewBgPUE7B6gBLYGQdyCLaLbATIKpGCsCDFgZgGMwMwHYMAIsApLBkMGQLJIUATIAoEIUgC0AWSFS0FxIAxIUhBAUmAAhQAIUBUBSEEBSACFEBUADIIQpAMTj/OH/AJep1nYs4vzWr/K1Otm3/P" .
|
||||
"3T0Z+Td8Xw6fmHo/udh59Pxno/udg+/wCK/a8qvNuj4malebdHxM4V6dh8yrrO32Vu3o6jh9lZqVnceX/61B6P129Xnnul60ZIxRkjhVRkiItxAKAFQFBURokFDA0V0VqriojtM6dXcKFCtMyLxLrLPNYmWXBr1NTB6aVCjIiMjGWqiACAAAAYGBRAy4EA" .
|
||||
"AYgALQAAyBMgAwGQKAQEgCZlyAELNwIgCiBZIFoBYB3C2wYAUmQyGQAYgO8AJdoGYBsEcFAdBLRZJcCBkMCZAAUWkAYgpMAICjECCAHeFRgYgARouJCCDAAAAAAKS0AACKgKIAhCgCCACDFkMmRhWLOI80c7nU63+J27OG8y/wBjV/mq/E3/AOfunoy8m6" .
|
||||
"HyNLxm/wDvGnS8Zt/unP3OvteZXm7R8ZpRt0fGcunp2fzajt/Lv9WjtOH2r/XqR3Hln+pR2/iej9cdXnnuno9yRURFRwMgRGRFAAAAAAhSMqMWVXoMYg4vSjJGKRkjKWywAgiACSygACSUABIFRGBLACCACkyKyWgAiSUASywWhYFBYAhSAMhJE7ioqBJL" .
|
||||
"IBYDAk3DAKttgJkMgKmG7SFkBKFlpPWJvADMNgAy4EkTYQMikyGAAJsk2gCgSSQBSCQoCWCQGIEkAt7BMQQCFkAQqIUAAAoACCAoAmBDIgEIykIJBCkYVjVccL5k/wBfV63+J3VfhfUcF5jVOtq9bN/+ffd0ZeTg+bo+I2/3jXoeIz/unP3OuDzo26XzDU" .
|
||||
"bNL5hy6ejbfPqO48sf+JR2nDaH+xV1Hb+VOdpSeiPxx/J57u6ej6KMjFGRmKikRSKqAAAAFEIUBGJDJkKPTSZIxRkjKWyoFBBBIADMmIGIFIAigAAEEKQAPWCAUhZJZICQQqAgAyADIAAmMiK8uQBO4skIBkTAKwhRSkBEA8RYAoAyAWQGS2AKS0AAww2E" .
|
||||
"AkMWCQoJDDAgDAABkwAQACAQpMQKIACrAgABAgFIMYEGRIAhMClYGLwIVkIIRlIFa9TwvqOB379utnfavgq6mfn29ftVno8H3dGXk4PHt/EZf3e0m38Qn9XtM+Lvg0mzT+YazOjx9xB6NH/YfUdr5S/8VHE6f+wdl5PV/jHoj8f9mN3d8H1kzJM1pmaZmM" .
|
||||
"0ymCZkmBkCEkgyDMWxJRSBkZUR1JXltZqrpq4uKm1mVOtrL3UJ3bFij1qqlXmac3Hla1qsEeihNUwZS1ZlMQRVJIxAQBBgBSBhlAAIAJIADDJIm8Ckd4kjvAoIAGAyIVYAATIsgC5GKvLkAkIhcQFgkEAsiSACyJIMwKCYACggkC5AmQAAYgCggkAAAoQE" .
|
||||
"AAAAUjBBUCFChUQoAoBAAAAFEAQjLBAJBGikZFYsxZkzFgatZ/p1PJM/P967amd9uHGjW/ys/P8AeO2rrPR4N1zK/fDz7e8n9ztLt8TH3zPi74NZnR4zAyp8RBvpca513k1X6LXUcen+sjq/Jav0ql1G9v4/7Mru74PtpmxM0U1SbEzly2yWTXJeIitkiT" .
|
||||
"CRxAZySTHiJJRnJJMZDYRkSTHiEg4vZTcZJmtOwyVWBlLdnIMZEkGRBJJAqZTGRNgFbvEmMiUEZSMiSSQKJJJJKKCSJASHgJI2BZDIw8QK8RkQSBfWDGRYBkEySRMDIGJZAoJJJAoJNgkCjMkkbAzwISbBIFkTKJITQFyBJAVQSQEUEEgUSRsSFBcSRNoF" .
|
||||
"ICSQWSkEgUGMlkKpUQswBZKYyXAgpSSAKAiSBSNFIFYkZkYsiMWYsybNbYV594422p/KzgN27aus7zfVf4ur/Kzgd07+s9Hh7bmV++GG3uZr982aHhfUaveMuLvgxKryFxA2J/qJn3fLN/RoLhrueJz8VJysDNamrkbWX2xbMSzutmZrDsl5ttovM15vts" .
|
||||
"zi1qapeZrZHVfHjKZLnaLzja5l+8bXM4vmaw5msSvjxkyX4O1+87X4h942uZxXHrDj1hXx4yZL8Ha/eNr8RPvG1+I4vmaw5msK+PGTJe7X7xtcyfeNrmcXzdYc3VyLm8eMmS52n3ja5j7vtZ8RxfN1chzdbIV8eMpkud6vO9lHjM/vex+M/P1q6uQ5urkc" .
|
||||
"U8WMu/rwh+gfe9j8Zfvexfvn5/zda+BztaLhTxYyv14Q/QPvWx+Mfetj8Z+f87WyHP1shTxYyn14Q/QfvOy+Mn3rZR4zgOfrZE5+rkMvixk+vCH6AvONkrOZJfvOx+M/Pufq5F+o1chl8Xqk+vCH6B942Xxl+8bL4z8++o1ch9RrZDL4vVJ9eEP0H7vsvj" .
|
||||
"H3bZfGfn31GrkPqdXIZfF6pPrwh+g/ddl+4Puuz/cPz/6rVyJ9TqZFy+L1SfXhD9B+6bP9xFfmez/cR+e/VamRfq9TImXx+qSt+D9C+57P9xEfmW0/cR+ffV6mQ+rryLl8fqlK34P0L7ltLf1EF5jtLP1Efnn1deRfq6shl8fqK34P0L7jtP3F3j7htf3V" .
|
||||
"3n579ZXkPrK8hl8fqK34P0P6/au3mU94+u2v7tPefnn1lWTL9bVkxk8fqK3YP0P67a/uU94W+237lMdZ+eLe1dJfrqukZPH6it2D9C+s21n6lPeX6vb/ALlPefnn11XSPrqunvGSz1ma7B+ifVaH7lPeFudH46e8/PPrnmx9fVmxp2eszXel+ifUaL99d4" .
|
||||
"+o0viXefnf19Wb7x9fVm+8advrgzXel+ic/SjxLvHO0/iR+efX1ZsfcKviY07fXBmn0v0Tm6fxLvHN048S7z88+41fEy/ca/iZNO31wZpwfofNos9pd5eZTmfnn3Kv42VeZ6vxsaUeuFzThL9C46cxxrM/Pl5pq/uMv3XW/dY0o9UGacJfoPGhxLM/P15t" .
|
||||
"r/u1F+76/wC7V3jS/wBoM3KXf8Q4jgV5vr/u1d7Ml5xr/uvvY0v9rTPyl3nETiOF+87j9195fvW5/dfeNKfVaZ+Uu5lDiRxH3vcx8wv33dfuE0pxhc/KXbOocRxP33dfuGX33dfuDSnGDPGEu0lFk4tefbr4/wACrz/dfH+A0bsYM8c3ZyWTjV/2HdfEvQ" .
|
||||
"Vf9h3XxIaN3IzxzdlIVRx3/ot1mi/+j3PQNG7kZ4djJeI47/0m56Cr/sm56CaN/Izw7CSycf8A+l3HQF/2XcXxSNG/kZ4dhIk5D/0u4ypL/wCl3OVJNG8zw61sxbOT/wDS6+VJH/2TcZUjRvXPDqmzXUzl3/2PcPCkxf8A2LcZUjRv5GeH3fMK1TtNScmj" .
|
||||
"gtw7+s+nvPNtfc08NTinJHydaqUa225bJrvlzM1lnov2H1GrEUuETEx4u+DEyVwBFblcXuAI7ZrsL3ABTuHcABe4WdHpAIFn5fSLPy+kAqln5fSLPy+kAIWdHpJZ0ekADNRHulUfl9IBBbPy+kWfl9IACz8vpJZ+X0gBFs/L6SOI930gAFH5fSLPy+kAKW" .
|
||||
"fl9JLOj0gALPy+kWdAAE7h3AATuHcAETuHcAA7idwBQ7idwADuJ3ABD+kj/wCIAD+kj/4gAP6R/SABi4/L6Q4/L6QCp8ks/L6RZ+X0gBPkWfl9JLPy+kAHyLPy+kWdHpAKfJLOj0izo9IARO4ABAgBRQAAIABQAA7x3gFQ7x3gBV7x3gBDvHeAPmHeO8Av" .
|
||||
"zDvL3gD5id47wCfMTvD7QAI+0jAAyQxAOHXB/9k=" );
|
||||
}
|
||||
}
|
||||
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"1": {
|
||||
"method": "insert",
|
||||
"params": [
|
||||
"core_permission_index",
|
||||
{
|
||||
"app": "calendar",
|
||||
"perm_type": "calendar",
|
||||
"perm_type_id": 1,
|
||||
"perm_view": "*",
|
||||
"perm_2": "*",
|
||||
"perm_3": "<%NO_GUESTS%>",
|
||||
"perm_4": "<%NO_GUESTS%>",
|
||||
"perm_5": "<%NO_GUESTS%>",
|
||||
"perm_6": "<%NO_GUESTS%>",
|
||||
"perm_7": "<%NO_GUESTS%>"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
Whitespace-only changes.
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief 4.0.0 Upgrade Code
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Calendar
|
||||
* @since 30 Oct 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\setup\upg_100002;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 4.0.0 Upgrade Code
|
||||
*/
|
||||
class _Upgrade
|
||||
{
|
||||
/**
|
||||
* Act on blogs
|
||||
*
|
||||
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
|
||||
*/
|
||||
public function step1()
|
||||
{
|
||||
\IPS\Db::i()->update( 'calendar_calendars', array( 'cal_title_seo' => null ) );
|
||||
\IPS\Db::i()->update( 'calendar_events', array( 'event_title_seo' => null ) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom title for this step
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function step1CustomTitle()
|
||||
{
|
||||
return "Resetting calendar friendly URL titles";
|
||||
}
|
||||
}
|
||||
Whitespace-only changes.
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"1": {
|
||||
"method": "dropIndex",
|
||||
"params": [
|
||||
"calendar_events",
|
||||
"event_content"
|
||||
]
|
||||
},
|
||||
"2": {
|
||||
"method": "dropIndex",
|
||||
"params": [
|
||||
"calendar_events",
|
||||
"event_title"
|
||||
]
|
||||
},
|
||||
"3": {
|
||||
"method": "dropIndex",
|
||||
"params": [
|
||||
"calendar_event_comments",
|
||||
"comment_text"
|
||||
]
|
||||
},
|
||||
"4": {
|
||||
"method": "dropIndex",
|
||||
"params": [
|
||||
"calendar_event_reviews",
|
||||
"review_text"
|
||||
]
|
||||
}
|
||||
}
|
||||
Whitespace-only changes.
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"1": {
|
||||
"method": "changeColumn",
|
||||
"params": [
|
||||
"calendar_event_reviews",
|
||||
"review_votes_data",
|
||||
{
|
||||
"name": "review_votes_data",
|
||||
"type": "TEXT",
|
||||
"length": 0,
|
||||
"decimals": null,
|
||||
"values": [],
|
||||
"allow_null": true,
|
||||
"default": "",
|
||||
"comment": "JSON object containing data about who has voted helpful\/unhelpful ",
|
||||
"unsigned": false,
|
||||
"zerofill": false,
|
||||
"auto_increment": false,
|
||||
"binary": false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
Whitespace-only changes.
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief 4.0.0 Upgrade Code
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @since 15 Jan 2015
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\setup\upg_100015;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 4.0.0 RC 2 Upgrade Code
|
||||
*/
|
||||
class _Upgrade
|
||||
{
|
||||
/**
|
||||
* Finish - This is run after all apps have been upgraded
|
||||
*
|
||||
* @return mixed If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
|
||||
* @note We opted not to let users run this immediately during the upgrade because of potential issues (it taking a long time and users stopping it or getting frustrated) but we can revisit later
|
||||
*/
|
||||
public function finish()
|
||||
{
|
||||
\IPS\Task::queue( 'core', 'RebuildItems', array( 'class' => 'IPS\calendar\Event' ), 3, array( 'class' ) );
|
||||
\IPS\Task::queue( 'core', 'RebuildItemCounts', array( 'class' => 'IPS\calendar\Event', 'count' => 0 ), 4, array( 'class' ) );
|
||||
\IPS\Task::queue( 'core', 'RebuildContainerCounts', array( 'class' => 'IPS\calendar\Calendar', 'count' => 0 ), 5, array( 'class' ) );
|
||||
}
|
||||
}
|
||||
Whitespace-only changes.
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"1": {
|
||||
"method": "delete",
|
||||
"params": [
|
||||
"core_modules",
|
||||
[
|
||||
"sys_module_application=? AND sys_module_key=?",
|
||||
"calendar",
|
||||
"events"
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief 4.0.0 RC 5 Upgrade Code
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Blog
|
||||
* @since 5 May 2015
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\setup\upg_100018;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 4.0.0 RC 5 Upgrade Code
|
||||
*/
|
||||
class _Upgrade
|
||||
{
|
||||
|
||||
/**
|
||||
* Make sure all theme settings are applied to every theme.
|
||||
*
|
||||
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
|
||||
*/
|
||||
public function finish()
|
||||
{
|
||||
\IPS\Task::queue( 'core', 'RebuildReputationIndex', array( 'class' => 'IPS\calendar\Event' ), 4 );
|
||||
\IPS\Task::queue( 'core', 'RebuildReputationIndex', array( 'class' => 'IPS\calendar\Event\Comment' ), 4 );
|
||||
\IPS\Task::queue( 'core', 'RebuildReputationIndex', array( 'class' => 'IPS\calendar\Event\Review' ), 4 );
|
||||
\IPS\Task::queue( 'core', 'RebuildContainerCounts', array( 'class' => 'IPS\calendar\Calendar', 'count' => 0 ), 5, array( 'class' ) );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
}
|
||||
Whitespace-only changes.
@@ -0,0 +1,111 @@
|
||||
{
|
||||
"1": {
|
||||
"method": "changeColumn",
|
||||
"params": [
|
||||
"calendar_events",
|
||||
"event_start_date",
|
||||
{
|
||||
"name": "event_start_date",
|
||||
"type": "DATETIME",
|
||||
"length": 0,
|
||||
"decimals": null,
|
||||
"values": [],
|
||||
"allow_null": false,
|
||||
"default": null,
|
||||
"comment": "",
|
||||
"unsigned": false,
|
||||
"zerofill": false,
|
||||
"auto_increment": false,
|
||||
"binary": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"2": {
|
||||
"method": "addIndex",
|
||||
"params": [
|
||||
"calendar_event_comments",
|
||||
{
|
||||
"type": "key",
|
||||
"name": "comment_approved",
|
||||
"columns": [
|
||||
"comment_approved"
|
||||
],
|
||||
"length": [
|
||||
null
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"3": {
|
||||
"method": "addIndex",
|
||||
"params": [
|
||||
"calendar_event_reviews",
|
||||
{
|
||||
"type": "key",
|
||||
"name": "review_approved",
|
||||
"columns": [
|
||||
"review_approved"
|
||||
],
|
||||
"length": [
|
||||
null
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"4": {
|
||||
"method": "addIndex",
|
||||
"params": [
|
||||
"calendar_events",
|
||||
{
|
||||
"type": "key",
|
||||
"name": "event_featured",
|
||||
"columns": [
|
||||
"event_featured",
|
||||
"event_approved",
|
||||
"event_calendar_id"
|
||||
],
|
||||
"length": [
|
||||
null,
|
||||
null,
|
||||
null
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"5": {
|
||||
"method": "addIndex",
|
||||
"params": [
|
||||
"calendar_events",
|
||||
{
|
||||
"type": "key",
|
||||
"name": "recurring_events",
|
||||
"columns": [
|
||||
"event_recurring",
|
||||
"event_approved",
|
||||
"event_calendar_id"
|
||||
],
|
||||
"length": [
|
||||
250,
|
||||
null,
|
||||
null
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"6": {
|
||||
"method": "addIndex",
|
||||
"params": [
|
||||
"calendar_events",
|
||||
{
|
||||
"type": "key",
|
||||
"name": "ip_lookup",
|
||||
"columns": [
|
||||
"event_ip_address"
|
||||
],
|
||||
"length": [
|
||||
null
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
Whitespace-only changes.
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"1": {
|
||||
"method": "update",
|
||||
"params": [
|
||||
"calendar_events",
|
||||
{
|
||||
"event_end_date": null
|
||||
},
|
||||
"event_start_date=event_end_date"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
{
|
||||
"1": {
|
||||
"method": "dropColumn",
|
||||
"params": [
|
||||
"calendar_events",
|
||||
"event_comments_pending"
|
||||
]
|
||||
},
|
||||
"2": {
|
||||
"method": "addColumn",
|
||||
"params": [
|
||||
"calendar_events",
|
||||
{
|
||||
"name": "event_queued_comments",
|
||||
"type": "INT",
|
||||
"length": 10,
|
||||
"decimals": null,
|
||||
"values": [],
|
||||
"allow_null": true,
|
||||
"default": null,
|
||||
"comment": "",
|
||||
"unsigned": true,
|
||||
"zerofill": false,
|
||||
"auto_increment": false,
|
||||
"binary": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"3": {
|
||||
"method": "addColumn",
|
||||
"params": [
|
||||
"calendar_events",
|
||||
{
|
||||
"name": "event_hidden_comments",
|
||||
"type": "INT",
|
||||
"length": 10,
|
||||
"decimals": null,
|
||||
"values": [],
|
||||
"allow_null": true,
|
||||
"default": null,
|
||||
"comment": "",
|
||||
"unsigned": true,
|
||||
"zerofill": false,
|
||||
"auto_increment": false,
|
||||
"binary": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"4": {
|
||||
"method": "addColumn",
|
||||
"params": [
|
||||
"calendar_events",
|
||||
{
|
||||
"name": "event_unapproved_reviews",
|
||||
"type": "INT",
|
||||
"length": 10,
|
||||
"decimals": null,
|
||||
"values": [],
|
||||
"allow_null": true,
|
||||
"default": null,
|
||||
"comment": "",
|
||||
"unsigned": true,
|
||||
"zerofill": false,
|
||||
"auto_increment": false,
|
||||
"binary": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"5": {
|
||||
"method": "addColumn",
|
||||
"params": [
|
||||
"calendar_events",
|
||||
{
|
||||
"name": "event_hidden_reviews",
|
||||
"type": "INT",
|
||||
"length": 0,
|
||||
"decimals": null,
|
||||
"values": [],
|
||||
"allow_null": true,
|
||||
"default": null,
|
||||
"comment": "",
|
||||
"unsigned": true,
|
||||
"zerofill": false,
|
||||
"auto_increment": false,
|
||||
"binary": false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief 4.0.5 Upgrade Code
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Blog
|
||||
* @since 5 May 2015
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\setup\upg_100028;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 4.0.5 Upgrade Code
|
||||
*/
|
||||
class _Upgrade
|
||||
{
|
||||
|
||||
/**
|
||||
* Make sure all theme settings are applied to every theme.
|
||||
*
|
||||
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
|
||||
*/
|
||||
public function finish()
|
||||
{
|
||||
\IPS\core\Setup\Upgrade::repairFileUrls('calendar');
|
||||
\IPS\Task::queue( 'core', 'RebuildContentImages', array( 'class' => 'IPS\calendar\Event' ), 3, array( 'class' ) );
|
||||
\IPS\Task::queue( 'core', 'RebuildContentImages', array( 'class' => 'IPS\calendar\Event\Comment' ), 3, array( 'class' ) );
|
||||
\IPS\Task::queue( 'core', 'RebuildContentImages', array( 'class' => 'IPS\calendar\Event\Review' ), 3, array( 'class' ) );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief 4.0.12 Upgrade Code
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @since 21 Jul 2015
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\setup\upg_100042;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 4.0.12 Upgrade Code
|
||||
*/
|
||||
class _Upgrade
|
||||
{
|
||||
/**
|
||||
* Fix all day calendar events
|
||||
*
|
||||
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
|
||||
*/
|
||||
public function step1()
|
||||
{
|
||||
$perCycle = 500;
|
||||
$did = 0;
|
||||
$limit = intval( \IPS\Request::i()->extra );
|
||||
|
||||
/* Try to prevent timeouts to the extent possible */
|
||||
$cutOff = \IPS\core\Setup\Upgrade::determineCutoff();
|
||||
|
||||
/* We need all day events where the time is not already 00:00 - these are the ones that are time zone adjusted and need to be fixed */
|
||||
foreach( \IPS\Db::i()->select( '*', 'calendar_events', array( "event_all_day=? AND DATE_FORMAT(event_start_date,'%H:%i') != ?", 1, '00:00' ), 'event_id ASC', array( $limit, $perCycle ) ) as $event )
|
||||
{
|
||||
if( $cutOff !== null AND time() >= $cutOff )
|
||||
{
|
||||
return ( $limit + $did );
|
||||
}
|
||||
|
||||
$did++;
|
||||
|
||||
$update = array();
|
||||
|
||||
/* We need to figure out the submitter's time zone offset so we can put the event back to where it belongs */
|
||||
if( $event['event_member_id'] )
|
||||
{
|
||||
$member = \IPS\Member::load( $event['event_member_id'] );
|
||||
$startDate = new \IPS\DateTime( $event['event_start_date'], $member->timezone ? new \DateTimeZone( $member->timezone ) : NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
$startDate = new \IPS\DateTime( $event['event_start_date'], NULL );
|
||||
}
|
||||
|
||||
/* Then move it back to UTC */
|
||||
$startDate->setTimezone( new \DateTimeZone('UTC') );
|
||||
|
||||
/* And then return our datetime */
|
||||
$update['event_start_date'] = $startDate->format( 'Y-m-d 00:00:00' );
|
||||
|
||||
/* Do the same if we have an end date */
|
||||
if( $event['event_end_date'] )
|
||||
{
|
||||
/* We need to figure out the submitter's time zone offset so we can put the event back to where it belongs */
|
||||
if( $event['event_member_id'] )
|
||||
{
|
||||
$member = \IPS\Member::load( $event['event_member_id'] );
|
||||
$endDate = new \IPS\DateTime( $event['event_end_date'], $member->timezone ? new \DateTimeZone( $member->timezone ) : NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
$endDate = new \IPS\DateTime( $event['event_end_date'], NULL );
|
||||
}
|
||||
|
||||
/* Then move it back to UTC */
|
||||
$endDate->setTimezone( new \DateTimeZone('UTC') );
|
||||
|
||||
/* And then return our datetime */
|
||||
$update['event_end_date'] = $endDate->format( 'Y-m-d 00:00:00' );
|
||||
}
|
||||
|
||||
\IPS\Db::i()->update( 'calendar_events', $update, array( 'event_id=?', $event['event_id'] ) );
|
||||
}
|
||||
|
||||
if( $did )
|
||||
{
|
||||
return ( $limit + $did );
|
||||
}
|
||||
else
|
||||
{
|
||||
unset( $_SESSION['_step1Count'] );
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom title for this step
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function step1CustomTitle()
|
||||
{
|
||||
$limit = isset( \IPS\Request::i()->extra ) ? \IPS\Request::i()->extra : 0;
|
||||
|
||||
if( !isset( $_SESSION['_step1Count'] ) )
|
||||
{
|
||||
$_SESSION['_step1Count'] = \IPS\Db::i()->select( 'COUNT(*)', 'calendar_events', array( "event_all_day=? AND DATE_FORMAT(event_start_date,'%H:%i') != ?", 1, '00:00' ) )->first();
|
||||
}
|
||||
|
||||
return "Fixing all day calendar events (Updated so far: " . ( ( $limit > $_SESSION['_step1Count'] ) ? $_SESSION['_step1Count'] : $limit ) . ' out of ' . $_SESSION['_step1Count'] . ')';
|
||||
}
|
||||
}
|
||||
Whitespace-only changes.
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
$SQL[] = "ALTER TABLE cal_calendars DROP cal_permissions,
|
||||
ADD cal_title_seo VARCHAR( 255 ) NULL DEFAULT NULL,
|
||||
ADD cal_comment_moderate TINYINT( 1 ) NOT NULL DEFAULT '0',
|
||||
ADD cal_rsvp_owner TINYINT( 1 ) NOT NULL DEFAULT '0';";
|
||||
|
||||
$SQL[] = "CREATE TABLE cal_event_ratings (
|
||||
rating_id int(10) NOT NULL auto_increment,
|
||||
rating_eid int(10) NOT NULL default '0',
|
||||
rating_member_id mediumint(8) NOT NULL default '0',
|
||||
rating_value smallint(6) NOT NULL default '0',
|
||||
rating_ip_address varchar(46) NOT NULL,
|
||||
PRIMARY KEY (rating_id),
|
||||
KEY rating_eid (rating_eid,rating_member_id),
|
||||
KEY rating_ip_address (rating_ip_address)
|
||||
);";
|
||||
|
||||
$SQL[] = "CREATE TABLE cal_event_comments (
|
||||
comment_id int(10) NOT NULL auto_increment,
|
||||
comment_eid int(10) NOT NULL default '0',
|
||||
comment_mid mediumint(8) NOT NULL default '0',
|
||||
comment_date int(11) NOT NULL default '0',
|
||||
comment_approved tinyint(1) NOT NULL default '0',
|
||||
comment_text mediumtext,
|
||||
comment_append_edit tinyint(1) NOT NULL default '0',
|
||||
comment_edit_time int(11) NOT NULL default '0',
|
||||
comment_edit_name varchar(255) default NULL,
|
||||
ip_address varchar(46) default NULL,
|
||||
comment_author varchar(255) default NULL,
|
||||
PRIMARY KEY (comment_id),
|
||||
KEY comment_eid (comment_eid),
|
||||
KEY ip_address (ip_address)
|
||||
);";
|
||||
|
||||
$SQL[] = "CREATE TABLE cal_event_rsvp (
|
||||
rsvp_id int(11) NOT NULL auto_increment,
|
||||
rsvp_event_id int(11) NOT NULL default '0',
|
||||
rsvp_member_id int(11) NOT NULL default '0',
|
||||
rsvp_date int(11) NOT NULL default '0',
|
||||
PRIMARY KEY (rsvp_id),
|
||||
KEY rsvp_event_id (rsvp_event_id),
|
||||
KEY rsvp_member_id (rsvp_member_id)
|
||||
);";
|
||||
|
||||
$SQL[] = "CREATE TABLE cal_import_feeds (
|
||||
feed_id int(11) NOT NULL auto_increment,
|
||||
feed_title varchar(255) default NULL,
|
||||
feed_url text,
|
||||
feed_added int(11) NOT NULL default '0',
|
||||
feed_lastupdated int(11) NOT NULL default '0',
|
||||
feed_recache_freq int(11) NOT NULL default '0',
|
||||
feed_calendar_id int(11) NOT NULL default '0',
|
||||
feed_member_id INT NOT NULL DEFAULT '0',
|
||||
feed_next_run INT NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (feed_id),
|
||||
KEY feed_calendar_id (feed_calendar_id),
|
||||
KEY feed_next_run (feed_next_run)
|
||||
);";
|
||||
|
||||
$SQL[] = "CREATE TABLE cal_import_map (
|
||||
import_id int(11) NOT NULL auto_increment,
|
||||
import_feed_id int(11) NOT NULL default '0',
|
||||
import_event_id int(11) NOT NULL default '0',
|
||||
import_guid varchar(255) NOT NULL default '0',
|
||||
PRIMARY KEY (import_id),
|
||||
KEY import_feed_id (import_feed_id),
|
||||
KEY import_event_id (import_event_id),
|
||||
KEY import_guid (import_guid)
|
||||
);";
|
||||
|
||||
|
||||
|
||||
$SQL[] = "RENAME TABLE cal_events TO cal_events_bak;";
|
||||
|
||||
$SQL[] = "CREATE TABLE cal_events (
|
||||
event_id int(10) unsigned NOT NULL auto_increment,
|
||||
event_calendar_id int(10) unsigned NOT NULL default '0',
|
||||
event_member_id mediumint(8) unsigned NOT NULL default '0',
|
||||
event_content mediumtext,
|
||||
event_title varchar(255) NOT NULL default '',
|
||||
event_smilies tinyint(1) NOT NULL default '0',
|
||||
event_comments int NOT NULL default '0',
|
||||
event_rsvp tinyint(1) NOT NULL default '0',
|
||||
event_perms text,
|
||||
event_private tinyint(1) NOT NULL default '0',
|
||||
event_approved tinyint(1) NOT NULL default '0',
|
||||
event_saved int(10) unsigned NOT NULL default '0',
|
||||
event_lastupdated int(10) unsigned NOT NULL default '0',
|
||||
event_recurring int(2) unsigned NOT NULL default '0',
|
||||
event_start_date datetime NOT NULL,
|
||||
event_end_date datetime default NULL,
|
||||
event_title_seo VARCHAR( 255 ) NULL DEFAULT NULL,
|
||||
event_rating_total INT NOT NULL DEFAULT '0',
|
||||
event_rating_hits INT NOT NULL DEFAULT '0',
|
||||
event_rating_avg INT NOT NULL DEFAULT '0',
|
||||
event_attachments INT NOT NULL DEFAULT '0',
|
||||
event_post_key VARCHAR( 32 ) NULL DEFAULT NULL,
|
||||
event_comments_pending INT NOT NULL DEFAULT '0',
|
||||
event_sequence INT NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (event_id),
|
||||
KEY approved (event_calendar_id , event_approved , event_start_date , event_end_date),
|
||||
KEY event_member_id (event_member_id, event_approved, event_private, event_lastupdated)
|
||||
);";
|
||||
|
||||
$SQL[] = "INSERT INTO cal_events SELECT event_id, event_calendar_id, event_member_id, event_content, event_title, event_smilies, 0, 0, event_perms, event_private, event_approved, event_unixstamp, event_unixstamp,
|
||||
event_recurring, FROM_UNIXTIME(event_unix_from), CASE WHEN event_unix_to > 0 THEN FROM_UNIXTIME(event_unix_to) ELSE NULL END, '', 0, 0, 0, 0, MD5( CONCAT( event_id, event_title ) ), 0, 1 FROM " . \IPS\Db::i()->prefix . "cal_events_bak;";
|
||||
|
||||
$SQL[] = "DROP TABLE cal_events_bak;";
|
||||
|
||||
$SQL[] = "ALTER TABLE cal_events ADD event_all_day TINYINT NOT NULL DEFAULT '0';";
|
||||
$SQL[] = "UPDATE cal_events SET event_all_day=1 WHERE TIME(event_start_date) = '00:00:00';";
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief 4.0.0 Upgrade Code
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Calendar
|
||||
* @since 24 Oct 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\setup\upg_32000;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 4.0.0 Upgrade Code
|
||||
*/
|
||||
class _Upgrade
|
||||
{
|
||||
/**
|
||||
* Conversion from 3.0
|
||||
*
|
||||
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
|
||||
*/
|
||||
public function step1()
|
||||
{
|
||||
\IPS\core\Setup\Upgrade::runLegacySql( 'calendar', 32000 );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
Whitespace-only changes.
@@ -0,0 +1,909 @@
|
||||
{
|
||||
"1": {
|
||||
"method": "renameTable",
|
||||
"params": [
|
||||
"cal_calendars",
|
||||
"calendar_calendars"
|
||||
]
|
||||
},
|
||||
"2": {
|
||||
"method": "renameTable",
|
||||
"params": [
|
||||
"cal_event_comments",
|
||||
"calendar_event_comments"
|
||||
]
|
||||
},
|
||||
"3": {
|
||||
"method": "renameTable",
|
||||
"params": [
|
||||
"cal_event_rsvp",
|
||||
"calendar_event_rsvp"
|
||||
]
|
||||
},
|
||||
"4": {
|
||||
"method": "dropTable",
|
||||
"params": [
|
||||
"calendar_events",
|
||||
true
|
||||
]
|
||||
},
|
||||
"5": {
|
||||
"method": "renameTable",
|
||||
"params": [
|
||||
"cal_events",
|
||||
"calendar_events"
|
||||
]
|
||||
},
|
||||
"6": {
|
||||
"method": "renameTable",
|
||||
"params": [
|
||||
"cal_import_feeds",
|
||||
"calendar_import_feeds"
|
||||
]
|
||||
},
|
||||
"7": {
|
||||
"method": "renameTable",
|
||||
"params": [
|
||||
"cal_import_map",
|
||||
"calendar_import_map"
|
||||
]
|
||||
},
|
||||
"8": {
|
||||
"method": "dropIndex",
|
||||
"params": [
|
||||
"calendar_events",
|
||||
"event_content"
|
||||
]
|
||||
},
|
||||
"9": {
|
||||
"method": "dropIndex",
|
||||
"params": [
|
||||
"calendar_events",
|
||||
"event_title"
|
||||
]
|
||||
},
|
||||
"10": {
|
||||
"method": "dropIndex",
|
||||
"params": [
|
||||
"calendar_event_comments",
|
||||
"comment_text"
|
||||
]
|
||||
},
|
||||
"11": {
|
||||
"method": "dropColumn",
|
||||
"params": [
|
||||
"calendar_calendars",
|
||||
[
|
||||
"cal_rss_cache",
|
||||
"cal_rss_update",
|
||||
"cal_rss_export",
|
||||
"cal_rss_export_days",
|
||||
"cal_rss_update_last",
|
||||
"cal_rss_export_max",
|
||||
"cal_rsvp_owner",
|
||||
"cal_bday_limit",
|
||||
"cal_event_limit"
|
||||
]
|
||||
]
|
||||
},
|
||||
"12": {
|
||||
"method": "dropColumn",
|
||||
"params": [
|
||||
"calendar_import_feeds",
|
||||
"feed_recache_freq"
|
||||
]
|
||||
},
|
||||
"13": {
|
||||
"method": "addColumn",
|
||||
"params": [
|
||||
"calendar_calendars",
|
||||
{
|
||||
"name": "cal_color",
|
||||
"type": "VARCHAR",
|
||||
"length": 7,
|
||||
"decimals": null,
|
||||
"values": [],
|
||||
"allow_null": true,
|
||||
"default": null,
|
||||
"comment": "Hex color code to represent this calendar",
|
||||
"unsigned": false,
|
||||
"zerofill": false,
|
||||
"auto_increment": false,
|
||||
"binary": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"14": {
|
||||
"method": "update",
|
||||
"params": [
|
||||
"calendar_calendars",
|
||||
"cal_color='#000000'"
|
||||
]
|
||||
},
|
||||
"15": {
|
||||
"method": "changeColumn",
|
||||
"params": [
|
||||
"calendar_event_comments",
|
||||
"ip_address",
|
||||
{
|
||||
"name": "comment_ip_address",
|
||||
"type": "VARCHAR",
|
||||
"length": 46,
|
||||
"decimals": null,
|
||||
"values": [],
|
||||
"allow_null": true,
|
||||
"default": null,
|
||||
"comment": "",
|
||||
"unsigned": false,
|
||||
"zerofill": false,
|
||||
"auto_increment": false,
|
||||
"binary": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"16": {
|
||||
"method": "addColumn",
|
||||
"params": [
|
||||
"calendar_events",
|
||||
{
|
||||
"name": "event_reviews",
|
||||
"type": "INT",
|
||||
"length": null,
|
||||
"decimals": null,
|
||||
"values": [],
|
||||
"allow_null": false,
|
||||
"default": "0",
|
||||
"comment": "",
|
||||
"unsigned": true,
|
||||
"zerofill": false,
|
||||
"auto_increment": false,
|
||||
"binary": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"17": {
|
||||
"method": "dropColumn",
|
||||
"params": [
|
||||
"calendar_events",
|
||||
[
|
||||
"event_smilies",
|
||||
"event_rating_hits",
|
||||
"event_rating_total",
|
||||
"event_attachments"
|
||||
]
|
||||
]
|
||||
},
|
||||
"18": {
|
||||
"method": "addColumn",
|
||||
"params": [
|
||||
"calendar_events",
|
||||
{
|
||||
"name": "event_ip_address",
|
||||
"type": "VARCHAR",
|
||||
"length": 46,
|
||||
"decimals": null,
|
||||
"values": [],
|
||||
"allow_null": true,
|
||||
"default": null,
|
||||
"comment": "",
|
||||
"unsigned": false,
|
||||
"zerofill": false,
|
||||
"auto_increment": false,
|
||||
"binary": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"19": {
|
||||
"method": "addColumn",
|
||||
"params": [
|
||||
"calendar_events",
|
||||
{
|
||||
"name": "event_locked",
|
||||
"type": "TINYINT",
|
||||
"length": 1,
|
||||
"decimals": null,
|
||||
"values": [],
|
||||
"allow_null": false,
|
||||
"default": "0",
|
||||
"comment": "Whether the event is locked (for new comments\/reviews) or not",
|
||||
"unsigned": true,
|
||||
"zerofill": false,
|
||||
"auto_increment": false,
|
||||
"binary": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"20": {
|
||||
"method": "addColumn",
|
||||
"params": [
|
||||
"calendar_events",
|
||||
{
|
||||
"name": "event_featured",
|
||||
"type": "TINYINT",
|
||||
"length": 1,
|
||||
"decimals": null,
|
||||
"values": [],
|
||||
"allow_null": false,
|
||||
"default": "0",
|
||||
"comment": "Whether the event is featured or not",
|
||||
"unsigned": true,
|
||||
"zerofill": false,
|
||||
"auto_increment": false,
|
||||
"binary": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"21": {
|
||||
"method": "changeColumn",
|
||||
"params": [
|
||||
"calendar_events",
|
||||
"event_rating_avg",
|
||||
{
|
||||
"name": "event_rating",
|
||||
"type": "SMALLINT",
|
||||
"length": 5,
|
||||
"decimals": null,
|
||||
"values": [],
|
||||
"allow_null": false,
|
||||
"default": "0",
|
||||
"comment": "",
|
||||
"unsigned": true,
|
||||
"zerofill": false,
|
||||
"auto_increment": false,
|
||||
"binary": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"22": {
|
||||
"method": "addColumn",
|
||||
"params": [
|
||||
"calendar_events",
|
||||
{
|
||||
"name": "event_last_comment",
|
||||
"type": "INT",
|
||||
"length": 11,
|
||||
"decimals": null,
|
||||
"values": [],
|
||||
"allow_null": true,
|
||||
"default": null,
|
||||
"comment": "",
|
||||
"unsigned": true,
|
||||
"zerofill": false,
|
||||
"auto_increment": false,
|
||||
"binary": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"23": {
|
||||
"method": "addColumn",
|
||||
"params": [
|
||||
"calendar_events",
|
||||
{
|
||||
"name": "event_last_review",
|
||||
"type": "INT",
|
||||
"length": 11,
|
||||
"decimals": null,
|
||||
"values": [],
|
||||
"allow_null": true,
|
||||
"default": null,
|
||||
"comment": "",
|
||||
"unsigned": true,
|
||||
"zerofill": false,
|
||||
"auto_increment": false,
|
||||
"binary": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"24": {
|
||||
"method": "addColumn",
|
||||
"params": [
|
||||
"calendar_events",
|
||||
{
|
||||
"name": "event_approved_by",
|
||||
"type": "BIGINT",
|
||||
"length": 0,
|
||||
"decimals": null,
|
||||
"values": [],
|
||||
"allow_null": true,
|
||||
"default": null,
|
||||
"comment": "Member ID who approved the event",
|
||||
"unsigned": true,
|
||||
"zerofill": false,
|
||||
"auto_increment": false,
|
||||
"binary": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"25": {
|
||||
"method": "addColumn",
|
||||
"params": [
|
||||
"calendar_events",
|
||||
{
|
||||
"name": "event_approved_on",
|
||||
"type": "INT",
|
||||
"length": 11,
|
||||
"decimals": null,
|
||||
"values": [],
|
||||
"allow_null": true,
|
||||
"default": null,
|
||||
"comment": "Date the event was approved on",
|
||||
"unsigned": true,
|
||||
"zerofill": false,
|
||||
"auto_increment": false,
|
||||
"binary": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"26": {
|
||||
"method": "dropTable",
|
||||
"params": [
|
||||
"cal_event_ratings",
|
||||
true
|
||||
]
|
||||
},
|
||||
"27": {
|
||||
"method": "addColumn",
|
||||
"params": [
|
||||
"calendar_calendars",
|
||||
{
|
||||
"name": "cal_allow_comments",
|
||||
"type": "TINYINT",
|
||||
"length": 1,
|
||||
"decimals": null,
|
||||
"values": [],
|
||||
"allow_null": false,
|
||||
"default": "1",
|
||||
"comment": "",
|
||||
"unsigned": true,
|
||||
"zerofill": false,
|
||||
"auto_increment": false,
|
||||
"binary": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"28": {
|
||||
"method": "addColumn",
|
||||
"params": [
|
||||
"calendar_calendars",
|
||||
{
|
||||
"name": "cal_allow_reviews",
|
||||
"type": "TINYINT",
|
||||
"length": 1,
|
||||
"decimals": null,
|
||||
"values": [],
|
||||
"allow_null": false,
|
||||
"default": "0",
|
||||
"comment": "",
|
||||
"unsigned": true,
|
||||
"zerofill": false,
|
||||
"auto_increment": false,
|
||||
"binary": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"29": {
|
||||
"method": "addColumn",
|
||||
"params": [
|
||||
"calendar_calendars",
|
||||
{
|
||||
"name": "cal_review_moderate",
|
||||
"type": "TINYINT",
|
||||
"length": 1,
|
||||
"decimals": null,
|
||||
"values": [],
|
||||
"allow_null": false,
|
||||
"default": "0",
|
||||
"comment": "",
|
||||
"unsigned": true,
|
||||
"zerofill": false,
|
||||
"auto_increment": false,
|
||||
"binary": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"30": {
|
||||
"method": "addColumn",
|
||||
"params": [
|
||||
"calendar_events",
|
||||
{
|
||||
"name": "event_location",
|
||||
"type": "TEXT",
|
||||
"length": null,
|
||||
"decimals": null,
|
||||
"values": [],
|
||||
"allow_null": true,
|
||||
"default": null,
|
||||
"comment": "Stores location data for the event, used to create a map",
|
||||
"unsigned": false,
|
||||
"zerofill": false,
|
||||
"auto_increment": false,
|
||||
"binary": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"31": {
|
||||
"method": "addColumn",
|
||||
"params": [
|
||||
"calendar_import_feeds",
|
||||
{
|
||||
"name": "feed_allow_rsvp",
|
||||
"type": "TINYINT",
|
||||
"length": 1,
|
||||
"decimals": null,
|
||||
"values": [],
|
||||
"allow_null": false,
|
||||
"default": "0",
|
||||
"comment": "",
|
||||
"unsigned": true,
|
||||
"zerofill": false,
|
||||
"auto_increment": false,
|
||||
"binary": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"32": {
|
||||
"method": "addColumn",
|
||||
"params": [
|
||||
"calendar_events",
|
||||
{
|
||||
"name": "event_rsvp_limit",
|
||||
"type": "INT",
|
||||
"length": 10,
|
||||
"decimals": null,
|
||||
"values": [],
|
||||
"allow_null": true,
|
||||
"default": null,
|
||||
"comment": "Maximum number of attendees allowed for the event",
|
||||
"unsigned": false,
|
||||
"zerofill": false,
|
||||
"auto_increment": false,
|
||||
"binary": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"33": {
|
||||
"method": "addColumn",
|
||||
"params": [
|
||||
"calendar_events",
|
||||
{
|
||||
"name": "event_cover_photo",
|
||||
"type": "VARCHAR",
|
||||
"length": 255,
|
||||
"decimals": null,
|
||||
"values": [],
|
||||
"allow_null": true,
|
||||
"default": null,
|
||||
"comment": "Header background image for the event",
|
||||
"unsigned": false,
|
||||
"zerofill": false,
|
||||
"auto_increment": false,
|
||||
"binary": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"34": {
|
||||
"method": "addColumn",
|
||||
"params": [
|
||||
"calendar_event_rsvp",
|
||||
{
|
||||
"name": "rsvp_response",
|
||||
"type": "TINYINT",
|
||||
"length": null,
|
||||
"decimals": null,
|
||||
"values": [],
|
||||
"allow_null": false,
|
||||
"default": "0",
|
||||
"comment": "0=No, 1=Yes, 2=Maybe",
|
||||
"unsigned": true,
|
||||
"zerofill": false,
|
||||
"auto_increment": false,
|
||||
"binary": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"35": {
|
||||
"method": "update",
|
||||
"params": [
|
||||
"calendar_event_rsvp",
|
||||
"rsvp_response=1"
|
||||
]
|
||||
},
|
||||
"36": {
|
||||
"method": "changeColumn",
|
||||
"params": [
|
||||
"calendar_events",
|
||||
"event_recurring",
|
||||
{
|
||||
"name": "event_recurring",
|
||||
"type": "TEXT",
|
||||
"length": 2,
|
||||
"decimals": null,
|
||||
"values": [],
|
||||
"allow_null": true,
|
||||
"default": "0",
|
||||
"comment": "Holds an RRULE value to indicate how the event recurs",
|
||||
"unsigned": true,
|
||||
"zerofill": false,
|
||||
"auto_increment": false,
|
||||
"binary": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"37": {
|
||||
"method": "changeColumn",
|
||||
"params": [
|
||||
"calendar_events",
|
||||
"event_end_date",
|
||||
{
|
||||
"name": "event_end_date",
|
||||
"type": "DATETIME",
|
||||
"length": 0,
|
||||
"decimals": null,
|
||||
"values": [],
|
||||
"allow_null": true,
|
||||
"default": "0000-00-00 00:00:00",
|
||||
"comment": "",
|
||||
"unsigned": false,
|
||||
"zerofill": false,
|
||||
"auto_increment": false,
|
||||
"binary": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"38": {
|
||||
"method": "changeColumn",
|
||||
"params": [
|
||||
"calendar_import_feeds",
|
||||
"feed_next_run",
|
||||
{
|
||||
"name": "feed_last_run",
|
||||
"type": "INT",
|
||||
"length": 11,
|
||||
"decimals": null,
|
||||
"values": [],
|
||||
"allow_null": false,
|
||||
"default": "0",
|
||||
"comment": "",
|
||||
"unsigned": false,
|
||||
"zerofill": false,
|
||||
"auto_increment": false,
|
||||
"binary": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"39": {
|
||||
"method": "changeIndex",
|
||||
"params": [
|
||||
"calendar_import_feeds",
|
||||
"feed_next_run",
|
||||
{
|
||||
"type": "key",
|
||||
"name": "feed_last_run",
|
||||
"columns": [
|
||||
"feed_last_run"
|
||||
],
|
||||
"length": [
|
||||
null
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"40": {
|
||||
"method": "addColumn",
|
||||
"params": [
|
||||
"calendar_events",
|
||||
{
|
||||
"name": "event_album",
|
||||
"type": "MEDIUMINT",
|
||||
"length": null,
|
||||
"decimals": null,
|
||||
"values": [],
|
||||
"allow_null": true,
|
||||
"default": null,
|
||||
"comment": "Holds album ID associated with this event",
|
||||
"unsigned": true,
|
||||
"zerofill": false,
|
||||
"auto_increment": false,
|
||||
"binary": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"41": {
|
||||
"method": "createTable",
|
||||
"params": [
|
||||
{
|
||||
"name": "calendar_event_reviews",
|
||||
"columns": {
|
||||
"review_id": {
|
||||
"allow_null": false,
|
||||
"auto_increment": true,
|
||||
"binary": false,
|
||||
"comment": "ID Number",
|
||||
"decimals": null,
|
||||
"default": null,
|
||||
"length": 20,
|
||||
"name": "review_id",
|
||||
"type": "BIGINT",
|
||||
"unsigned": true,
|
||||
"values": [],
|
||||
"zerofill": false
|
||||
},
|
||||
"review_eid": {
|
||||
"allow_null": false,
|
||||
"auto_increment": false,
|
||||
"binary": false,
|
||||
"comment": "The event ID",
|
||||
"decimals": null,
|
||||
"default": "0",
|
||||
"length": 10,
|
||||
"name": "review_eid",
|
||||
"type": "INT",
|
||||
"unsigned": true,
|
||||
"values": [],
|
||||
"zerofill": false
|
||||
},
|
||||
"review_mid": {
|
||||
"allow_null": false,
|
||||
"auto_increment": false,
|
||||
"binary": false,
|
||||
"comment": "The member ID of the review author",
|
||||
"decimals": null,
|
||||
"default": "0",
|
||||
"length": 8,
|
||||
"name": "review_mid",
|
||||
"type": "MEDIUMINT",
|
||||
"unsigned": true,
|
||||
"values": [],
|
||||
"zerofill": false
|
||||
},
|
||||
"review_text": {
|
||||
"allow_null": true,
|
||||
"auto_increment": false,
|
||||
"binary": false,
|
||||
"comment": "The review contents",
|
||||
"decimals": null,
|
||||
"default": null,
|
||||
"length": 0,
|
||||
"name": "review_text",
|
||||
"type": "MEDIUMTEXT",
|
||||
"unsigned": false,
|
||||
"values": [],
|
||||
"zerofill": false
|
||||
},
|
||||
"review_append_edit": {
|
||||
"allow_null": false,
|
||||
"auto_increment": false,
|
||||
"binary": false,
|
||||
"comment": "Boolean indicating if edit message should show",
|
||||
"decimals": null,
|
||||
"default": "0",
|
||||
"length": 1,
|
||||
"name": "review_append_edit",
|
||||
"type": "TINYINT",
|
||||
"unsigned": true,
|
||||
"values": [],
|
||||
"zerofill": false
|
||||
},
|
||||
"review_edit_time": {
|
||||
"allow_null": true,
|
||||
"auto_increment": false,
|
||||
"binary": false,
|
||||
"comment": "Unix timestamp of when the review was last edited",
|
||||
"decimals": null,
|
||||
"default": null,
|
||||
"length": 10,
|
||||
"name": "review_edit_time",
|
||||
"type": "INT",
|
||||
"unsigned": true,
|
||||
"values": [],
|
||||
"zerofill": false
|
||||
},
|
||||
"review_edit_name": {
|
||||
"allow_null": true,
|
||||
"auto_increment": false,
|
||||
"binary": false,
|
||||
"comment": "Username of user who last edited review",
|
||||
"decimals": null,
|
||||
"default": null,
|
||||
"length": 255,
|
||||
"name": "review_edit_name",
|
||||
"type": "VARCHAR",
|
||||
"unsigned": false,
|
||||
"values": [],
|
||||
"zerofill": false
|
||||
},
|
||||
"review_date": {
|
||||
"allow_null": true,
|
||||
"auto_increment": false,
|
||||
"binary": false,
|
||||
"comment": "Unix timestamp of when review was made",
|
||||
"decimals": null,
|
||||
"default": null,
|
||||
"length": 10,
|
||||
"name": "review_date",
|
||||
"type": "INT",
|
||||
"unsigned": false,
|
||||
"values": [],
|
||||
"zerofill": false
|
||||
},
|
||||
"review_ip": {
|
||||
"allow_null": false,
|
||||
"auto_increment": false,
|
||||
"binary": false,
|
||||
"comment": "IP address review was made from",
|
||||
"decimals": null,
|
||||
"default": "",
|
||||
"length": 46,
|
||||
"name": "review_ip",
|
||||
"type": "VARCHAR",
|
||||
"unsigned": false,
|
||||
"values": [],
|
||||
"zerofill": false
|
||||
},
|
||||
"review_author_name": {
|
||||
"allow_null": false,
|
||||
"auto_increment": false,
|
||||
"binary": false,
|
||||
"comment": "Username of user who made review",
|
||||
"decimals": null,
|
||||
"default": "",
|
||||
"length": 255,
|
||||
"name": "review_author_name",
|
||||
"type": "VARCHAR",
|
||||
"unsigned": false,
|
||||
"values": [],
|
||||
"zerofill": false
|
||||
},
|
||||
"review_rating": {
|
||||
"allow_null": true,
|
||||
"auto_increment": false,
|
||||
"binary": false,
|
||||
"comment": "The rating (out of 5) with the review",
|
||||
"decimals": null,
|
||||
"default": null,
|
||||
"length": 1,
|
||||
"name": "review_rating",
|
||||
"type": "TINYINT",
|
||||
"unsigned": true,
|
||||
"values": [],
|
||||
"zerofill": false
|
||||
},
|
||||
"review_votes": {
|
||||
"allow_null": false,
|
||||
"auto_increment": false,
|
||||
"binary": false,
|
||||
"comment": "The number of people who have voted \"helpful\" or \"unhelpful\"",
|
||||
"decimals": null,
|
||||
"default": "0",
|
||||
"length": 10,
|
||||
"name": "review_votes",
|
||||
"type": "INT",
|
||||
"unsigned": true,
|
||||
"values": [],
|
||||
"zerofill": false
|
||||
},
|
||||
"review_votes_helpful": {
|
||||
"allow_null": false,
|
||||
"auto_increment": false,
|
||||
"binary": false,
|
||||
"comment": "The number of people who have voted \"helpful\"",
|
||||
"decimals": null,
|
||||
"default": "0",
|
||||
"length": 10,
|
||||
"name": "review_votes_helpful",
|
||||
"type": "INT",
|
||||
"unsigned": true,
|
||||
"values": [],
|
||||
"zerofill": false
|
||||
},
|
||||
"review_votes_data": {
|
||||
"allow_null": false,
|
||||
"auto_increment": false,
|
||||
"binary": false,
|
||||
"comment": "JSON object containing data about who has voted helpful\/unhelpful ",
|
||||
"decimals": null,
|
||||
"default": "",
|
||||
"length": 0,
|
||||
"name": "review_votes_data",
|
||||
"type": "TEXT",
|
||||
"unsigned": false,
|
||||
"values": [],
|
||||
"zerofill": false
|
||||
},
|
||||
"review_approved": {
|
||||
"allow_null": false,
|
||||
"auto_increment": false,
|
||||
"binary": false,
|
||||
"comment": "Review is approved?",
|
||||
"decimals": null,
|
||||
"default": "1",
|
||||
"length": 1,
|
||||
"name": "review_approved",
|
||||
"type": "TINYINT",
|
||||
"unsigned": false,
|
||||
"values": [],
|
||||
"zerofill": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"PRIMARY": {
|
||||
"type": "primary",
|
||||
"name": "PRIMARY",
|
||||
"length": [
|
||||
null
|
||||
],
|
||||
"columns": [
|
||||
"review_id"
|
||||
]
|
||||
},
|
||||
"review_eid": {
|
||||
"type": "key",
|
||||
"name": "review_eid",
|
||||
"length": [
|
||||
null
|
||||
],
|
||||
"columns": [
|
||||
"review_eid"
|
||||
]
|
||||
},
|
||||
"review_mid": {
|
||||
"type": "key",
|
||||
"name": "review_mid",
|
||||
"length": [
|
||||
null
|
||||
],
|
||||
"columns": [
|
||||
"review_mid"
|
||||
]
|
||||
},
|
||||
"review_ip": {
|
||||
"type": "key",
|
||||
"name": "review_ip",
|
||||
"columns": [
|
||||
"review_ip"
|
||||
],
|
||||
"length": [
|
||||
null
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"42": {
|
||||
"method": "addIndex",
|
||||
"params": [
|
||||
"calendar_event_comments",
|
||||
{
|
||||
"type": "key",
|
||||
"name": "comment_mid",
|
||||
"columns": [
|
||||
"comment_mid"
|
||||
],
|
||||
"length": [
|
||||
null
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"43": {
|
||||
"method": "addColumn",
|
||||
"params": [
|
||||
"calendar_events",
|
||||
{
|
||||
"name": "event_cover_offset",
|
||||
"type": "INT",
|
||||
"length": null,
|
||||
"decimals": null,
|
||||
"values": [],
|
||||
"allow_null": false,
|
||||
"default": "0",
|
||||
"comment": "",
|
||||
"unsigned": true,
|
||||
"zerofill": false,
|
||||
"auto_increment": false,
|
||||
"binary": false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief 4.0.0 Alpha 1 Upgrade Code
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @subpackage Calendar
|
||||
* @package IPS Social Suite
|
||||
* @since 8 Jan 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\setup\upg_40000;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 4.0.0 Alpha 1 Upgrade Code
|
||||
*/
|
||||
class _Upgrade
|
||||
{
|
||||
/**
|
||||
* Upgrade calendar
|
||||
*
|
||||
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
|
||||
*/
|
||||
public function step1()
|
||||
{
|
||||
\IPS\Db::i()->update( 'calendar_events', array( 'event_recurring' => NULL ), array( 'event_recurring=?', '0' ) );
|
||||
\IPS\Db::i()->update( 'calendar_events', array( 'event_recurring' => "FREQ=yearly;INTERVAL=1" ), array( 'event_recurring=?', '3' ) );
|
||||
\IPS\Db::i()->update( 'calendar_events', array( 'event_recurring' => "FREQ=monthly;INTERVAL=1" ), array( 'event_recurring=?', '2' ) );
|
||||
\IPS\Db::i()->update( 'calendar_events', array( 'event_recurring' => "FREQ=weekly;INTERVAL=1" ), array( 'event_recurring=?', '1' ) );
|
||||
|
||||
\IPS\Db::i()->update( 'calendar_events', "event_recurring=CONCAT( event_recurring, ';UNTIL=', DATE_FORMAT( event_end_date, '%Y%m%dT%k%i%sZ' ) ), event_end_date=NULL", 'event_recurring IS NOT NULL AND event_end_date IS NOT NULL' );
|
||||
|
||||
\IPS\Db::i()->update( 'calendar_events', array( 'event_approved' => 0 ), "event_private=1 or event_perms!='*'" );
|
||||
\IPS\Db::i()->update( 'calendar_events', array( 'event_end_date' => NULL ), array( 'event_end_date=?', '0000-00-00 00:00:00' ) );
|
||||
|
||||
\IPS\Db::i()->dropColumn( 'calendar_events', array( 'event_private', 'event_perms' ) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom title for this step
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function step1CustomTitle()
|
||||
{
|
||||
return "Upgrading calendar events";
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrade calendar
|
||||
*
|
||||
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
|
||||
*/
|
||||
public function step2()
|
||||
{
|
||||
foreach( \IPS\Db::i()->select( '*', 'calendar_calendars' ) as $calendar )
|
||||
{
|
||||
\IPS\Lang::saveCustom( 'calendar', "calendar_calendar_{$calendar['cal_id']}", html_entity_decode( $calendar['cal_title'], ENT_QUOTES, 'UTF-8' ) );
|
||||
}
|
||||
|
||||
\IPS\Db::i()->dropColumn( 'calendar_calendars', 'cal_title' );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom title for this step
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function step2CustomTitle()
|
||||
{
|
||||
return "Upgrading calendars";
|
||||
}
|
||||
|
||||
/**
|
||||
* Finish - This is run after all apps have been upgraded
|
||||
*
|
||||
* @return mixed If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
|
||||
* @note We opted not to let users run this immediately during the upgrade because of potential issues (it taking a long time and users stopping it or getting frustrated) but we can revisit later
|
||||
*/
|
||||
public function finish()
|
||||
{
|
||||
\IPS\Task::queue( 'core', 'RebuildPosts', array( 'class' => 'IPS\calendar\Event' ), 2 );
|
||||
\IPS\Task::queue( 'core', 'RebuildPosts', array( 'class' => 'IPS\calendar\Event\Comment' ), 2 );
|
||||
\IPS\Task::queue( 'core', 'RebuildPosts', array( 'class' => 'IPS\calendar\Event\Review' ), 2 );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,272 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Calendar Node
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Calendar
|
||||
* @since 18 Dec 2013
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calendar Node
|
||||
*/
|
||||
class _Calendar extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
{
|
||||
/**
|
||||
* @brief [ActiveRecord] Multiton Store
|
||||
*/
|
||||
protected static $multitons;
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Table
|
||||
*/
|
||||
public static $databaseTable = 'calendar_calendars';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Prefix
|
||||
*/
|
||||
public static $databasePrefix = 'cal_';
|
||||
|
||||
/**
|
||||
* @brief [Node] Order Database Column
|
||||
*/
|
||||
public static $databaseColumnOrder = 'position';
|
||||
|
||||
/**
|
||||
* @brief [Node] Node Title
|
||||
*/
|
||||
public static $nodeTitle = 'calendars';
|
||||
|
||||
/**
|
||||
* @brief [Node] ACP Restrictions
|
||||
* @code
|
||||
array(
|
||||
'app' => 'core', // The application key which holds the restrictrions
|
||||
'module' => 'foo', // The module key which holds the restrictions
|
||||
'map' => array( // [Optional] The key for each restriction - can alternatively use "prefix"
|
||||
'add' => 'foo_add',
|
||||
'edit' => 'foo_edit',
|
||||
'permissions' => 'foo_perms',
|
||||
'delete' => 'foo_delete'
|
||||
),
|
||||
'all' => 'foo_manage', // [Optional] The key to use for any restriction not provided in the map (only needed if not providing all 4)
|
||||
'prefix' => 'foo_', // [Optional] Rather than specifying each key in the map, you can specify a prefix, and it will automatically look for restrictions with the key "[prefix]_add/edit/permissions/delete"
|
||||
* @endcode
|
||||
*/
|
||||
protected static $restrictions = array(
|
||||
'app' => 'calendar',
|
||||
'module' => 'calendars',
|
||||
'prefix' => 'calendars_'
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief [Node] App for permission index
|
||||
*/
|
||||
public static $permApp = 'calendar';
|
||||
|
||||
/**
|
||||
* @brief [Node] Type for permission index
|
||||
*/
|
||||
public static $permType = 'calendar';
|
||||
|
||||
/**
|
||||
* @brief The map of permission columns
|
||||
*/
|
||||
public static $permissionMap = array(
|
||||
'view' => 'view',
|
||||
'read' => 2,
|
||||
'add' => 3,
|
||||
'reply' => 4,
|
||||
'review' => 7,
|
||||
'askrsvp' => 5,
|
||||
'rsvp' => 6,
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief [Node] Title prefix. If specified, will look for a language key with "{$key}_title" as the key
|
||||
*/
|
||||
public static $titleLangPrefix = 'calendar_calendar_';
|
||||
|
||||
/**
|
||||
* @brief [Node] Moderator Permission
|
||||
*/
|
||||
public static $modPerm = 'calendar_calendars';
|
||||
|
||||
/**
|
||||
* @brief Content Item Class
|
||||
*/
|
||||
public static $contentItemClass = 'IPS\calendar\Event';
|
||||
|
||||
/**
|
||||
* @brief [Node] Prefix string that is automatically prepended to permission matrix language strings
|
||||
*/
|
||||
public static $permissionLangPrefix = 'calperm_';
|
||||
|
||||
/**
|
||||
* [Node] Set whether or not this node is enabled
|
||||
*
|
||||
* @param bool|int $enabled Whether to set it enabled or disabled
|
||||
* @return void
|
||||
*/
|
||||
protected function set__enabled( $enabled )
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Get SEO name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_title_seo()
|
||||
{
|
||||
if( !$this->_data['title_seo'] )
|
||||
{
|
||||
$this->title_seo = \IPS\Http\Url::seoTitle( \IPS\Lang::load( \IPS\Lang::defaultLanguage() )->get( 'calendar_calendar_' . $this->id ) );
|
||||
$this->save();
|
||||
}
|
||||
|
||||
return $this->_data['title_seo'] ?: \IPS\Http\Url::seoTitle( \IPS\Lang::load( \IPS\Lang::defaultLanguage() )->get( 'calendar_calendar_' . $this->id ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Add/Edit Form
|
||||
*
|
||||
* @param \IPS\Helpers\Form $form The form
|
||||
* @return void
|
||||
*/
|
||||
public function form( &$form )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Translatable( 'cal_title', NULL, TRUE, array( 'app' => 'calendar', 'key' => ( $this->id ? "calendar_calendar_{$this->id}" : NULL ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Color( 'cal_color', $this->id ? $this->color : $this->_generateColor(), TRUE ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'cal_moderate', $this->id ? $this->moderate : FALSE, FALSE ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'cal_allow_comments', $this->id ? $this->allow_comments : TRUE, FALSE, array( 'togglesOn' => array( 'cal_comment_moderate' ) ) ) );
|
||||
$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' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Format form values from add/edit form for save
|
||||
*
|
||||
* @param array $values Values from the form
|
||||
* @return array
|
||||
*/
|
||||
public function formatFormValues( $values )
|
||||
{
|
||||
if ( !$this->id )
|
||||
{
|
||||
$this->save();
|
||||
}
|
||||
|
||||
if( isset( $values['cal_title'] ) )
|
||||
{
|
||||
\IPS\Lang::saveCustom( 'calendar', 'calendar_calendar_' . $this->id, $values['cal_title'] );
|
||||
$values['title_seo'] = \IPS\Http\Url::seoTitle( $values['cal_title'][ \IPS\Lang::defaultLanguage() ] );
|
||||
|
||||
unset( $values['cal_title'] );
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Cached URL
|
||||
*/
|
||||
protected $_url = NULL;
|
||||
|
||||
/**
|
||||
* Get URL
|
||||
*
|
||||
* @return \IPS\Http\Url
|
||||
*/
|
||||
public function url()
|
||||
{
|
||||
if( $this->_url === NULL )
|
||||
{
|
||||
$this->_url = \IPS\Http\Url::internal( "app=calendar&module=calendar&controller=view&id={$this->_id}", 'front', 'calendar_calendar', $this->title_seo );
|
||||
}
|
||||
|
||||
return $this->_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* [ActiveRecord] Delete Record
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
\IPS\Db::i()->delete( 'calendar_import_feeds', array( 'feed_calendar_id=?', $this->id ) );
|
||||
|
||||
return parent::delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Default colors
|
||||
*/
|
||||
protected static $colors = array(
|
||||
'#6E4F99', // Purple
|
||||
'#4F994F', // Green
|
||||
'#4F7C99', // Blue
|
||||
'#F3F781', // Yellow
|
||||
'#DF013A', // Red
|
||||
'#FFBF00', // Orange
|
||||
);
|
||||
|
||||
/**
|
||||
* Grab the next available color
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function _generateColor()
|
||||
{
|
||||
foreach( static::$colors as $color )
|
||||
{
|
||||
foreach( static::roots( NULL ) as $calendar )
|
||||
{
|
||||
if( mb_strtolower( $color ) == mb_strtolower( $calendar->color ) )
|
||||
{
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
|
||||
return $color;
|
||||
}
|
||||
|
||||
/* If we're still here, all of our pre-defined codes are used...generate something random */
|
||||
return '#' . str_pad( dechex( mt_rand( 0, 255 ) ), 2, '0', STR_PAD_LEFT ) .
|
||||
str_pad( dechex( mt_rand( 0, 255 ) ), 2, '0', STR_PAD_LEFT ) .
|
||||
str_pad( dechex( mt_rand( 0, 255 ) ), 2, '0', STR_PAD_LEFT );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the appropriate CSS to the page output
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function addCss()
|
||||
{
|
||||
$output = '';
|
||||
|
||||
foreach( static::roots() as $calendar )
|
||||
{
|
||||
$output .= "a.cEvents_style{$calendar->id}, .cEvents_style{$calendar->id} a, .cCalendarIcon.cEvents_style{$calendar->id} {
|
||||
background-color: {$calendar->color};
|
||||
}\n";
|
||||
}
|
||||
|
||||
\IPS\Output::i()->headCss = \IPS\Output::i()->headCss . $output;
|
||||
}
|
||||
}
|
||||
Whitespace-only changes.
@@ -0,0 +1,734 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Calendar-specific date functions
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Calendar
|
||||
* @since 30 Dec 2013
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calendar-specific date functions
|
||||
*/
|
||||
class _Date extends \IPS\DateTime
|
||||
{
|
||||
/**
|
||||
* @brief Data retrieved from get_date() with timezone accounted for
|
||||
*/
|
||||
protected $dateInformation = array();
|
||||
|
||||
/**
|
||||
* @brief Information about the first day of the month we are working with
|
||||
*/
|
||||
protected $firstDayOfMonth = array();
|
||||
|
||||
/**
|
||||
* @brief Information about the last day of the month we are working with
|
||||
*/
|
||||
protected $lastDayOfMonth = array();
|
||||
|
||||
/**
|
||||
* @brief Information about the first day of the week we are working with
|
||||
*/
|
||||
protected $firstDayOfWeek = array();
|
||||
|
||||
/**
|
||||
* @brief Information about the last day of the week we are working with
|
||||
*/
|
||||
protected $lastDayOfWeek = array();
|
||||
|
||||
/**
|
||||
* @brief Information about the previous month
|
||||
*/
|
||||
protected $lastMonth = array();
|
||||
|
||||
/**
|
||||
* @brief Information about the next month
|
||||
*/
|
||||
protected $nextMonth = array();
|
||||
|
||||
/**
|
||||
* @brief Timezone offset for the current user
|
||||
*/
|
||||
public $offset = NULL;
|
||||
|
||||
/**
|
||||
* @brief Custom date formatting options for calendar
|
||||
*/
|
||||
public static $dateFormats = array(
|
||||
'locale' => "%x",
|
||||
'd_sm_y' => "%d %b %Y",
|
||||
'd_lm_y' => "%d %B %Y",
|
||||
'sm_d_y' => "%b %d, %Y",
|
||||
'lm_d_y' => "%B %d, %Y",
|
||||
);
|
||||
|
||||
/**
|
||||
* Creates a new object to represent the requested date
|
||||
*
|
||||
* @param int|NULL $year Year, or NULL for current year
|
||||
* @param int|NULL $month Month, or NULL for current month
|
||||
* @param int|NULL $day Day, or NULL for current day
|
||||
* @param int $hour Hour (defaults to 0)
|
||||
* @param int $minute Minutes (defaults to 0)
|
||||
* @param int $second Seconds (defaults to 0)
|
||||
* @param int $offset The offset from GMT (NULL to calculate automatically based on member's current time)
|
||||
* @return \IPS\calendar\Date
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public static function getDate( $year=NULL, $month=NULL, $day=NULL, $hour=0, $minute=0, $second=0, $offset=0 )
|
||||
{
|
||||
/* Get our time zone offset */
|
||||
if ( !$offset and \IPS\Member::loggedIn()->timezone )
|
||||
{
|
||||
$offset = \IPS\DateTime::create()->setTimezone( new \DateTimeZone( \IPS\Member::loggedIn()->timezone ) )->getOffset();
|
||||
}
|
||||
|
||||
/* Set appropriate defaults for values not supplied, which is normal */
|
||||
if( $year === NULL )
|
||||
{
|
||||
$year = date( 'Y', time() + $offset );
|
||||
}
|
||||
|
||||
if( $day === NULL )
|
||||
{
|
||||
$day = ( $month !== NULL ) ? 1 : date( 'd', time() + $offset );
|
||||
}
|
||||
|
||||
if( $month === NULL )
|
||||
{
|
||||
$month = date( 'm', time() + $offset );
|
||||
}
|
||||
|
||||
/* If the date is not valid, that means a bad value was supplied */
|
||||
if( !checkdate( $month, $day, $year ) )
|
||||
{
|
||||
throw new \InvalidArgumentException;
|
||||
}
|
||||
|
||||
/* Create the timestamp */
|
||||
$timeStamp = gmmktime( $hour, $minute, $second, $month, $day, $year );
|
||||
|
||||
/* Store the information and return the object */
|
||||
$obj = static::ts( $timeStamp - $offset );
|
||||
$obj->dateInformation = getdate( $timeStamp );
|
||||
$obj->offset = $offset;
|
||||
|
||||
return $obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new datetime object
|
||||
*
|
||||
* @note We override to update dateInformation and stored offset
|
||||
* @param string $time Time
|
||||
* @param \DateTimeZone|null $timezone Timezone
|
||||
* @return \IPS\calendar\Date
|
||||
*/
|
||||
public function __construct( $time="now", $timezone=NULL )
|
||||
{
|
||||
if ( $timezone )
|
||||
{
|
||||
$result = parent::__construct( $time, $timezone );
|
||||
}
|
||||
else
|
||||
{
|
||||
$result = parent::__construct( $time );
|
||||
}
|
||||
|
||||
$this->dateInformation = getdate( $this->getTimestamp() );
|
||||
$this->offset = $this->getOffset();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the time zone for the DateTime object
|
||||
*
|
||||
* @note We override to update dateInformation and stored offset
|
||||
* @param \DateTimeZone $timezone New timezone
|
||||
* @return \IPS\calendar\Date|FALSE
|
||||
*/
|
||||
public function setTimezone( $timezone )
|
||||
{
|
||||
$result = parent::setTimezone( $timezone );
|
||||
|
||||
$this->dateInformation = getdate( $this->getTimestamp() );
|
||||
$this->offset = $this->getOffset();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a date object created based on an arbitrary string. Used for both relative time strings and SQL datetime values.
|
||||
*
|
||||
* @note Datetime values are stored in the database normalized to UTC
|
||||
* @param string $datetime String-based date/time
|
||||
* @param bool $forceUTC Force timezone to UTC (necessary when passing a datetime retrieved from the database)
|
||||
* @return \IPS\calendar\Date
|
||||
*/
|
||||
public static function parseTime( $datetime, $forceUTC=FALSE )
|
||||
{
|
||||
/* Create an \IPS\DateTime object from the datetime value passed in */
|
||||
$timezone = ( $forceUTC === TRUE ) ? new \DateTimeZone( 'UTC' ) : ( \IPS\Member::loggedIn()->timezone ? new \DateTimeZone( \IPS\Member::loggedIn()->timezone ) : NULL );
|
||||
$datetime = new \IPS\DateTime( $datetime, $timezone );
|
||||
|
||||
/* Now correct it back if necessary */
|
||||
if( $forceUTC === TRUE AND \IPS\Member::loggedIn()->timezone )
|
||||
{
|
||||
$datetime->setTimezone( new \DateTimeZone( \IPS\Member::loggedIn()->timezone ) );
|
||||
}
|
||||
|
||||
return static::getDate( $datetime->format('Y'), $datetime->format('m'), $datetime->format('d'), $datetime->format('H'), $datetime->format('i'), $datetime->format('s'), $datetime->getOffset() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts the date and returns a new date object representing the adjustment
|
||||
*
|
||||
* @param string $adjustment String to turn into a \DateInterval object which will be applied to the current date/time (supports most strtotime adjustments)
|
||||
* @return \IPS\calendar\Date
|
||||
* @see <a href='http://www.php.net/manual/en/dateinterval.createfromdatestring.php'>DateInterval::createFromDateString() docs</a>
|
||||
*/
|
||||
public function adjust( $adjustment )
|
||||
{
|
||||
$datetime = \IPS\DateTime::ts( $this->dateInformation[0] )->setTimezone( new \DateTimeZone( "UTC" ) );
|
||||
$datetime->add( \DateInterval::createFromDateString( $adjustment ) );
|
||||
|
||||
return static::getDate( gmdate( 'Y', $datetime->getTimestamp() ), gmdate( 'm', $datetime->getTimestamp() ), gmdate( 'd', $datetime->getTimestamp() ), gmdate( 'H', $datetime->getTimestamp() ), gmdate( 'i', $datetime->getTimestamp() ), gmdate( 's', $datetime->getTimestamp() ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the localized day names in correct order
|
||||
*
|
||||
* @return array
|
||||
* @see <a href='http://stackoverflow.com/questions/7765469/retrieving-day-names-in-php'>Get localized day names in PHP</a>
|
||||
*/
|
||||
public static function getDayNames()
|
||||
{
|
||||
$dayNames = array();
|
||||
$startDay = \IPS\Settings::i()->ipb_calendar_mon ? 'Monday' : 'Sunday';
|
||||
|
||||
for( $i = 0; $i < 7; $i++ )
|
||||
{
|
||||
$_time = strtotime( 'next ' . $startDay . ' +' . $i . ' days' );
|
||||
$_abbr = \IPS\Member::loggedIn()->language()->convertString( strftime( '%a', $_time ) );
|
||||
|
||||
$dayNames[] = array( 'full' => \IPS\Member::loggedIn()->language()->convertString( strftime( '%A', $_time ) ), 'english' => date( 'l', $_time ), 'abbreviated' => $_abbr, 'letter' => mb_substr( $_abbr, 0, 1 ), 'ical' => mb_strtoupper( mb_substr( date( 'D', $_time ), 0, 2 ) ) );
|
||||
}
|
||||
|
||||
return $dayNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief List of timezones and the PHP timezone IDs to utilize. Note that this is only used during submit.
|
||||
*/
|
||||
public static $timezones = array(
|
||||
'-12',
|
||||
'-11',
|
||||
'-10',
|
||||
'-9.5',
|
||||
'-9',
|
||||
'-8',
|
||||
'-7',
|
||||
'-6',
|
||||
'-5',
|
||||
'-4.5',
|
||||
'-4',
|
||||
'-3.5',
|
||||
'-3',
|
||||
'-2',
|
||||
'-1',
|
||||
'0',
|
||||
'1',
|
||||
'2',
|
||||
'3',
|
||||
'3.5',
|
||||
'4',
|
||||
'4.5',
|
||||
'5',
|
||||
'5.5',
|
||||
'5.75',
|
||||
'6',
|
||||
'6.5',
|
||||
'7',
|
||||
'8',
|
||||
'9',
|
||||
'9.5',
|
||||
'10',
|
||||
'10.5',
|
||||
'11',
|
||||
'11.5',
|
||||
'12',
|
||||
'12.75',
|
||||
'13',
|
||||
'14',
|
||||
);
|
||||
|
||||
/**
|
||||
* Get an array of time zones with GMT offset information supplied in a user-friendly format
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getTimezones()
|
||||
{
|
||||
$return = array();
|
||||
|
||||
if( \IPS\Member::loggedIn()->timezone )
|
||||
{
|
||||
$return[ \IPS\Member::loggedIn()->timezone ] = array( 'text' => \IPS\Member::loggedIn()->timezone, 'short' => \IPS\Member::loggedIn()->timezone );
|
||||
}
|
||||
|
||||
foreach( static::$timezones as $_offset )
|
||||
{
|
||||
$sprintf = ( \strpos( $_offset, '-' ) === 0 ) ? '- ' . \substr( $_offset, 1 ) : '+ ' . $_offset;
|
||||
$return[ $_offset !== '0' ? $_offset : 'GMT' ] = array( 'text' => \IPS\Member::loggedIn()->language()->addToStack('timezone_offset_' . $_offset ), 'short' => \IPS\Member::loggedIn()->language()->addToStack('timezone_offset_short', FALSE, array( 'sprintf' => array( $sprintf ) ) ) );
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a date object based on supplied values, factoring in the timezone offset which could be in the "friendly" timezone format
|
||||
*
|
||||
* @param string $date Date as a textual string, from the date form helper
|
||||
* @param string $time Time as a textual string
|
||||
* @param string $timezone Timezone chosen
|
||||
* @return \IPS\calendar\Date
|
||||
*/
|
||||
public static function createFromForm( $date, $time, $timezone )
|
||||
{
|
||||
/* Correct date */
|
||||
$date = \IPS\Helpers\Form\Date::_convertDateFormat( $date );
|
||||
|
||||
/* Fix time inconsistencies */
|
||||
if( $time )
|
||||
{
|
||||
$time = mb_strtolower( $time );
|
||||
|
||||
/* If they typed in 'am', convert '12' to 00, and then strip 'am' */
|
||||
if( \strpos( $time, 'am' ) !== FALSE )
|
||||
{
|
||||
if( \strpos( $time, '12' ) === 0 )
|
||||
{
|
||||
$time = substr_replace( $time, '00', 0, 2 );
|
||||
}
|
||||
|
||||
$time = str_replace( 'am', '', $time );
|
||||
}
|
||||
/* If they typed in 'pm', add 12 to anything other than 12 and strip 'pm' */
|
||||
else if( \strpos( $time, 'pm' ) !== FALSE )
|
||||
{
|
||||
$_timeBits = explode( ':', $time );
|
||||
$_timeBits[0] = $_timeBits[0] < 12 ? ( $_timeBits[0] + 12 ) : $_timeBits[0];
|
||||
$time = implode( ':', $_timeBits );
|
||||
|
||||
$time = str_replace( 'pm', '', $time );
|
||||
}
|
||||
|
||||
/* Make sure we have 3 pieces and that all are 2 digits */
|
||||
$_timeBits = explode( ':', $time );
|
||||
|
||||
if ( count( $_timeBits ) < 3 )
|
||||
{
|
||||
while( count( $_timeBits ) < 3 )
|
||||
{
|
||||
$_timeBits[] = '00';
|
||||
}
|
||||
}
|
||||
|
||||
foreach( $_timeBits as $k => $v )
|
||||
{
|
||||
$_timeBits[ $k ] = str_pad( trim( $v ), 2, '0', STR_PAD_LEFT );
|
||||
}
|
||||
|
||||
/* Avengers assemble! */
|
||||
$time = implode( ':', $_timeBits );
|
||||
}
|
||||
|
||||
/* Default timezone - fairly straightforward */
|
||||
if( \IPS\Member::loggedIn()->timezone AND $timezone == \IPS\Member::loggedIn()->timezone )
|
||||
{
|
||||
$dateObject = new static( $date . ( $time ? ' ' . $time : '' ), new \DateTimeZone( \IPS\Member::loggedIn()->timezone ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If time is supplied, we are going to create a date-time string containing timezone offset info, so reformat date since it might be m/d/yyyy for instance */
|
||||
$date = new static( $date, \IPS\Member::loggedIn()->timezone ? new \DateTimeZone( \IPS\Member::loggedIn()->timezone ) : NULL );
|
||||
$date = $date->format( 'Y-m-d' );
|
||||
|
||||
/* Reformat the time to give us what we want */
|
||||
if( $time )
|
||||
{
|
||||
if( $timezone == 'GMT' )
|
||||
{
|
||||
$time = 'T' . $time . '+00:00';
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Handle incrementals */
|
||||
$timezone = str_replace( array( '.5', '.75' ), array( ':30', ':45' ), $timezone );
|
||||
$timezone = explode( ':', $timezone );
|
||||
|
||||
$hours = ( mb_substr( $timezone[0], 0, 1 ) == '-' ) ? '-' . str_pad( ltrim( $timezone[0], "-" ), 2, '0', STR_PAD_LEFT ) : '+' . str_pad( $timezone[0], 2, '0', STR_PAD_LEFT );
|
||||
$time = 'T' . $time . $hours .':' . ( isset( $timezone[1] ) ? str_pad( $timezone[1], 2, '0', STR_PAD_LEFT ) : '00' );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$time = 'T00:00:00+00:00';
|
||||
}
|
||||
|
||||
$dateObject = new static( $date . $time );
|
||||
}
|
||||
|
||||
return $dateObject->setTimezone( new \DateTimeZone( 'UTC' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Modified version of ISO-8601 used by iCalendar - omits the timezone identifier and all dashes and colons
|
||||
*
|
||||
* @param bool $includeTime Whether to include time or not
|
||||
* @param bool $includeIdentifier Whether to include 'Z' at the end or not
|
||||
* @return string
|
||||
* @see <a href='http://www.kanzaki.com/docs/ical/dateTime.html'>DateTime explanation</a>
|
||||
*/
|
||||
public function modifiedIso8601( $includeTime=TRUE, $includeIdentifier=FALSE )
|
||||
{
|
||||
if( $includeTime )
|
||||
{
|
||||
return date( 'Ymd', $this->getTimestamp() ) . 'T' . date( 'His', $this->getTimestamp() ) . ( $includeIdentifier ? 'Z' : '' );
|
||||
}
|
||||
else
|
||||
{
|
||||
return date( 'Ymd', $this->getTimestamp() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the date for use in calendar (used instead of localeDate() to allow admin to configure)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function calendarDate()
|
||||
{
|
||||
if( \IPS\Settings::i()->calendar_date_format == -1 AND \IPS\Settings::i()->calendar_date_format_custom )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->convertString( strftime( \IPS\Settings::i()->calendar_date_format_custom, $this->getTimestamp() + $this->getTimezone()->getOffset( $this ) ) );
|
||||
}
|
||||
elseif( isset( static::$dateFormats[ \IPS\Settings::i()->calendar_date_format ] ) )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->convertString( strftime( static::$dateFormats[ \IPS\Settings::i()->calendar_date_format ], $this->getTimestamp() + $this->getTimezone()->getOffset( $this ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return static::localeDate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the MySQL-style datetime value
|
||||
*
|
||||
* @param bool $includeTime Whether to include time or not
|
||||
* @return string
|
||||
*/
|
||||
public function mysqlDatetime( $includeTime=TRUE )
|
||||
{
|
||||
if( $includeTime )
|
||||
{
|
||||
return date( 'Y-m-d H:i:s', isset( $this->dateInformation[0] ) ? $this->dateInformation[0] : $this->getTimestamp() );
|
||||
}
|
||||
else
|
||||
{
|
||||
return date( 'Y-m-d', isset( $this->dateInformation[0] ) ? $this->dateInformation[0] : $this->getTimestamp() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the birthdays for the date
|
||||
*
|
||||
* @param bool $day Whether to limit to the current day or not
|
||||
* @return array
|
||||
*/
|
||||
public function getBirthdays( $day=FALSE )
|
||||
{
|
||||
$birthdays = array();
|
||||
|
||||
/* Is the setting enabled? */
|
||||
if( !\IPS\Settings::i()->show_bday_calendar )
|
||||
{
|
||||
return $birthdays;
|
||||
}
|
||||
|
||||
$where = array( array( 'bday_month=?', $this->mon ) );
|
||||
|
||||
if( $day === TRUE )
|
||||
{
|
||||
if( $this->mon == 2 AND $this->mday == 28 AND !$this->leapYear() )
|
||||
{
|
||||
$where[] = array( 'bday_day IN(28,29)' );
|
||||
}
|
||||
else
|
||||
{
|
||||
$where[] = array( 'bday_day=?', $this->mday );
|
||||
}
|
||||
}
|
||||
|
||||
$members = \IPS\DB::i()->select( '*', 'core_members', $where );
|
||||
|
||||
if( $members->count() )
|
||||
{
|
||||
foreach( $members as $member )
|
||||
{
|
||||
/* If it's not leap year we do the nice thing and show Feb 29th birthdays on Feb 28th */
|
||||
if( $this->mon == 2 AND !$this->leapYear() AND $member['bday_month'] == 2 AND $member['bday_day'] == 29 )
|
||||
{
|
||||
$member['bday_day'] = 28;
|
||||
}
|
||||
|
||||
$member = \IPS\Member::constructFromData( $member );
|
||||
|
||||
$banned = FALSE;
|
||||
|
||||
if ( $member->temp_ban != 0 )
|
||||
{
|
||||
if ( $member->temp_ban > 0 OR $member->temp_ban == -1 )
|
||||
{
|
||||
$banned = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if( !$member->group['g_view_board'] )
|
||||
{
|
||||
$banned = TRUE;
|
||||
}
|
||||
|
||||
if ( !$banned )
|
||||
{
|
||||
$birthdays[ str_pad( $member->bday_month, 2, 0, STR_PAD_LEFT ) . str_pad( $member->bday_day, 2, 0, STR_PAD_LEFT ) ][] = $member;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $birthdays;
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic method to make retrieving certain data easier
|
||||
*
|
||||
* @param mixed $key Value we tried to retrieve
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get( $key )
|
||||
{
|
||||
return $this->_findValue( $key, $this->dateInformation );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve information about the first day of the month
|
||||
*
|
||||
* @param mixed $key Key (from getdate()) we want to retrieve
|
||||
* @return mixed
|
||||
*/
|
||||
public function firstDayOfMonth( $key )
|
||||
{
|
||||
if( !isset( $this->firstDayOfMonth[0] ) )
|
||||
{
|
||||
$this->firstDayOfMonth = getdate( gmmktime( 0, 0, 0, $this->mon, 1, $this->year ) );
|
||||
}
|
||||
|
||||
return $this->_findValue( $key, $this->firstDayOfMonth );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve information about the last day of the month
|
||||
*
|
||||
* @param mixed $key Key (from getdate()) we want to retrieve
|
||||
* @return mixed
|
||||
*/
|
||||
public function lastDayOfMonth( $key )
|
||||
{
|
||||
if( !isset( $this->lastDayOfMonth[0] ) )
|
||||
{
|
||||
$this->lastDayOfMonth = getdate( gmmktime( 0, 0, 0, $this->mon + 1, 0, $this->year ) );
|
||||
}
|
||||
|
||||
return $this->_findValue( $key, $this->lastDayOfMonth );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve information about the previous month
|
||||
*
|
||||
* @param mixed $key Key (from getdate()) we want to retrieve
|
||||
* @return mixed
|
||||
*/
|
||||
public function lastMonth( $key )
|
||||
{
|
||||
if( !isset( $this->lastMonth[0] ) )
|
||||
{
|
||||
$this->lastMonth = getdate( gmmktime( 0, 0, 0, $this->mon - 1, 1, $this->year ) );
|
||||
}
|
||||
|
||||
return $this->_findValue( $key, $this->lastMonth );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve information about the next month
|
||||
*
|
||||
* @param mixed $key Key (from getdate()) we want to retrieve
|
||||
* @return mixed
|
||||
*/
|
||||
public function nextMonth( $key )
|
||||
{
|
||||
if( !isset( $this->nextMonth[0] ) )
|
||||
{
|
||||
$this->nextMonth = getdate( gmmktime( 0, 0, 0, $this->mon + 1, 1, $this->year ) );
|
||||
}
|
||||
|
||||
return $this->_findValue( $key, $this->nextMonth );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve information about the first day of the week we are working with
|
||||
*
|
||||
* @param mixed $key Key (from getdate()) we want to retrieve
|
||||
* @return mixed
|
||||
*/
|
||||
public function firstDayOfWeek( $key )
|
||||
{
|
||||
if( !isset( $this->firstDayOfWeek[0] ) )
|
||||
{
|
||||
$this->firstDayOfWeek = getdate( gmmktime( 0, 0, 0, $this->mon, $this->mday - $this->wday, $this->year ) );
|
||||
}
|
||||
|
||||
return $this->_findValue( $key, $this->firstDayOfWeek );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve information about the last day of the week we are working with
|
||||
*
|
||||
* @param mixed $key Key (from getdate()) we want to retrieve
|
||||
* @return mixed
|
||||
*/
|
||||
public function lastDayOfWeek( $key )
|
||||
{
|
||||
if( !isset( $this->lastDayOfWeek[0] ) )
|
||||
{
|
||||
$this->lastDayOfWeek = getdate( gmmktime( 0, 0, 0, $this->mon, $this->mday + ( 6 - $this->wday ), $this->year ) );
|
||||
}
|
||||
|
||||
return $this->_findValue( $key, $this->lastDayOfWeek );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the date falls in a leap year or not
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function leapYear()
|
||||
{
|
||||
return (bool) gmdate( 'L', $this->dateInformation[0] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the current locale uses AM/PM or 24 hour format
|
||||
*
|
||||
* @return bool
|
||||
* @link <a href='http://stackoverflow.com/questions/6871258/how-to-determine-if-current-locale-has-24-hour-or-12-hour-time-format-in-php'>Check for 24 hour locale use</a>
|
||||
*/
|
||||
public static function usesAmPm()
|
||||
{
|
||||
return ( \substr( gmstrftime( '%X', 57600 ), 0, 2) != 16 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the 12 hour version of an hour value
|
||||
*
|
||||
* @param int Hour The hour value between 0 and 23
|
||||
* @return int
|
||||
*/
|
||||
public static function getTwelveHour( $hour )
|
||||
{
|
||||
if( $hour == 0 )
|
||||
{
|
||||
return 12;
|
||||
}
|
||||
else if( $hour > 12 )
|
||||
{
|
||||
return $hour - 12;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $hour;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the AM/PM value for the current locale
|
||||
*
|
||||
* @param int Hour The hour value between 0 and 23
|
||||
* @return string
|
||||
*/
|
||||
public static function getAmPm( $hour )
|
||||
{
|
||||
return gmstrftime( '%p', $hour * 60 * 60 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a value in the supplied array and return it. Also supports a few 'special' keys.
|
||||
*
|
||||
* @param mixed $key Key (from getdate()) we want to retrieve
|
||||
* @param array $data Array to look for the key in
|
||||
* @return mixed
|
||||
*/
|
||||
protected function _findValue( $key, $data )
|
||||
{
|
||||
if( isset( $data[ $key ] ) )
|
||||
{
|
||||
if( $key == 'wday' AND \IPS\Settings::i()->ipb_calendar_mon )
|
||||
{
|
||||
return ( $data[ $key ] == 0 ) ? 6: ( $data[ $key ] - 1 );
|
||||
}
|
||||
|
||||
if( $key == 'mon' OR $key == 'mday' )
|
||||
{
|
||||
return str_pad( $data[ $key ], 2, '0', STR_PAD_LEFT );
|
||||
}
|
||||
|
||||
return $data[ $key ];
|
||||
}
|
||||
|
||||
if( $key == 'monthName' AND isset( $data[0] ) )
|
||||
{
|
||||
return mb_convert_case( \IPS\Member::loggedIn()->language()->convertString( strftime( '%B', $data[0] ) ), MB_CASE_TITLE );
|
||||
}
|
||||
|
||||
if( $key == 'monthNameShort' AND isset( $data[0] ) )
|
||||
{
|
||||
return mb_convert_case( \IPS\Member::loggedIn()->language()->convertString( strftime( '%b', $data[0] ) ), MB_CASE_TITLE );
|
||||
}
|
||||
|
||||
if( $key == 'dayName' AND isset( $data[0] ) )
|
||||
{
|
||||
return mb_convert_case( \IPS\Member::loggedIn()->language()->convertString( strftime( '%A', $data[0] ) ), MB_CASE_TITLE );
|
||||
}
|
||||
|
||||
if( $key == 'dayNameShort' AND isset( $data[0] ) )
|
||||
{
|
||||
return mb_convert_case( \IPS\Member::loggedIn()->language()->convertString( strftime( '%a', $data[0] ) ), MB_CASE_TITLE );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
Whitespace-only changes.
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Event Comment Model
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Calendar
|
||||
* @since 7 Jan 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\Event;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Event Comment Model
|
||||
*/
|
||||
class _Comment extends \IPS\Content\Comment implements \IPS\Content\EditHistory, \IPS\Content\ReportCenter, \IPS\Content\Hideable, \IPS\Content\Reputation, \IPS\Content\Searchable, \IPS\Content\Embeddable
|
||||
{
|
||||
/**
|
||||
* @brief [ActiveRecord] Multiton Store
|
||||
*/
|
||||
protected static $multitons;
|
||||
|
||||
/**
|
||||
* @brief [Content\Comment] Item Class
|
||||
*/
|
||||
public static $itemClass = 'IPS\calendar\Event';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Table
|
||||
*/
|
||||
public static $databaseTable = 'calendar_event_comments';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Prefix
|
||||
*/
|
||||
public static $databasePrefix = 'comment_';
|
||||
|
||||
/**
|
||||
* @brief Database Column Map
|
||||
*/
|
||||
public static $databaseColumnMap = array(
|
||||
'item' => 'eid',
|
||||
'author' => 'mid',
|
||||
'author_name' => 'author',
|
||||
'content' => 'text',
|
||||
'date' => 'date',
|
||||
'ip_address' => 'ip_address',
|
||||
'edit_time' => 'edit_time',
|
||||
'edit_member_name' => 'edit_name',
|
||||
'edit_show' => 'append_edit',
|
||||
'approved' => 'approved'
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Application
|
||||
*/
|
||||
public static $application = 'calendar';
|
||||
|
||||
/**
|
||||
* @brief Title
|
||||
*/
|
||||
public static $title = 'calendar_event_comment';
|
||||
|
||||
/**
|
||||
* @brief Icon
|
||||
*/
|
||||
public static $icon = 'calendar';
|
||||
|
||||
/**
|
||||
* @brief Reputation Type
|
||||
*/
|
||||
public static $reputationType = 'comment_id';
|
||||
|
||||
/**
|
||||
* @brief [Content] Key for hide reasons
|
||||
*/
|
||||
public static $hideLogKey = 'calendar-events';
|
||||
|
||||
/**
|
||||
* Get URL for doing stuff
|
||||
*
|
||||
* @param string|NULL $action Action
|
||||
* @return \IPS\Http\Url
|
||||
*/
|
||||
public function url( $action=NULL )
|
||||
{
|
||||
return parent::url( $action )->setQueryString( 'tab', 'comments' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get template for content tables
|
||||
*
|
||||
* @return callable
|
||||
*/
|
||||
public static function contentTableTemplate()
|
||||
{
|
||||
return array( \IPS\Theme::i()->getTemplate( 'tables', 'core' ), 'commentRows' );
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Event Review Model
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Calendar
|
||||
* @since 7 Jan 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\Event;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Event Review Model
|
||||
*/
|
||||
class _Review extends \IPS\Content\Review implements \IPS\Content\EditHistory, \IPS\Content\ReportCenter, \IPS\Content\Hideable, \IPS\Content\Reputation, \IPS\Content\Searchable, \IPS\Content\Embeddable
|
||||
{
|
||||
/**
|
||||
* @brief [ActiveRecord] Multiton Store
|
||||
*/
|
||||
protected static $multitons;
|
||||
|
||||
/**
|
||||
* @brief [Content\Comment] Item Class
|
||||
*/
|
||||
public static $itemClass = 'IPS\calendar\Event';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Table
|
||||
*/
|
||||
public static $databaseTable = 'calendar_event_reviews';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Prefix
|
||||
*/
|
||||
public static $databasePrefix = 'review_';
|
||||
|
||||
/**
|
||||
* @brief Database Column Map
|
||||
*/
|
||||
public static $databaseColumnMap = array(
|
||||
'item' => 'eid',
|
||||
'author' => 'mid',
|
||||
'author_name' => 'author_name',
|
||||
'content' => 'text',
|
||||
'date' => 'date',
|
||||
'ip_address' => 'ip',
|
||||
'edit_time' => 'edit_time',
|
||||
'edit_member_name' => 'edit_name',
|
||||
'edit_show' => 'append_edit',
|
||||
'rating' => 'rating',
|
||||
'votes_total' => 'votes',
|
||||
'votes_helpful' => 'votes_helpful',
|
||||
'votes_data' => 'votes_data',
|
||||
'approved' => 'approved',
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Application
|
||||
*/
|
||||
public static $application = 'calendar';
|
||||
|
||||
/**
|
||||
* @brief Title
|
||||
*/
|
||||
public static $title = 'calendar_event_review';
|
||||
|
||||
/**
|
||||
* @brief Icon
|
||||
*/
|
||||
public static $icon = 'calendar';
|
||||
|
||||
/**
|
||||
* @brief Reputation Type
|
||||
*/
|
||||
public static $reputationType = 'review_id';
|
||||
|
||||
/**
|
||||
* @brief [Content] Key for hide reasons
|
||||
*/
|
||||
public static $hideLogKey = 'calendar-events-rev';
|
||||
|
||||
/**
|
||||
* Get URL for doing stuff
|
||||
*
|
||||
* @param string|NULL $action Action
|
||||
* @return \IPS\Http\Url
|
||||
*/
|
||||
public function url( $action=NULL )
|
||||
{
|
||||
return parent::url( $action )->setQueryString( 'tab', 'reviews' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get template for content tables
|
||||
*
|
||||
* @return callable
|
||||
*/
|
||||
public static function contentTableTemplate()
|
||||
{
|
||||
return array( \IPS\Theme::i()->getTemplate( 'tables', 'core' ), 'commentRows' );
|
||||
}
|
||||
}
|
||||
Whitespace-only changes.
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief iCalendar active record
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Calendar
|
||||
* @since 19 Dec 2013
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* iCalendar active record
|
||||
*/
|
||||
class _Icalendar extends \IPS\Patterns\ActiveRecord
|
||||
{
|
||||
/**
|
||||
* @brief [ActiveRecord] Multiton Store
|
||||
*/
|
||||
protected static $multitons;
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Table
|
||||
*/
|
||||
public static $databaseTable = 'calendar_import_feeds';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Prefix
|
||||
*/
|
||||
public static $databasePrefix = 'feed_';
|
||||
|
||||
/**
|
||||
* Set Default Values
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setDefaultValues()
|
||||
{
|
||||
$this->added = time();
|
||||
$this->lastupdated = time();
|
||||
$this->last_run = time();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reimport iCalendar events
|
||||
*
|
||||
* @return int
|
||||
* @throws \UnexpectedValueException
|
||||
* @note PHP installs do not (at least typically) have stream wrappers for webcal://, so we have to change the scheme to http://
|
||||
*/
|
||||
public function refresh()
|
||||
{
|
||||
$this->last_run = time();
|
||||
$this->save();
|
||||
|
||||
$icsParser = new \IPS\calendar\Icalendar\ICSParser;
|
||||
|
||||
return $icsParser->parse( \IPS\Http\Url::external( str_replace( array( 'webcal://', 'webcals://' ), array( 'http://', 'https://' ), $this->url ) )->request()->get(), $this->calendar_id, $this->member_id, $this->id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete events imported from an iCalendar feed
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function deleteFeedEvents()
|
||||
{
|
||||
/* Looping over all event IDs this feed has imported, delete them */
|
||||
foreach( \IPS\Db::i()->select( '*', 'calendar_import_map', array( 'import_feed_id=?', $this->id ) ) as $mappedEvent )
|
||||
{
|
||||
\IPS\calendar\Event::load( $mappedEvent['import_event_id'] )->delete();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [ActiveRecord] Delete Record
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
\IPS\Db::i()->delete( 'calendar_import_map', array( 'import_feed_id=?', $this->id ) );
|
||||
return parent::delete();
|
||||
}
|
||||
}
|
||||
Whitespace-only changes.
Whitespace-only changes.
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief icalendar Task
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage calendar
|
||||
* @since 18 Dec 2013
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\tasks;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* icalendar Task
|
||||
*/
|
||||
class _icalendar extends \IPS\Task
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* If ran successfully, should return anything worth logging. Only log something
|
||||
* worth mentioning (don't log "task ran successfully"). Return NULL (actual NULL, not '' or 0) to not log (which will be most cases).
|
||||
* If an error occurs which means the task could not finish running, throw an \IPS\Task\Exception - do not log an error as a normal log.
|
||||
* Tasks should execute within the time of a normal HTTP request.
|
||||
*
|
||||
* @return mixed Message to log or NULL
|
||||
* @throws \IPS\Task\Exception
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
try
|
||||
{
|
||||
$next = \IPS\Db::i()->select( '*', 'calendar_import_feeds', NULL, 'feed_last_run ASC', 1 )->first();
|
||||
|
||||
if( $next['feed_id'] )
|
||||
{
|
||||
/* Refresh the feed */
|
||||
try
|
||||
{
|
||||
$count = \IPS\calendar\Icalendar::load( $next['feed_id'] )->refresh();
|
||||
}
|
||||
catch( \Exception $e )
|
||||
{
|
||||
throw new \IPS\Task\Exception( $this, \IPS\Member::loggedIn()->language()->addToStack( 'task_' . $e->getMessage(), FALSE, array( 'sprintf' => array( $next['feed_title'] ) ) ) );
|
||||
}
|
||||
|
||||
/* Task log */
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'acplog__icalfeed_refreshed', FALSE, array( 'sprintf' => array( $count['imported'], $count['skipped'] ) ) );
|
||||
}
|
||||
}
|
||||
catch( \UnderflowException $e )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup
|
||||
*
|
||||
* If your task takes longer than 15 minutes to run, this method
|
||||
* will be called before execute(). Use it to clean up anything which
|
||||
* may not have been done
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function cleanup()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
Whitespace-only changes.
Whitespace-only changes.
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Recent event reviews Widget
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Calendar
|
||||
* @since 19 Feb 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\widgets;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recent event reviews Widget
|
||||
*/
|
||||
class _recentReviews extends \IPS\Widget\PermissionCache
|
||||
{
|
||||
/**
|
||||
* @brief Widget Key
|
||||
*/
|
||||
public $key = 'recentReviews';
|
||||
|
||||
/**
|
||||
* @brief App
|
||||
*/
|
||||
public $app = 'calendar';
|
||||
|
||||
/**
|
||||
* @brief Plugin
|
||||
*/
|
||||
public $plugin = '';
|
||||
|
||||
/**
|
||||
* Specify widget configuration
|
||||
*
|
||||
* @param null|\IPS\Helpers\Form $form Form object
|
||||
* @return null|\IPS\Helpers\Form
|
||||
*/
|
||||
public function configuration( &$form=null )
|
||||
{
|
||||
if ( $form === null )
|
||||
{
|
||||
$form = new \IPS\Helpers\Form;
|
||||
}
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'review_count', isset( $this->configuration['review_count'] ) ? $this->configuration['review_count'] : 5, TRUE ) );
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a widget
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
if( !\IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'calendar', 'calendar' ) ) )
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
$reviews = \IPS\calendar\Event\Review::getItemsWithPermission( array(), NULL, ( isset( $this->configuration['review_count'] ) AND $this->configuration['review_count'] > 0 ) ? $this->configuration['review_count'] : 5 );
|
||||
|
||||
return $this->output( $reviews );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief todaysBirthdays Widget
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage calendar
|
||||
* @since 18 Dec 2013
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\widgets;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* todaysBirthdays Widget
|
||||
*/
|
||||
class _todaysBirthdays extends \IPS\Widget
|
||||
{
|
||||
/**
|
||||
* @brief Widget Key
|
||||
*/
|
||||
public $key = 'todaysBirthdays';
|
||||
|
||||
/**
|
||||
* @brief App
|
||||
*/
|
||||
public $app = 'calendar';
|
||||
|
||||
/**
|
||||
* @brief Plugin
|
||||
*/
|
||||
public $plugin = '';
|
||||
|
||||
/**
|
||||
* Specify widget configuration
|
||||
*
|
||||
* @param null|\IPS\Helpers\Form $form Form object
|
||||
* @return null|\IPS\Helpers\Form
|
||||
*/
|
||||
public function configuration( &$form=null )
|
||||
{
|
||||
if ( $form === null )
|
||||
{
|
||||
$form = new \IPS\Helpers\Form;
|
||||
}
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'auto_hide', isset( $this->configuration['auto_hide'] ) ? $this->configuration['auto_hide'] : FALSE, FALSE ) );
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a widget
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
if( !\IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'calendar', 'calendar' ) ) )
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
$date = \IPS\calendar\Date::getDate();
|
||||
$birthdays = $date->getBirthdays( TRUE );
|
||||
|
||||
if( !isset( $birthdays[ $date->mon . $date->mday ] ) )
|
||||
{
|
||||
$birthdays[ $date->mon . $date->mday ] = array();
|
||||
}
|
||||
|
||||
/* Auto hiding? */
|
||||
if( !count( $birthdays[ $date->mon . $date->mday ] ) AND isset( $this->configuration['auto_hide'] ) AND $this->configuration['auto_hide'] )
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
return $this->output( $birthdays[ $date->mon . $date->mday ] );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief upcomingEvents Widget
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage calendar
|
||||
* @since 18 Dec 2013
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\widgets;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* upcomingEvents Widget
|
||||
*/
|
||||
class _upcomingEvents extends \IPS\Widget\PermissionCache
|
||||
{
|
||||
/**
|
||||
* @brief Widget Key
|
||||
*/
|
||||
public $key = 'upcomingEvents';
|
||||
|
||||
/**
|
||||
* @brief App
|
||||
*/
|
||||
public $app = 'calendar';
|
||||
|
||||
/**
|
||||
* @brief Plugin
|
||||
*/
|
||||
public $plugin = '';
|
||||
|
||||
/**
|
||||
* @brief Cache Expiration
|
||||
* @note We allow this cache to be valid for 12 hours
|
||||
*/
|
||||
public $cacheExpiration = 43200;
|
||||
|
||||
/**
|
||||
* Initialize this widget
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'calendar.css', 'calendar' ) );
|
||||
|
||||
parent::init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify widget configuration
|
||||
*
|
||||
* @param null|\IPS\Helpers\Form $form Form object
|
||||
* @return null|\IPS\Helpers\Form
|
||||
*/
|
||||
public function configuration( &$form=null )
|
||||
{
|
||||
if ( $form === null )
|
||||
{
|
||||
$form = new \IPS\Helpers\Form;
|
||||
}
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'auto_hide', isset( $this->configuration['auto_hide'] ) ? $this->configuration['auto_hide'] : FALSE, FALSE ) );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'days_ahead', isset( $this->configuration['days_ahead'] ) ? $this->configuration['days_ahead'] : NULL, TRUE, array( 'unlimited' => -1 ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'maximum_count', isset( $this->configuration['maximum_count'] ) ? $this->configuration['maximum_count'] : 5, TRUE, array( 'unlimited' => -1 ) ) );
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a widget
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
if( !\IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'calendar', 'calendar' ) ) )
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
$_today = \IPS\calendar\Date::getDate();
|
||||
|
||||
/* Do we have a days ahead cutoff? */
|
||||
$endDate = NULL;
|
||||
|
||||
if( isset( $this->configuration['days_ahead'] ) AND $this->configuration['days_ahead'] > 0 )
|
||||
{
|
||||
$endDate = $_today->adjust( "+" . $this->configuration['days_ahead'] . " days" );
|
||||
}
|
||||
|
||||
$events = \IPS\calendar\Event::retrieveEvents( $_today, $endDate, NULL, ( isset( $this->configuration['maximum_count'] ) AND $this->configuration['maximum_count'] > 0 ) ? $this->configuration['maximum_count'] : 5, FALSE );
|
||||
|
||||
/* Auto hiding? */
|
||||
if( !count($events) AND isset( $this->configuration['auto_hide'] ) AND $this->configuration['auto_hide'] )
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
return $this->output( $events, $_today );
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user