Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EE 3-5 Compatibility update #9

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
164 changes: 164 additions & 0 deletions easy_ical/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
# Easy iCalendar

ExpressionEngine plugin that builds valid iCalendar files.

*Forked from <a href="https://github.com/expressodev/easy_icalendar/" target="_blank" title="Expresso's Easy iCalendar ExpressionEngine Plugin">Expresso's Easy iCalendar ExpressionEngine Plugin</a>*

## Requirements

ExpressionEngine v2+

*Compatible with EE v2-5*

## Installation

- **EE v2:** Copy `easy_ical` directory into `/system/expressionengine/third_party/`
- **EE v3:** Copy `easy_ical` directory into `/system/user/addons/`
- **EE v4:** Copy `easy_ical` directory into `/system/user/addons/`
- **EE v5:** Copy `easy_ical` directory into `/system/user/addons/`

## Usage

### `{exp:easy_ical:calendar}`

Along with `{exp:easy_ical:event}`, builds the <a href="https://en.wikipedia.org/wiki/ICalendar#Core_object" target="_blank" title="Learn more about the iCalendar Core Object">iCalendar Core Object</a>

#### Parameters

##### `timezone` *(optional)*

Specify the timezone for all events

- **Type:** string
- **Default:** `America/New_York`
- **Options:** <a href="https://www.php.net/manual/en/timezones.php" target="_blank" title="Learn more about PHP timezones">PHP timezones</a>

##### `calendar_name` *(optional)*

Give your calendar a name

- **Type:** string
- **Default:** `Save the Date!`

##### `content_type` *(optional)*

Force the specified content type (for debugging)

- **Type:** string
- **Default:** `text/calendar; charset=UTF-8`
- **Options:** `text/plain`

##### `filename` *(optional)*

Name for the generated iCalendar file

- **Type:** string
- **Default:** `save-the-date`

### `{exp:easy_ical:event}`

Along with `{exp:easy_ical:calendar}`, builds the <a href="https://en.wikipedia.org/wiki/ICalendar#Core_object" target="_blank" title="Read more about the iCalendar Core Object">iCalendar Core Object</a>

#### Parameters

##### `uid` *(optional)*

A unique identifier for the event, typically `{entry_id}`

- **Type:** string
- **Default:** unix timestamp

##### `start_time` *(optional)*

The event start date and time, typically `{entry_date}`

- **Type:** int
- **Default:** Current date and time (unix timestamp)

##### `end_time` *(optional)*

The event end date and time, typically `{expiration_date}` or custom channel field (date)

- **Type:** int
- **Default:** Current date and time + 24 hours (unix timestamp)

##### `location` *(optional)*

The event location, typically a custom channel field (text).

- **Type:** string
- **Default:** `New York, NY`

##### `summary` *(optional)*

The event summary, typically `{title}` or a custom channel field (text)

- **Type:** string
- **Default:** `An event happening in New York, NY`

##### `url` *(optional)*

Allows you to add a link to the event.

- **Type:** string

##### `sequence` *(optional)*

Needed if you update an entry with the same `uid`, otherwise iCal will not update the event.

- **Type:** int
- **Default:** unix timestamp

### Example
```
{exp:easy_ical:calendar timezone="Pacific/Auckland" name="My Event Calendar"}
{exp:channel:entries channel="events" show_future_entries="yes" show_expired="yes" limit="20"}
{exp:easy_ical:event uid="{entry_id}" start_time="{entry_date}" end_time="{expiration_date}" location="{event_location}" summary="{title}"}
{event_description}
{/exp:easy_ical:event}
{/exp:channel:entries}
{/exp:easy_ical:calendar}
```

## Changelog

### 2.0.0 *(2020-03-11)*

- ExpressionEngine 3+ compatibility
- Refactored methods
- Overhauled documentation

### 1.3.0 *(2013-07-08)*

- Updated `name` attr to `calendar_name`
- Fixed a few conditionals

### 1.2.0 *(2013-07-08)*

- ExpressionEngine 2.6 compatibility

### 1.1.1 *(2011-06-09)*

- Adjusted the output slightly to fix compatibility issues with some versions of iCal

### 1.1.0 *(2011-05-05)*

- Added url="" and sequence="" parameters (thanks to [GDmac](http://github.com/GDmac))

### 1.0.0 *(2010-11-24)*

- Initial release

## License

Copyright © Crescendo Multimedia Ltd and individual contributors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

## Disclaimer

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 changes: 28 additions & 0 deletions easy_ical/addon.setup.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

/**
* Easy iCalendar (forked)
*
* @package ExpressionEngine
* @category Plugin
* @author Matthew Kirkpatrick
* @copyright Copyright (c) 2020, Matthew Kirkpatrick
* @link https://github.com/javashakes
*/

// config
include(PATH_THIRD.'easy_ical/config.php');

return array(
'name' => EASY_ICAL_NAME,
'version' => EASY_ICAL_VERSION,
'author' => EASY_ICAL_AUTHOR,
'author_url' => EASY_ICAL_AUTHOR_URL,
'docs_url' => EASY_ICAL_DOCS,
'description' => EASY_ICAL_DESC,
'namespace' => EASY_ICAL_NAMESPACE,
'settings_exist' => FALSE
);

/* End of file addon.setup.php */
/* Location: /system/expressionengine/third_party/easy_ical/addon.setup.php */
27 changes: 27 additions & 0 deletions easy_ical/config.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

/**
* Easy iCalendar (forked)
*
* @package ExpressionEngine
* @category Plugin
* @author Matthew Kirkpatrick
* @copyright Copyright (c) 2020, Matthew Kirkpatrick
* @link https://github.com/javashakes
*/

if ( ! defined('EASY_ICAL_NAME'))
{
define('EASY_ICAL_NAME', 'Easy iCalendar');
define('EASY_ICAL_VERSION', '2.0.0');
define('EASY_ICAL_AUTHOR', 'Matthew Kirkpatrick');
define('EASY_ICAL_AUTHOR_URL', 'https://github.com/javashakes');
define('EASY_ICAL_DOCS', 'https://github.com/javashakes/easy_icalendar');
define('EASY_ICAL_DESC', '<p><strong>ExpressionEngine Plugin that creates valid iCalendar ICS files.</strong></p>Documentation and Usage: <a href="' . EASY_ICAL_DOCS . '" target="_blank">' . EASY_ICAL_DOCS . '</a>');
define('EASY_ICAL_PACKAGE', 'easy_ical');
define('EASY_ICAL_NAMESPACE', 'javashakes\EasyiCal');
define('EASY_ICAL_CLASS_NAME', 'Easy_ical');
}

/* End of file config.php */
/* Location: ./system/expressionengine/third_party/easy_ical/config.php */
158 changes: 158 additions & 0 deletions easy_ical/pi.easy_ical.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

/**
* Easy iCalendar (forked)
*
* @package ExpressionEngine
* @category Plugin
* @author Matthew Kirkpatrick
* @copyright Copyright (c) 2020, Matthew Kirkpatrick
* @link https://github.com/javashakes
*/

// config
include(PATH_THIRD.'easy_ical/config.php');

// EE v2 backward compatibility
// Ignored by EE v3+
$plugin_info = array(
'pi_name' => EASY_ICAL_NAME,
'pi_version' => EASY_ICAL_VERSION,
'pi_author' => EASY_ICAL_AUTHOR,
'pi_author_url' => EASY_ICAL_AUTHOR_URL,
'pi_description' => EASY_ICAL_DESC
);

class Easy_ical
{

public $return_data = '';

/**
* Constructor
*
* @access public
* @return string
*/
public function __construct()
{
// default output
$this->return_data = '' . EASY_ICAL_NAME . '<br>' . EASY_ICAL_DESC;
}

/**
* CALENDAR OBJECT
*
* @access public
* @return string
*/
public function calendar()
{
// parameters
$timezone = $this->escape(ee()->TMPL->fetch_param('timezone', 'America/New_York'));
$calendar_name = $this->escape(ee()->TMPL->fetch_param('calendar_name', 'Save the Date!'));
$content_type = ee()->TMPL->fetch_param('content_type', 'text/calendar; charset=UTF-8');
$filename = $this->escape(ee()->TMPL->fetch_param('filename', 'save-the-date'));

// capture event tag and trim away whitespace
$tagdata = trim(ee()->TMPL->tagdata);
$tagdata = preg_replace('/END\:VEVENT\s*BEGIN\:VEVENT/', "END:VEVENT\r\nBEGIN:VEVENT", $tagdata);

// build the calendar object
$this->return_data = "BEGIN:VCALENDAR\r\nVERSION:2.0\r\n" .
"PRODID:-//ExpressionEngine " . EASY_ICAL_NAME . " plugin//NONSGML v" . EASY_ICAL_VERSION . "//EN\r\n" .
"X-WR-TIMEZONE:" . $timezone . "\r\n" .
"X-WR-CALNAME:" . $calendar_name . "\r\n" .
( (!empty($tagdata)) ? $tagdata . "\r\n" : '' ) .
"END:VCALENDAR";

// output headers
header('Content-Description: File Transfer');
header('Content-Type: ' . $content_type);
header('Content-Disposition: attachment; filename="' . $filename . '.ics"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');

// output file content
exit($this->return_data);
}

/**
* EVENT OBJECT
*
* @access public
* @return string
*/
public function event()
{
// parameters
$uid = $this->escape(ee()->TMPL->fetch_param('uid', ee()->localize->now));
$start_time = $this->ical_time(ee()->TMPL->fetch_param('start_time', ee()->localize->now));
$end_time = $this->ical_time(ee()->TMPL->fetch_param('end_time', $start_time+(60*60*24)));
$summary = $this->escape(ee()->TMPL->fetch_param('summary', 'An event happening in New York, NY'));
$location = $this->escape(ee()->TMPL->fetch_param('location', 'New York, NY'));
$sequence = $this->escape(ee()->TMPL->fetch_param('sequence', 1));
$url = $this->escape(ee()->TMPL->fetch_param('url', ''));
$description = $this->escape(trim(ee()->TMPL->tagdata));

$this->return_data = "BEGIN:VEVENT\r\n" .
"UID:" . $uid . "\r\n" .
"DTSTAMP:" . $start_time . "\r\n" .
"DTSTART:" . $start_time . "\r\n" .
"DTEND:" . $end_time . "\r\n" .
"SUMMARY:" . $summary . "\r\n" .
"LOCATION:" . $location . "\r\n" .
( (!empty($description)) ? "DESCRIPTION:" . $description . "\r\n" : '' ) .
( (!empty($url)) ? "URL:" . $url . "\r\n" : '' ) .
"SEQUENCE:" . $sequence . "\r\n" .
"END:VEVENT"."\r\n";

// return event object
return $this->return_data;
}

/**
* HELPER: STRING ESCAPING/CLEANING
*
* @access public
* @return string
*/
public function escape($str)
{
// replace, then strip html tags
$str = preg_replace('/\<p\>/i', "\n\n", $str);
$str = preg_replace('/\<br\s*\/?\>/i', "\n", $str);
$str = strip_tags($str);
$str = trim(html_entity_decode($str, ENT_QUOTES, 'UTF-8'));

// no more than two newlines please
$str = preg_replace("/(\r?\n){3,}/", "\n\n", $str);

// lines can't be more than 75 chars, use 60 to be safe
$lines = str_split($str, 60);

foreach ($lines as $key => $line) {
// escape special icalendar chars and convert newlines to '\n'
$lines[$key] = str_replace(array('\\', ',', ';'), array('\\\\', '\,', '\;'), $lines[$key]);
$lines[$key] = preg_replace("/\r?\n/", '\n', $lines[$key]);
}

return implode("\r\n ", $lines);
}

/**
* HELPER: DATE FORMATTING
*
* @access public
* @return string
*/
public function ical_time($time)
{
return ee()->localize->format_date('%Y%m%dT%H%i%s', $time);
}

}

/* End of file pi.easy_ical.php */
/* Location: /system/expressionengine/third_party/easy_ical/pi.easy_ical.php */
Loading