
Content of the material
Warning
The unoptimized values are hardcoded and not sensitive to the date changing. That is, local timezone changes like Daylight Savings Time will not be properly reflected in this data set. This should only be used for prototyping, not usage in production.
We recommend avoiding Daylight Savings Time in prompts if possible. If not, see for dynamically updating new values
Video
❡Viewing events
After all this work, it will be a shame not to see the data we’ve imported. Therefore let’s bootstrap a little page that lists all of our events ordered by descending starting time (from most recent to oldest).
First, we need to create a query that accesses all of the events from a given user. Unfortunately we cannot use the hasManyThrough
relationship since the Event
model is three levels deep from the User
model. That is, we could fetch the calendars (User → GoogleAccount → Calendar
) but not one level deeper.
There is actually a package that defines a new Laravel relationship called hasManyDeep
which would allow us to reach the Event
model from the User
model. However, for the purpose of this article, I’d rather not include yet another package. So here is my quick and simple implementation:
Okay next, let’s create an EventController
with only one index
action.
Finally let’s define a route for this.
If you’d like to see the front-end’s code, please check the changes on GitHub below.
Here is what my (made up) calendar events look like on the Google calendar app.
Here is what they look like on our application. 🍺
❡Models
❡User
The user model stays the same but gets a hasMany
relationship to the GoogleAccount
model.
❡GoogleAccount
Every model that comes from the Google API, i.e. GoogleAccount
, Calendar
and Event
have a column google_id
which keeps track of the identifier of the resource that Google understands. This will be helpful at a later stage to know if we need to create a new resource or simply update an existing one.
For the GoogleAccount model, it will be helpful to ensure a user doesn’t enter twice the same account. This model also has a name
(typically the email address of the account) and an authentication token
which is stored as JSON.
❡Calendar
Aside from its name
and google_id
, our simplified Calendar model also has a color
and a timezone
.
❡Event
Finally our Event model has a name
, a description
and a starting and ending datetime
with an allday
flag letting us know if we should ignore the time of our datetime columns.
Instead of just casting our datetime columns, we provide custom accessors to incorporate the calendar’s timezone into the parsed Carbon instance. We also define an accessor to retrieve the event’s duration.
Options
currentTimezone | a string like “America/Chicago”. Consult for a full list. |
---|---|
editable | whether to allow dragging/resizing (default: false ) |
className | CSS class to attach to each event |
Any of the other Event Source options… |
Dependencies
Next, you must have all the required js/css files. This includes the standard fullcalendar.js and fullcalendar.css, in addition to gcal.js:
<script type=‘text/javascript’ src=‘fullcalendar/gcal.js’></script>
Documentation
Build
To build the latest set of assets, run:
Human friendly timezones
We have set up human friendly timezones via google-calendar-tz.json
, cleanup-google-calendar-tz.js
, and tz-locales.json
To refresh the data for tz-locales.json
(final result), perform the following steps:
- Go to Google Calendar ()
- Open “Create” page for a new event
- Open “Network” tab in developer tools
- Click “Timezone”
- Download “POST ” response body to
google-calendar-tz.json
- Run
npm run build-locales
Country codes
We have set up human friendly timezones via google-calendar-countries.json
, cleanup-google-calendar-countries.js
, and country-codes.json
To refresh the data for country-codes.json
(final result), perform the following steps:
- Go to Google Calendar ()
- Open “Create” page for a new event
- Click “Timezone”
- Inspect the “Countries” element
- Download
$0.outerHTML
togoogle-calendar-countries.html
- Run
npm run build-country-codes