BEGIN:VCALENDAR VERSION:2.0 PRODID:-//hacksw/handcal//NONSGML v1.0//EN BEGIN:VEVENT UID:[email protected] DTSTAMP:19970610T172345Z DTSTART:19970714T170000Z DTEND:19970715T040000Z SUMMARY:Bastille Day Party END:VEVENT END:VCALENDAR
BEGIN:VCALENDAR
and end with END:VCALENDAR
. The body consists of a sequence of properties and one or more calendar components.VERSION
and PRODID
. While there are many other properties, these two must be present in an iCal object in order for it to parse correctly.PRODID
is your company details in the format: Business Name//Product Name//Language. VERSION
is the current version of iCal.BEGIN:VEVENT
and END:VEVENT
delimiters.$ composer create-project --prefer-dist laravel/lumen iCal
$ php -S localhost:8000 -t public
make:migration
Artisan command:$ php artisan make:migration create_tech_events_table
<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateTechEventsTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('tech_events', function (Blueprint $table) { $table->increments('id'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('tech_events'); } }
up()
method, we create a table and define its columns. The down()
method reverses the migrations if we need to.<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateTechEventsTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('tech_events', function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->timestamp('starts')->default(\DB::raw('CURRENT_TIMESTAMP')); $table->timestamp('ends')->default(\DB::raw('CURRENT_TIMESTAMP')); $table->string('status'); $table->text('summary'); $table->string('location'); $table->string('uid'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('tech_events'); } }
$table->string('name')
. This means we have a column called name and its datatype is a string.$ php artisan migrate
<?php $app->withFacades(); $app->withEloquent();
<?php /* |-------------------------------------------------------------------------- | Model Factories |-------------------------------------------------------------------------- | | Here you may define all of your model factories. Model factories give | you a convenient way to create models for testing and seeding your | database. Just tell the factory how a default model should look. | */ use Carbon\Carbon; $factory->define(App\User::class, function (Faker\Generator $faker) { return [ 'name' => $faker->name, 'email' => $faker->email, ]; }); $factory->define(App\TechEvents::class, function (Faker\Generator $faker) { $startTime = Carbon::createFromTimeStamp($faker->dateTimeBetween('now', '+1 month')->getTimestamp()); return [ 'name' => $faker->word, 'starts' => $startTime, 'ends' => Carbon::createFromFormat('Y-m-d H:i:s', $startTime)->addHours(2), 'status' => 'CONFIRMED', 'summary' => $faker->sentence($nbWords = 6, $variableNbWords = true), 'location' => $faker->word, 'uid' => $faker->domainName, 'created_at' => Carbon::now()->toDateTimeString(), 'updated_at' => Carbon::now()->toDateTimeString() ]; });
$startTime
. This generates a random date within a month from now. For this tutorial, our events will only last two hours. In the 'ends' field we add two hours to the $startTime.run()
. When we run seeders, this is the method that is called.<?php use Illuminate\Database\Seeder; use App\TechEvents; class DatabaseSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { factory(TechEvents::class, 10)->create(); } }
factory(TechEvents::class, 10)->create()
inside the run method, we are indicating that we would like to generate and insert ten records into our database.$ php artisan db:seed
<?php namespace App\Http\Controllers; use App\TechEvents; class ICalController extends Controller { /** * Gets the events data from the database * and populates the iCal object. * * @return void */ public function getEventsICalObject() { $events = TechEvents::all(); define('ICAL_FORMAT', 'Ymd\THis\Z'); $icalObject = "BEGIN:VCALENDAR VERSION:2.0 METHOD:PUBLISH PRODID:-//Charles Oduk//Tech Events//EN\n"; // loop over events foreach ($events as $event) { $icalObject .= "BEGIN:VEVENT DTSTART:" . date(ICAL_FORMAT, strtotime($event->starts)) . " DTEND:" . date(ICAL_FORMAT, strtotime($event->ends)) . " DTSTAMP:" . date(ICAL_FORMAT, strtotime($event->created_at)) . " SUMMARY:$event->summary UID:$event->uid STATUS:" . strtoupper($event->status) . " LAST-MODIFIED:" . date(ICAL_FORMAT, strtotime($event->updated_at)) . " LOCATION:$event->location END:VEVENT\n"; } // close calendar $icalObject .= "END:VCALENDAR"; // Set the headers header('Content-type: text/calendar; charset=utf-8'); header('Content-Disposition: attachment; filename="cal.ics"'); $icalObject = str_replace(' ', '', $icalObject); echo $icalObject; } }
getEventsICalObject()
method, we start by using Eloquent’s all()
method to fetch all the events from the database and store them in the $events
variable. Secondly, we define the iCal format. This is used to transform our timestamps into UTC format. Then we begin building our iCal object by looping through each event and adding them to the iCal object.<?php $router->get("ical-events", "ICalController@getEventsICalObject");
$ php -S localhost:8000 -t public
$ ngrok http 8000
Email: [email protected]
Github: charlieoduk
Twitter: @charlieoduk