1. Code
  2. PHP

Building Your Startup: Customizing the Meeting View

This post is part of a series called Building Your Startup With PHP.
Using the Mailgun Store(): A Temporary Mailbox for Your App's Incoming Email
Building Your Startup: Delivering the Meeting Invitation
Final product image
What You'll Be Creating


This tutorial is part of the Building Your Startup With PHP series on Envato Tuts+. In this series, I'm guiding you through launching a startup from concept to reality using my Meeting Planner app as a real-life example. Every step along the way, I'll release the Meeting Planner code as open-source examples you can learn from. I'll also address startup-related business issues as they arise.

Why the Gap in This Series?

You may notice that there's been a huge gap in time between the last episode and this one. In April 2015, I was diagnosed with a brain tumor which required surgery and radiation. I'm incredibly fortunate overall to have such good care, and things went pretty well—many people do not have access to the quality of neurosurgery resources available to me with health insurance in the Pacific Northwest. I've been writing again for Envato Tuts+ since last fall, but it's fun to finally return focus to the startup series, and I hope you enjoy it.

What Does This Episode Cover?

In this tutorial, we'll cover the custom features that are needed to provide different views depending on who is looking at meeting invitations. Before we begin emailing the invitation to participants, we need to have a view ready with potentially restricted functionality to share with them. Essentially, we're making sure the meeting view is exactly what's needed for the meeting owner and the meeting participant. Follow along to learn what's needed.

All of the code for Meeting Planner is written in the Yii2 Framework for PHP, which has built-in support for I18n. If you'd like to learn more about Yii2, check out our parallel series Programming With Yii2 at Envato Tuts+.

Interestingly, a potential angel investor recently approached me about contributing resources to speed the development process of our site—he sees the value in the concept. As I sort out the appropriate path to continue forward, I'll keep you posted. If anything, I hope it creates intriguing new tutorial topics around managing the investment process as an entrepreneur.

Just a reminder, I do participate in the comment threads below. I'm especially interested if you have different approaches, additional ideas or want to suggest topics for future tutorials. You can also reach me on Twitter @reifman.

Meeting View Requirements

It's kind of exciting—soon, Meeting Planner will be delivering invitations to invited participants. However, to support that, we need to make sure that the meeting view page is properly configured. If you created the meeting, you have certain powers, such as inviting participants, adding proposed meeting places, dates and times, and choosing the final selections. In some cases, the organizer may want to offer some or all of these powers to participants as well.

Essentially, we have to make the application aware of who's viewing the meeting page and then customize the appearance and commands available. Yii makes most of this pretty easy, but there's a lot of detail involved.

A Brief Caveat About the User Experience

And let me say up front, there is a lot of user experience rework and polish that will need to be done iteratively over time on the way to the minimum viable product (MVP). Most of what I'm building right now is core functionality to get the alpha running for actual usage. I know it looks rough in places and won't always seem as intuitive as you want. There are also coding inefficiencies that will need to be optimized in the future. Please feel free to post your thoughts and comments below and I will take them into account for ongoing work.

The Current Meeting View

Here's a look at the existing meeting view that the creator (or owner) sees:

Customizing Meeting View - The Existing Codes Meeting View

The Send button emails the meeting invitation with the current open options to the participant for them to offer feedback. The checkboxes below You and Them allow the viewer to express whether location(s) and time(s) work for them. The Choose checkboxes allow the viewer to determine the final place and final time. The Finalize button puts the meeting on the schedule with the chosen place and time options.

Certainly, as the product matures, we'll want to improve the user experience in a number of ways and polish it a lot, but here are a handful of functional elements we'd like to modify for participants:

  • The Send button won't be needed after the owner delivers the invitation.
  • Participants may or may not be allowed to Finalize meeting options.
  • Participants won't be able to Edit (pencil icon) the meeting detail text.
  • Participants won't be able to add People at this time (for our MVP).
  • Participants may or may not be allowed to add Places (plus icon).
  • Participants may or may not be allowed to add Dates & Times (plus icon).
  • In both Places and Dates & Times panels, we'll want to show the current viewer's choices under the You column and the other person's data in Them.
  • In both Places and Dates & Times panels, participants may or may not be able to Choose the final location and time.

All of these options need to be addressed in our work today. Let's walk through what's required to build these features.

Requirements Implementation

If you're following along with the code, the updates described here are included in this release on GitHub.

Who's the Current Viewer

The Yii Framework provides the current user_id for the viewer here:

The Meeting model has the $owner_id property and isOwner function to help determine if the current viewer is actually the meeting's creator. If not, the viewer will have conditionally less control over the meeting. 

I've created a couple of helper functions in the Meeting model to make this faster:

These configure the $owner_id and $viewer properties in the Meeting model.

Building for Meeting Settings

Every meeting you create will likely have different characteristics. Sometimes, you'll want to limit the participant from suggesting different times and places or finalizing the details. Other times, you won't care. When we eventually create Meeting Templates for reusing common types of meetings, e.g. morning coffee business meetings, the Templates will likely need to retain these kinds of custom settings as well. How should we implement this?

First, I'd like to create a set of default preferences for users with respect to the meetings they create.

Then, I'll create a set of MeetingSettings for every meeting. When a meeting is created from scratch, they'll inherit the default preferences from the user that creates it. Editing the settings for individual meetings can be postponed until later.

In the future, when we implement the Meeting Templates, we'll add Meeting settings for the Templates too. However, this can also be postponed.

Here are the preferences that we'd like to create to start:

  • Allow participants to add Places.
  • Allow participants to add Dates & Times.
  • Allow participants to choose Places.
  • Allow participants to choose Dates & Times.
  • Allow participants to Finalize the meeting.

Since we're all coming back to the series after some time because of my health absence, I'll go through a bit more detail on some of the work.

First, we'll create the Meeting Settings migration:

That creates the migration file we need to write the code which builds the database table according to our schema:

Each meeting essentially has a row of MeetingSettings with boolean properties for the various participant options I've shown above.

Then, we instruct Yii to migrate up and create the table:

Our foreign key creates a relation between the Meeting table and the MeetingSetting table.

Next, we'll use Yii's Gii to auto-generate code for viewing and updating the settings. To begin, I return to http://localhost:8888/mp/index.php/gii/. We'll start with generating the model:

Customizing Meeting View - Yiis Gii Model Generator for Meeting Setting

Then, we'll generate the Create, Read, Update, Delete code (CRUD):

Customizing Meeting View - The Gii CRUD Generator

Since we don't need all that code right now, Gii lets us select just the functions that we do need: the controller, view, _form and update:

Customizing Meeting View - Manually limiting files to overwrite

Gii shows you a list of the files it creates with each step:

Customizing Meeting View - List of generated files by Gii

But what about the user's default meeting settings? Essentially, their typical meeting preferences?

Extending the User Preferences

For that, we'll add parallel meeting setting properties to the user_setting table. Again, we'll create a migration:

Here are the columns we need to add:

Then, we'll run the migration:

Rather than force an overwrite of our UserSetting.php model with Gii, we'll use Gii's diff option:

Customizing Meeting View - Using Giis diff rather than overwriting

And, from there, we'll hand pick the new additions to the file and paste them in:

Customizing Meeting View - Diff view to copy and paste necessary changes

Functionally, we'll add a meeting settings tab to the Update Your Settings property page:

Customizing Meeting View - User settings with the existing two tabs

We'll add the following code to /frontend/views/user-setting/_form.php to support our new properties:

Here's the updated form:

Customizing Meeting View - User settings with meeting preferences

Initializing New Meeting Sessions

Whenever the user creates a new meeting, we have to load their default settings and copy them to the individual meeting's settings. initializeMeetingSetting is called when a new meeting is created to do this:

With meeting settings in place, we're ready to move on to what's actually the bulk of today's work, customizing the meeting views for the owner and participant.

Reviewing the Meeting Owner View

Now, let's consider the state of our meeting view based on the meeting creator or owner. Here's a meeting invitation I've recently created to invite my friend Rob to drinks:

Customizing Meeting View - The Current Meeting View

The Command Bar

Before Send and Finalize should be enabled, there must be a person invited and at least one place and time. If there are more than one place and time, one must be chosen for the meeting to be finalized.

The Cancel (X icon) and Edit (pencil icon) meeting buttons are also enabled for creators.


For the MVP, we're limiting meeting invitations to one participant at first. So, once a person has been invited, the Add (plus icon) button is disabled. 

Places and Date & Times

The creator can add Places and Date & Times up to our site's maximum (e.g. seven per meeting) and they can indicate their availability and acceptance. And, finally, when there is more than one, they can choose which location and time will be used.


The creator can always add notes to the meeting. Notes allow the creator and participants to communicate with each other.

Ultimately, we'll put the bulk of our work into improving the AJAX functionality so that as the owner chooses places and times, the Send and Finalize buttons are properly enabled (or disabled in some cases).

Here's an example of a meeting with two possible times. The Finalize button can't be enabled until one time is chosen:

Customizing Meeting View - Another Meeting View Scenario

Once the choice is made, we'd like to enable the Finalize button via AJAX, sparing the user a page refresh.

Reviewing the Participant View

When we view the invitation from the participant's point of view, there's a lot less initial capability:

Customizing Meeting View - The Participant View

The participant can cancel (X icon) their attendance to the meeting and they can specify whether the places and times are acceptable to them, but they can't choose the final place or Finalize the meeting. Also, the data in the You and Them columns are now switched. And, the participant panel is hidden as it's not needed.

Additionally, let's say the meeting was created with settings that allowed the participant to choose the location, date and time but not finalize the meeting. That would need to look like this:

Customizing Meeting View - The Participant View with Participant Choice

Since there's only one Place, Herkimer Coffee, there's no need for a choice selector. But, where there are two possible times, you can now see the Choose selectors. Still, there is no Finalize button.

It turned out that supporting all of this required a lot of new code to update the system, but this is beginning to dive into the heart of the product—the scheduling meetings user experience. I'll walk you through a handful of the changes that were needed.

Coding the Meeting Requirements

Implementing the Meeting Settings

In the meeting-time and meeting-place panels, we need to use the meeting settings to determine if we need to show the choice selector. In the _panel.php view, it looks like this:

We're checking the participant settings and passing them as a parameter to the subsequent _list.php view, which looks like this:

If the view is the creator or the participant is allowed to choose the final time, they'll see something like this, the ability to Choose in the right column:

Customizing Meeting View - The Choice Selector for Dates  Times

Can the Viewer Send and Finalize the Meeting

I created canSend() and canFinalize() functions, which support the code generally and the AJAX requests to determine the active state of Send and Finalize buttons. 

Here's canSend():

The organizer can't send the meeting invitation until there are participant(s), places and times.

Here's canFinalize():

This first checks if the meeting could be sent, because if not, it can't be finalized. Then, it checks to make sure that both a place and time have been chosen. And then, it checks if the viewer is the organizer or the meeting settings allow a participant to finalize the meeting.

Basically, as changes are made, you'll see the state of the Send and Finalize buttons change:

Customizing Meeting View - The Command Bar with Send and Finalize

In the meeting view.php, I've embedded JavaScript to support AJAX updates to the state of the Send and Finalize buttons as users change settings for their meeting. When selections of places and times are made, refreshSend() and refreshFinalize() are called and the buttons are appropriately modified:

Reversing the Place and Time Status Selectors

In the current user interface, we show the viewer's place and time selections in the leftmost or first column. The code has to be customized to reverse this when participants are viewing:

Customizing Meeting View - The You and Them Columns for Selection Data

To support showing different data in the You and Them columns of the meeting view for Times and Places, the meeting-time and meeting-place _list.php files needed to be updated to dynamically determine what data to display:

For now, I placed these functions within the _panel.php view, which calls _list.php, as they rely on having the SwitchInput widget included in context:

Upcoming Adjustments

Ultimately, there are a lot of improvements to make to this code going forward. In places, I'm making AJAX calls to the server two or three times when I could code these more efficiently into a single request. In other places, I can do more locally with JavaScript. And the user interface will need to keep improving, and the code will need to change to adapt to that. But, from a functional perspective, today's work represents a lot of overall progress towards the MVP.

What's Next?

With the meeting settings and view requirements in place for organizers and participants, I'm ready to move on to sending the first invitation. The next episode will explore emailing the invitation to the participant and implementing the appearance of content, functional command links within the email, and managing the permissions for users that haven't registered yet. Watch for upcoming tutorials in our Building Your Startup With PHP series—this is getting exciting!

Please feel free to add your questions and comments below; I generally participate in the discussions. You can also reach me on Twitter @reifman.

Related Links

Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.