Statuses—Other Media [ 252 ] Videos A nice YouTube player is embedded with the video we selected when we posted a new video. Links If we post a status with a link attached, the link is shown beneath our status. Repeat! We also need to extend our status stream to work in the same way as our proles, pulling in extended data from the extended status types. As we have discussed thoroughly how to update the prole view, you should be able to tackle the status stream on your own, applying the knowledge from this chapter. Download from Wow! eBook <www.wowebook.com> Chapter 8 [ 253 ] Summary In this chapter we have taken our simple status stream and user proles and extended them to support statuses and messages that make use of other media including images, videos, and links. Next up, is creating calendars and providing provisions for creating and displaying events and birthdays. Download from Wow! eBook <www.wowebook.com> Download from Wow! eBook <www.wowebook.com> Events and Birthdays Our social network is nearing completion; we now have not only a status stream of updates for our users, but also support for a number of different types of media, including video and images. One of the two main remaining features (the other being groups) is events. No social network would be complete without support for events and of course, birthdays. In this chapter, you will learn: • How to dynamically generate innovative calendars • How to use these calendars to display specic dates • How to re-use this calendar feature in other areas of the site • How to notify users of the birthday of their contacts • How to manage event invitations and RSVPs • How to send reminders via the site, e-mail, and SMS Let's plan So, we want to store, manage, and display user-organized events and the birthdays of our members on the site. In itself, this is fairly trivial; we can simply list any events occurring within the next X days, and allow our users to paginate through the results. This of course, isn't a very user friendly approach; a more user friendly approach would be to display the events within a calendar, which is somewhat more complicated. Because a calendar is something we will most likely want to reuse throughout our network, and because of the complexities that come with it, it is important for us to plan what we need it to do. We will create a calendar library le, a class that can be re-used throughout Dino Space, while we will also create controllers to display the primary calendar. The library le will do most of the work for us, so that we can re-use it in any number of other controllers we need. Download from Wow! eBook <www.wowebook.com> Events and Birthdays [ 256 ] Calendars: what do we need to be able to do? We need our calendar library to: • Generate a friendly interface for the current month • Be capable of generating a friendly interface for other months • Be aware of the next and previous months, and their years if they differ from the current year, as in most cases, a user will browse through months starting at the current month, moving forward or backwards a month at a time • Be capable of indicating which day is the current day, and days with events within them • Work out how many days there are in a particular month Calendar library We will save our calendar library le as /lib/calendar/calendar.class.php. The rst thing for us to do in our le, is create a number of variables, and the constructor. We need variables for: • The year the calendar represents • The day the calendar represents • The month the calendar represents • The day of the week we want our calendar to start with • Days of the week, ordered so we can change them using our start day of the week as an offset • Days of the week ordered with respect to our offset • The name of the month represented by the calendar • Dates of the month • Styles associated with each of the days of the month • Data associated with each of the days of the month, that is, the events on those days <?php /** * Calendar object */ class Calendar{ Download from Wow! eBook <www.wowebook.com> Chapter 9 [ 257 ] /** * The year represented within the calendar */ private $year; /** * The current day being represented within the calendar, if appropriate */ private $day; /** * The current month being represented within the calendar */ private $month; /** * Tells the calendar which day of the month weeks start at. Sunday is standard for UK calendars. */ private $startDay = 0; /** * Array of days as if we didn't already know */ private $days = array('Sun','Mon','Tue','Wed','Thu','Fri', 'Sat'); /** * Array of months */ private $months = array( 0=> '', 1 => 'January', 2 => 'February', 3 => 'March', 4 => 'April', 5 => 'May', 6 => 'June', 7 => 'July', 8 => 'August', 9 => 'September', 10 => 'October', 11 => 'November', 12 => 'December' ); Download from Wow! eBook <www.wowebook.com> Events and Birthdays [ 258 ] /** * Days of the week, ordered by our chosen start day */ private $orderedDays; /** * Name of the current month */ private $monthName; /** * Dates of the month */ private $dates=array(); /** * Styles for each day of the month */ private $dateStyles=array(); /** * List of days with events associated with them */ private $daysWithEvents = array(); /** * Data to associate with dates */ private $data=array(); /** * Data associated with dates, in corresponding 42 record array */ private $datesData = array(); With our variables in place, we now need a constructor that takes the day, month, and year, which we wish to represent in calendar form, and then set the appropriate values of our object. If an empty string is passed for any of the values, they default to today's date. /** * Calendar constructor * @param int $day selected day in the calendar Download from Wow! eBook <www.wowebook.com> Chapter 9 [ 259 ] * @param int $month month being represented in calendar * @param int $year the year being represented in the calendar * @return void */ public function __construct( $day, $month, $year ) { $this->year = ( $year == '' ) ? date('y') : $year; $this->month = ( $month == '' ) ? date('m') : $month; $this->day = ( $day == '' ) ? date('d') : $day; $this->monthName = $this->months[ ltrim( $this->month, '0') ]; } Generating the month From a computational perspective, and with the way our template engine works, it is best to think of a month as a grid of 42 squares. No month has 42 days in it; however, if a month starts on the last day of the week, then the grid may need to have 42 squares, 31 for the month itself, and the remaining 11 for the un-used grids on the rst week, and last week of the month. With this in mind, all we need our calendar library to do, is iterate 42 times and work out if the current grid is for a valid date for that month, and also, whether the date has any events associated with it, or if the date is the current date. This method in itself won't return anything; instead, it will set various variables within the object that we can use, including: • An ordered list of days of the week (ordered based off the desired start day of the week, allowing for US users to have weeks starting on Monday, and UK users to have weeks starting on Sunday) • The name of the current month • The days of the month, in an array corresponding to the 42 square grid for the calendar • The styles (CSS classes to be used) of the days of the month, also in a corresponding array • The data for each calendar day, also in a corresponding array /** * Builds the month being represented by the calendar object * @return void */ public function buildMonth() { Download from Wow! eBook <www.wowebook.com> Events and Birthdays [ 260 ] First, we generate a list of the days in order, with respect to our chosen rst day of the week. Then, we look up the string representation of the current month and set that: $this->orderedDays = $this->getDaysInOrder(); $this->monthName = $this->months[ ltrim( $this->month, '0') ]; Since we need to know the day of the rst of the month, so we know which of our 42 boxes is to contain data for the rst, we need to look up which day of the week the rst of the month is: // start of whichever month we are building $start_of_month = getdate( mktime(12, 0, 0, $this->month, 1, $this->year ) ); $first_day_of_month = $start_of_month['wday']; With the day of the rst of the month looked up, we now need to work out an offset with respect to the rst day of the week, so we know after how many days the rst of the month appears. For example, if our calendar is set to display Sunday as the rst of the week, and the 1st of the month is Wednesday, the rst three boxes in the calendar will be empty, so we need to know how many to "pass over": $days = $this->startDay - $first_day_of_month; if( $days > 1 ) { // get an offset $days -= 7; } $num_days = $this->daysInMonth($this->month, $this->year); // 42 iterations $start = 0; $cal_dates = array(); $cal_dates_style = array(); $cal_events = array(); Next, we loop 42 times, for each of the boxes in our calendar grid. Using the offset ($days), we skip the rst empty boxes, setting an appropriate class for them: while( $start < 42 ) { // off set dates Download from Wow! eBook <www.wowebook.com> Chapter 9 [ 261 ] if( $days < 0 ) { $cal_dates[] = ''; $cal_dates_style[] = 'calendar-empty'; $cal_dates_data[] = ''; } else { Once we have passed the offset dates, the next "number of days in the month" cycles are valid dates in the calendar, so we look to see if we have events assigned to the dates, and if so, we put them in the appropriate array and set an appropriate class for the day. We also put the day of the month in an array of calendar dates. We created empty values for the previous iterations, so we know the dates will be appropriately offset. if( $days < $num_days ) { // real days $cal_dates[] = $days+1; if( in_array( $days+1, $this->daysWithEvents ) ) { $cal_dates_style[] = 'has-events'; $cal_dates_data[] = $this->data[ $days+1 ]; } else { $cal_dates_style[] = ''; $cal_dates_data[] = ''; } } else { After the offset days, and the days of the month, we set an appropriate class indicating that the current box is not an actual date in the month: // surplus $cal_dates[] = ''; $cal_dates_style[] = 'calendar-empty'; $cal_dates_data[] = ''; } } Download from Wow! eBook <www.wowebook.com> . over": $days = $this->startDay - $first_day_of_month; if( $days > 1 ) { // get an offset $days -= 7; } $num_days = $this->daysInMonth($this->month, $this->year); // 42. representation of the current month and set that: $this->orderedDays = $this->getDaysInOrder(); $this->monthName = $this->months[ ltrim( $this->month, '0') ]; Since we need to. $month, $year ) { $this->year = ( $year == '' ) ? date('y') : $year; $this->month = ( $month == '' ) ? date('m') : $month; $this->day = ( $day ==