Skip to content

Commit bff117c

Browse files
committed
adds repeating events.
1 parent f3795f6 commit bff117c

10 files changed

Lines changed: 1493 additions & 0 deletions
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?php
2+
3+
use Phinx\Migration\AbstractMigration;
4+
5+
/**
6+
* Add recurrence (RFC 5545 RRULE) support to the events table.
7+
*
8+
* A recurring event stores its rule in `rrule` (the master). Individual
9+
* occurrences are expanded on the fly at query time. A modified single
10+
* occurrence is stored as a child "override" row that points back to its
11+
* master via `recurrence_parent_id` and identifies the original occurrence it
12+
* replaces via `recurrence_id`. `recurrence_until` caches the last occurrence
13+
* date of a bounded rule (NULL for an infinite rule) so range queries can skip
14+
* masters whose window does not intersect the requested range.
15+
*
16+
* NOTE: For EXISTING installations that already ran the original
17+
* create_events_table migration. New installations pick up the columns from
18+
* this migration when running migrations in order.
19+
*/
20+
class AddRecurrenceToEvents extends AbstractMigration
21+
{
22+
/**
23+
* Add recurrence columns to events table
24+
*/
25+
public function change()
26+
{
27+
$table = $this->table( 'events' );
28+
29+
if( !$table->hasColumn( 'rrule' ) )
30+
{
31+
$table->addColumn( 'rrule', 'text', [
32+
'null' => true,
33+
'after' => 'all_day'
34+
] )->update();
35+
}
36+
37+
if( !$table->hasColumn( 'recurrence_parent_id' ) )
38+
{
39+
$table->addColumn( 'recurrence_parent_id', 'integer', [
40+
'signed' => false,
41+
'null' => true,
42+
'after' => 'rrule'
43+
] )
44+
->addIndex( [ 'recurrence_parent_id' ] )
45+
->addForeignKey( 'recurrence_parent_id', 'events', 'id', [
46+
'delete' => 'CASCADE',
47+
'update' => 'CASCADE'
48+
] )
49+
->update();
50+
}
51+
52+
if( !$table->hasColumn( 'recurrence_id' ) )
53+
{
54+
$table->addColumn( 'recurrence_id', 'datetime', [
55+
'null' => true,
56+
'after' => 'recurrence_parent_id'
57+
] )
58+
->addIndex( [ 'recurrence_id' ] )
59+
->update();
60+
}
61+
62+
if( !$table->hasColumn( 'recurrence_until' ) )
63+
{
64+
$table->addColumn( 'recurrence_until', 'datetime', [
65+
'null' => true,
66+
'after' => 'recurrence_id'
67+
] )
68+
->addIndex( [ 'recurrence_until' ] )
69+
->update();
70+
}
71+
}
72+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
use Phinx\Migration\AbstractMigration;
4+
5+
/**
6+
* Create event_recurrence_exceptions table.
7+
*
8+
* Stores excluded occurrence dates (EXDATE) for a recurring master event.
9+
* A cancelled single occurrence is recorded here; when expanding the master
10+
* rule any occurrence whose start matches an exception row is skipped.
11+
*/
12+
class CreateEventRecurrenceExceptionsTable extends AbstractMigration
13+
{
14+
/**
15+
* Create event_recurrence_exceptions table
16+
*/
17+
public function change()
18+
{
19+
$table = $this->table( 'event_recurrence_exceptions', [ 'signed' => false ] );
20+
21+
$table->addColumn( 'event_id', 'integer', [ 'signed' => false, 'null' => false ] )
22+
->addColumn( 'occurrence_date', 'datetime', [ 'null' => false ] )
23+
->addColumn( 'created_at', 'timestamp', [ 'default' => 'CURRENT_TIMESTAMP' ] )
24+
->addIndex( [ 'event_id', 'occurrence_date' ], [ 'unique' => true ] )
25+
->addForeignKey( 'event_id', 'events', 'id', [ 'delete' => 'CASCADE', 'update' => 'CASCADE' ] )
26+
->create();
27+
}
28+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
use Phinx\Migration\AbstractMigration;
4+
5+
/**
6+
* Add occurrence_date to event_registrations.
7+
*
8+
* For recurring events, a registration targets a specific occurrence so that
9+
* capacity and duplicate-email checks are scoped per occurrence. For
10+
* non-recurring events the column is NULL and behaviour is unchanged.
11+
*
12+
* NOTE: For EXISTING installations that already ran the
13+
* create_event_registrations_table migration. New installations pick up the
14+
* column from this migration when running migrations in order.
15+
*/
16+
class AddOccurrenceDateToEventRegistrations extends AbstractMigration
17+
{
18+
/**
19+
* Add occurrence_date column to event_registrations table
20+
*/
21+
public function change()
22+
{
23+
$table = $this->table( 'event_registrations' );
24+
25+
if( !$table->hasColumn( 'occurrence_date' ) )
26+
{
27+
$table->addColumn( 'occurrence_date', 'datetime', [
28+
'null' => true,
29+
'after' => 'event_id'
30+
] )
31+
->addIndex( [ 'event_id', 'occurrence_date' ] )
32+
->update();
33+
}
34+
}
35+
}

0 commit comments

Comments
 (0)