Skip to content
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
93 changes: 93 additions & 0 deletions actions/event_manager/export/ical.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?php

$calendar_type = get_input('calendar_type', 'all');
$date_format = elgg_get_config('date_format', elgg_echo('input:date_format'));

$start_date = get_input('start_date', "");
if ($start_date == "") {
$start_date = time();
} else {
$start_date = DateTime::createFromFormat($date_format, $start_date)->getTimestamp();
}

$end_date = get_input('end_date', "");
if ($end_date == "") {
$end_date = DateTime::createFromFormat('U', time())
->add(DateInterval::createFromDateString('1 month'))
->getTimestamp();
} else {
$end_date = DateTime::createFromFormat($date_format, $end_date)->getTimestamp();
}

$region = get_input('region', '');
$event_type = get_input('event_type', '');

$owner = get_input('owner', '');
$group = get_input('group', '');

$options = [
'types' => ['object'],
'subTypes' => [Event::SUBTYPE],
'metadata_name_value_pairs' => [
[
'name' => 'event_start',
'operand' => '>=',
'value' => $start_date,
],
[
'name' => 'event_end',
'operand' => '<=',
'value' => $end_date,
],
]
];

if ($region != '') {
$options['metadata_name_value_pairs'][] = [
'name' => 'region',
'operand' => 'IN',
'value' => $region,
];
}

if ($event_type != '') {
$options['metadata_name_value_pairs'][] = [
'name' => 'event_type',
'operand' => 'IN',
'value' => $event_type,
];
}

switch ($calendar_type) {
case 'group':
$options['container_guids'] = [$group];
break;
case 'owner':
$options['owner_guids'] = [$owner];
break;
}

$events = elgg_get_entities($options);

use Kigkonsult\Icalcreator\Vcalendar;

/** @noinspection PhpUnhandledExceptionInspection */
/** @noinspection PhpClassConstantAccessedViaChildClassInspection */
$vcalendar = Vcalendar::factory(
[
Vcalendar::UNIQUE_ID => "https://github.com/ColdTrick/event_manager",
]
)
->setMethod(Vcalendar::PUBLISH)
->setXprop(Vcalendar::X_WR_CALNAME, "Exported event")
->setXprop(Vcalendar::X_WR_CALDESC, "Exported events from event_manager")
->setXprop(Vcalendar::X_WR_RELCALID, elgg_get_site_url())
->setXprop(Vcalendar::X_WR_TIMEZONE, date_default_timezone_get());

foreach ($events as $event) {
/** @noinspection PhpUnhandledExceptionInspection */
$vcalendar->setComponent($event->toVEvent());
}

/** @noinspection PhpUnhandledExceptionInspection */
return elgg_download_response($vcalendar->createCalendar(), "export.ics");
50 changes: 50 additions & 0 deletions actions/event_manager/import/ical.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

use Kigkonsult\Icalcreator\Vcalendar;
use Kigkonsult\Icalcreator\Vevent;

$calendar_type = get_input('calendar_type', 'all');

$owner = get_input('owner', '')[0];
$group = get_input('group', '')[0];
$file = elgg_get_uploaded_file('import');

$vcalendar = Vcalendar::factory(
[
Vcalendar::UNIQUE_ID => "https://github.com/ColdTrick/event_manager",
]
);
try {
$vcalendar->parse($file->getContent());
} catch (Exception $e) {
return elgg_error_response("Error parsing calendar: " . $e);
}

$event_counter = 0;

/** @var Vevent $component */
foreach ($vcalendar->getComponents("Vevent") as $component) {
try {
$event = Event::fromVEvent($component);

switch ($calendar_type) {
case "group":
$event->setContainerGUID($group);
break;
case "owner":
$event->owner_guid = $owner;
break;
}
$event->save();
$event_counter++;
} catch (Exception $e) {
return elgg_error_response(
elgg_echo("event_manager:ical_direct:import:failure", [$e])
);
}
}

return elgg_ok_response(
'',
elgg_echo("event_manager:ical_direct:import:success", [$event_counter])
);
35 changes: 35 additions & 0 deletions classes/ColdTrick/EventManager/Menus/Entity.php
Original file line number Diff line number Diff line change
Expand Up @@ -148,4 +148,39 @@ public static function registerEventUnsubscribe(\Elgg\Event $event): ?MenuItems

return $result;
}

/**
* Adds menu items to the event entity menu for exporting it to ical
*
* @param \Elgg\Event $event 'register', 'menu:entity'
*
* @return null|MenuItems
*/
public static function registerICalExport(\Elgg\Event $event): ?MenuItems {
$entity = $event->getEntityParam();
if (!$entity instanceof \Event) {
return null;
}

if (!elgg_get_plugin_setting('ical_direct', 'event_manager')) {
return null;
}

// show an ical export link
$result = $event->getValue();

$result[] = \ElggMenuItem::factory([
'name' => 'ical-export',
'icon' => 'calendar-plus',
'text' => elgg_echo('event_manager:ical_direct:export'),
'href' => elgg_generate_url('default:object:event:export', [
'guid' => $entity->guid,
'view' => 'ical'
]),
'priority' => 300,
]);

return $result;
}

}
23 changes: 23 additions & 0 deletions classes/ColdTrick/EventManager/Menus/Filter.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,29 @@ public static function registerEventsList(\Elgg\Event $event): MenuItems {
'priority' => 400,
]);
}

if (elgg_get_plugin_setting('ical_direct', 'event_manager')) {
$result[] = \ElggMenuItem::factory([
'name' => 'export-ical',
'text' => elgg_echo('event_manager:ical_direct:export'),
'href' => elgg_http_add_url_query_elements(elgg_generate_url('collection:ical:export'),[
'list_route' => elgg_get_current_route_name(),
'route_parameters' => elgg_get_current_route()->getMatchedParameters(),
]),
'priority' => 500,
'selected' => $selected === 'export-ical',
]);
$result[] = \ElggMenuItem::factory([
'name' => 'import-ical',
'text' => elgg_echo('event_manager:ical_direct:import'),
'href' => elgg_http_add_url_query_elements(elgg_generate_url('collection:ical:import'),[
'list_route' => elgg_get_current_route_name(),
'route_parameters' => elgg_get_current_route()->getMatchedParameters(),
]),
'priority' => 500,
'selected' => $selected === 'import-ical',
]);
}

return $result;
}
Expand Down
152 changes: 152 additions & 0 deletions classes/Event.php
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
<?php

use Elgg\Database\Clauses\JoinClause;
use Elgg\Database\Clauses\OrderByClause;
use Elgg\Database\Delete;
use Elgg\Database\QueryBuilder;
use Elgg\Database\Select;
use Kigkonsult\Icalcreator\Vevent;

/**
* Event
Expand Down Expand Up @@ -33,6 +35,8 @@
* @property bool $waiting_list_enabled is a waitling list enabled
* @property string $website event website
* @property bool $with_program has a program
* @property mixed $starttime start time of event
* @property mixed $endtime end time of event
*/
class Event extends \ElggObject {

Expand Down Expand Up @@ -1105,6 +1109,29 @@ public function countAttendees(): int {
});
}

/**
* Fetches all attendees of this event
*
* @return ElggUser[]
*/
public function getAttendees(): array
{
$options = [
'type' => 'user', // trigger search fields generation
'type_subtype_pairs' => [
'user' => ELGG_ENTITIES_ANY_VALUE,
'object' => [
EventRegistration::SUBTYPE,
],
],
'relationship_guid' => $this->guid,
'relationship' => 'event_attending',
'no_results' => true,
'order_by' => new OrderByClause('r.time_created', 'DESC'),
];
return elgg_get_entities($options);
}

/**
* Counts the waiters
*
Expand Down Expand Up @@ -1159,4 +1186,129 @@ public function getOrganizers(array $options = []): int|array {

return elgg_get_entities($options);
}

/**
* Returns the VEvent representation of this event.
*
* @return Vevent
* @throws Exception
*/
public function toVEvent(): Vevent {
$timezone = \Kigkonsult\Icalcreator\Util\DateTimeZoneFactory::factory(date_default_timezone_get());
$dtstart = DateTimeImmutable::createFromFormat("Y-m-d\\TH:i:s", $this->getStartDate("Y-m-d\\TH:i:s"), $timezone);
$dtend = DateTimeImmutable::createFromFormat("Y-m-d\\TH:i:s", $this->getEndDate("Y-m-d\\TH:i:s"), $timezone);
/** @noinspection PhpUnhandledExceptionInspection */
$vevent = Vevent::factory(
null,
$dtstart,
$dtend,
null,
$this->title
)
->setDescription($this->shortdescription)
->setDtstamp(DateTimeImmutable::createFromFormat("c", $this->getTimeCreated()))
->setComment($this->description)
->setLocation($this->location);

$organizers = $this->getOrganizers();
if (count($organizers) > 0 && isset($organizers[0]->email)) {
$vevent->setOrganizer($organizers[0]->email);
}

if ($this->countAttendees() > 0) {
foreach ($this->getAttendees() as $attendee) {
$vevent->setAttendee($attendee->email);
}
}

foreach ($this->getContacts() as $contact) {
if ($contact instanceof ElggUser && isset($contact->email)) {
$vevent->setContact($contact->email);
}
}

if ($this->website) {
$vevent->setXprop("X-WEBSITE", $this->website);
}

if ($this->region) {
$vevent->setXprop("X-PROP-REGION", $this->region);
}

if ($this->venue) {
$vevent->setXprop("X-PROP-VENUE", $this->venue);
}

if ($this->event_type) {
$vevent->setXprop("X-PROP-TYPE", $this->event_type);
}

return $vevent;
}

/**
* Generates a new event based on an iCal Vevent
*
* @param Vevent $vevent
* @return Event
* @throws Exception
*/
static public function fromVEvent(Vevent $vevent): Event
{
$event = new Event();
$event->event_start = $vevent->getDtstart()->getTimestamp() + $vevent->getDtstart()->getOffset();
$event->event_end = $vevent->getDtend()->getTimestamp() + $vevent->getDtend()->getOffset();
$event->title = $vevent->getSummary();
$event->shortdescription = $vevent->getDescription();
$event->description = $vevent->getComment();
$event->location = $vevent->getLocation();

if ($vevent->isOrganizerSet()) {
$organizer = elgg_get_user_by_email($vevent->getOrganizer());
if (is_null($organizer)) {
$event->organizer = $vevent->getOrganizer();
} else {
$event->organizer_guids = [$organizer->guid];
}
}

if ($vevent->isAttendeeSet()) {
foreach ($vevent->getAllAttendee() as $attendee) {
$attendee_object = elgg_get_user_by_email($attendee);
if (!is_null($attendee_object)) {
$event->addRelationship($attendee_object->guid, 'event_attending');
}
}
}

if ($vevent->isContactSet()) {
foreach ($vevent->getAllContact() as $contact) {
$contact_object = elgg_get_user_by_email($contact);
if (!is_null($contact_object)) {
if (!is_array($event->contact_guids)) {
$event->contact_guids = [];
}
$event->contact_guids[] = $contact_object->guid;
}
}
}

if ($vevent->isXpropSet("X-WEBSITE")) {
$event->website = $vevent->getXprop("X-WEBSITE")[1];
}

if ($vevent->isXpropSet("X-PROP-REGION")) {
$event->region = $vevent->getXprop("X-PROP-REGION")[1];
}

if ($vevent->isXpropSet("X-PROP-VENUE")) {
$event->venue = $vevent->getXprop("X-PROP-VENUE")[1];
}

if ($vevent->isXpropSet("X-PROP-TYPE")) {
$event->event_type = $vevent->getXprop("X-PROP-TYPE")[1];
}

return $event;
}
}
Loading