| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- Reviewed: no -->
- <sect1 id="zend.gdata.calendar">
- <title>Using Google Calendar</title>
- <para>
- You can use the
- <classname>Zend_Gdata_Calendar</classname>
- class to view, create, update, and delete events in the online Google Calendar service.
- </para>
- <para>
- See <ulink
- url="http://code.google.com/apis/calendar/overview.html">
- http://code.google.com/apis/calendar/overview.html</ulink>
- for more information about the Google Calendar <acronym>API</acronym>.
- </para>
- <sect2 id="zend.gdata.calendar.connecting">
- <title>Connecting To The Calendar Service</title>
- <para>
- The Google Calendar <acronym>API</acronym>, like all GData <acronym>API</acronym>s, is
- based off of the Atom Publishing Protocol (APP), an <acronym>XML</acronym> based format
- for managing web-based resources. Traffic between a client and the Google Calendar
- servers occurs over <acronym>HTTP</acronym> and allows for both authenticated and
- unauthenticated connections.
- </para>
- <para>
- Before any transactions can occur, this connection needs to be made. Creating a
- connection to the calendar servers involves two steps: creating an
- <acronym>HTTP</acronym> client and binding a <classname>Zend_Gdata_Calendar</classname>
- service instance to that client.
- </para>
- <sect3 id="zend.gdata.calendar.connecting.authentication">
- <title>Authentication</title>
- <para>
- The Google Calendar <acronym>API</acronym> allows access to both public and private
- calendar feeds. Public feeds do not require authentication, but are read-only and
- offer reduced functionality. Private feeds offers the most complete functionality
- but requires an authenticated connection to the calendar servers. There are three
- authentication schemes that are supported by Google Calendar:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <firstterm>ClientAuth</firstterm>
- provides direct username/password authentication to the
- calendar servers. Since this scheme requires that users
- provide your application with their password, this
- authentication is only recommended when other
- authentication schemes are insufficient.
- </para>
- </listitem>
- <listitem>
- <para>
- <firstterm>AuthSub</firstterm>
- allows authentication to the calendar servers via a
- Google proxy server. This provides the same level of
- convenience as ClientAuth but without the security
- risk, making this an ideal choice for web-based
- applications.
- </para>
- </listitem>
- <listitem>
- <para>
- <firstterm>MagicCookie</firstterm>
- allows authentication based on a semi-random <acronym>URL</acronym>
- available from within the Google Calendar interface.
- This is the simplest authentication scheme to
- implement, but requires that users manually retrieve
- their secure <acronym>URL</acronym> before they can authenticate, doesn't
- provide access to calendar lists, and is limited to
- read-only access.
- </para>
- </listitem>
- </itemizedlist>
- <para>
- The <classname>Zend_Gdata</classname>
- library provides support for all three authentication schemes.
- The rest of this chapter will assume that you are familiar the
- authentication schemes available and how to create an
- appropriate authenticated connection. For more information,
- please see section the <link
- linkend="zend.gdata.introduction.authentication">Authentication section</link>
- of this manual or the <ulink
- url="http://code.google.com/apis/gdata/auth.html">Authentication Overview in the
- Google Data <acronym>API</acronym> Developer's Guide</ulink>.
- </para>
- </sect3>
- <sect3 id="zend.gdata.calendar.connecting.service">
- <title>Creating A Service Instance</title>
- <para>
- In order to interact with Google Calendar, this library provides the
- <classname>Zend_Gdata_Calendar</classname> service class. This class provides a
- common interface to the Google Data and Atom Publishing Protocol models and assists
- in marshaling requests to and from the calendar servers.
- </para>
- <para>
- Once deciding on an authentication scheme, the next step is to create an instance
- of <classname>Zend_Gdata_Calendar</classname>. The class constructor takes an
- instance of <classname>Zend_Http_Client</classname> as a single argument. This
- provides an interface for AuthSub and ClientAuth authentication, as both of these
- require creation of a special authenticated <acronym>HTTP</acronym> client. If no
- arguments are provided, an unauthenticated instance of
- <classname>Zend_Http_Client</classname> will be automatically created.
- </para>
- <para>
- The example below shows how to create a Calendar service class using ClientAuth
- authentication:
- </para>
- <programlisting language="php"><![CDATA[
- // Parameters for ClientAuth authentication
- $service = Zend_Gdata_Calendar::AUTH_SERVICE_NAME;
- $user = "sample.user@gmail.com";
- $pass = "pa$$w0rd";
- // Create an authenticated HTTP client
- $client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $service);
- // Create an instance of the Calendar service
- $service = new Zend_Gdata_Calendar($client);
- ]]></programlisting>
- <para>
- A Calendar service using AuthSub can be created in a similar, though slightly more
- lengthy fashion:
- </para>
- <programlisting language="php"><![CDATA[
- /*
- * Retrieve the current URL so that the AuthSub server knows where to
- * redirect the user after authentication is complete.
- */
- function getCurrentUrl()
- {
- global $_SERVER;
- // Filter php_self to avoid a security vulnerability.
- $php_request_uri =
- htmlentities(substr($_SERVER['REQUEST_URI'],
- 0,
- strcspn($_SERVER['REQUEST_URI'], "\n\r")),
- ENT_QUOTES);
- if (isset($_SERVER['HTTPS']) &&
- strtolower($_SERVER['HTTPS']) == 'on') {
- $protocol = 'https://';
- } else {
- $protocol = 'http://';
- }
- $host = $_SERVER['HTTP_HOST'];
- if ($_SERVER['HTTP_PORT'] != '' &&
- (($protocol == 'http://' && $_SERVER['HTTP_PORT'] != '80') ||
- ($protocol == 'https://' && $_SERVER['HTTP_PORT'] != '443'))) {
- $port = ':' . $_SERVER['HTTP_PORT'];
- } else {
- $port = '';
- }
- return $protocol . $host . $port . $php_request_uri;
- }
- /**
- * Obtain an AuthSub authenticated HTTP client, redirecting the user
- * to the AuthSub server to login if necessary.
- */
- function getAuthSubHttpClient()
- {
- global $_SESSION, $_GET;
- // if there is no AuthSub session or one-time token waiting for us,
- // redirect the user to the AuthSub server to get one.
- if (!isset($_SESSION['sessionToken']) && !isset($_GET['token'])) {
- // Parameters to give to AuthSub server
- $next = getCurrentUrl();
- $scope = "http://www.google.com/calendar/feeds/";
- $secure = false;
- $session = true;
- // Redirect the user to the AuthSub server to sign in
- $authSubUrl = Zend_Gdata_AuthSub::getAuthSubTokenUri($next,
- $scope,
- $secure,
- $session);
- header("HTTP/1.0 307 Temporary redirect");
- header("Location: " . $authSubUrl);
- exit();
- }
- // Convert an AuthSub one-time token into a session token if needed
- if (!isset($_SESSION['sessionToken']) && isset($_GET['token'])) {
- $_SESSION['sessionToken'] =
- Zend_Gdata_AuthSub::getAuthSubSessionToken($_GET['token']);
- }
- // At this point we are authenticated via AuthSub and can obtain an
- // authenticated HTTP client instance
- // Create an authenticated HTTP client
- $client = Zend_Gdata_AuthSub::getHttpClient($_SESSION['sessionToken']);
- return $client;
- }
- // -> Script execution begins here <-
- // Make sure that the user has a valid session, so we can record the
- // AuthSub session token once it is available.
- session_start();
- // Create an instance of the Calendar service, redirecting the user
- // to the AuthSub server if necessary.
- $service = new Zend_Gdata_Calendar(getAuthSubHttpClient());
- ]]></programlisting>
- <para>
- Finally, an unauthenticated server can be created for use with either public feeds
- or MagicCookie authentication:
- </para>
- <programlisting language="php"><![CDATA[
- // Create an instance of the Calendar service using an unauthenticated
- // HTTP client
- $service = new Zend_Gdata_Calendar();
- ]]></programlisting>
- <para>
- Note that MagicCookie authentication is not supplied with the
- <acronym>HTTP</acronym> connection, but is instead specified along with the desired
- visibility when submitting queries. See the section on retrieving events below for
- an example.
- </para>
- </sect3>
- </sect2>
- <sect2 id="zend.gdata.calendar_retrieval">
- <title>Retrieving A Calendar List</title>
- <para>
- The calendar service supports retrieving a list of calendars for the authenticated
- user. This is the same list of calendars which are displayed in the Google Calendar
- UI, except those marked as "<emphasis>hidden</emphasis>" are also available.
- </para>
- <para>
- The calendar list is always private and must be accessed over an authenticated
- connection. It is not possible to retrieve another user's calendar list and it cannot
- be accessed using MagicCookie authentication. Attempting to access a calendar list
- without holding appropriate credentials will fail and result in a 401 (Authentication
- Required) status code.
- </para>
- <programlisting language="php"><![CDATA[
- $service = Zend_Gdata_Calendar::AUTH_SERVICE_NAME;
- $client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $service);
- $service = new Zend_Gdata_Calendar($client);
- try {
- $listFeed= $service->getCalendarListFeed();
- } catch (Zend_Gdata_App_Exception $e) {
- echo "Error: " . $e->getMessage();
- }
- ]]></programlisting>
- <para>
- Calling <methodname>getCalendarListFeed()</methodname> creates a new instance of
- <classname>Zend_Gdata_Calendar_ListFeed</classname> containing each available calendar
- as an instance of <classname>Zend_Gdata_Calendar_ListEntry</classname>. After retrieving
- the feed, you can use the iterator and accessors contained within the feed to inspect
- the enclosed calendars.
- </para>
- <programlisting language="php"><![CDATA[
- echo "<h1>Calendar List Feed</h1>";
- echo "<ul>";
- foreach ($listFeed as $calendar) {
- echo "<li>" . $calendar->title .
- " (Event Feed: " . $calendar->id . ")</li>";
- }
- echo "</ul>";
- ]]></programlisting>
- </sect2>
- <sect2 id="zend.gdata.event_retrieval">
- <title>Retrieving Events</title>
- <para>
- Like the list of calendars, events are also retrieved using the
- <classname>Zend_Gdata_Calendar</classname> service class. The event list returned is of
- type <classname>Zend_Gdata_Calendar_EventFeed</classname> and contains each event as an
- instance of <classname>Zend_Gdata_Calendar_EventEntry</classname>. As before, the
- iterator and accessors contained within the event feed instance allow inspection of
- individual events.
- </para>
- <sect3 id="zend.gdata.event_retrieval.queries">
- <title>Queries</title>
- <para>
- When retrieving events using the Calendar <acronym>API</acronym>, specially
- constructed query <acronym>URL</acronym>s are used to describe what events should be
- returned. The <classname>Zend_Gdata_Calendar_EventQuery</classname> class simplifies
- this task by automatically constructing a query <acronym>URL</acronym> based on
- provided parameters. A full list of these parameters is available at the <ulink
- url="http://code.google.com/apis/gdata/reference.html#Queries">Queries section
- of the Google Data <acronym>API</acronym>s Protocol Reference</ulink>. However,
- there are three parameters that are worth special attention:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <firstterm>User</firstterm>
- is used to specify the user whose calendar is being
- searched for, and is specified as an email address. If
- no user is provided, "default" will be used instead to
- indicate the currently authenticated user (if
- authenticated).
- </para>
- </listitem>
- <listitem>
- <para>
- <firstterm>Visibility</firstterm>
- specifies whether a users public or private calendar
- should be searched. If using an unauthenticated session
- and no MagicCookie is available, only the public feed
- will be available.
- </para>
- </listitem>
- <listitem>
- <para>
- <firstterm>Projection</firstterm>
- specifies how much data should be returned by the
- server and in what format. In most cases you will want
- to use the "full" projection. Also available is the
- "basic" projection, which places most meta-data into
- each event's content field as human readable text, and
- the "composite" projection which includes complete text
- for any comments alongside each event. The "composite"
- view is often much larger than the "full" view.
- </para>
- </listitem>
- </itemizedlist>
- </sect3>
- <sect3 id="zend.gdata.event_retrieval.start_time">
- <title>Retrieving Events In Order Of Start Time</title>
- <para>
- The example below illustrates the use of the <classname>Zend_Gdata_Query</classname>
- class and specifies the private visibility feed, which requires that an
- authenticated connection is available to the calendar servers. If a MagicCookie is
- being used for authentication, the visibility should be instead set to
- "<emphasis>private-magicCookieValue</emphasis>", where magicCookieValue is the
- random string obtained when viewing the private <acronym>XML</acronym> address in
- the Google Calendar UI. Events are requested chronologically by start time and only
- events occurring in the future are returned.
- </para>
- <programlisting language="php"><![CDATA[
- $query = $service->newEventQuery();
- $query->setUser('default');
- // Set to $query->setVisibility('private-magicCookieValue') if using
- // MagicCookie auth
- $query->setVisibility('private');
- $query->setProjection('full');
- $query->setOrderby('starttime');
- $query->setFutureevents('true');
- // Retrieve the event list from the calendar server
- try {
- $eventFeed = $service->getCalendarEventFeed($query);
- } catch (Zend_Gdata_App_Exception $e) {
- echo "Error: " . $e->getMessage();
- }
- // Iterate through the list of events, outputting them as an HTML list
- echo "<ul>";
- foreach ($eventFeed as $event) {
- echo "<li>" . $event->title . " (Event ID: " . $event->id . ")</li>";
- }
- echo "</ul>";
- ]]></programlisting>
- <para>
- Additional properties such as ID, author, when, event status, visibility, web
- content, and content, among others are available within
- <classname>Zend_Gdata_Calendar_EventEntry</classname>. Refer to the
- <ulink url="http://framework.zend.com/apidoc/core/">Zend Framework
- <acronym>API</acronym> Documentation</ulink> and the
- <ulink url="http://code.google.com/apis/gdata/reference.html">Calendar Protocol
- Reference</ulink> for a complete list.
- </para>
- </sect3>
- <sect3 id="zend.gdata.event_retrieval.date_range">
- <title>Retrieving Events In A Specified Date Range</title>
- <para>
- To print out all events within a certain range, for example from December 1,
- 2006 through December 15, 2007, add the following two lines to the previous sample.
- Take care to remove "<command>$query->setFutureevents('true')</command>", since
- <property>futureevents</property> will override <property>startMin</property> and
- <property>startMax</property>.
- </para>
- <programlisting language="php"><![CDATA[
- $query->setStartMin('2006-12-01');
- $query->setStartMax('2006-12-16');
- ]]></programlisting>
- <para>
- Note that <property>startMin</property> is inclusive whereas
- <property>startMax</property> is exclusive. As a result, only events through
- 2006-12-15 23:59:59 will be returned.
- </para>
- </sect3>
- <sect3 id="zend.gdata.event_retrieval.fulltext">
- <title>Retrieving Events By Fulltext Query</title>
- <para>
- To print out all events which contain a specific word, for example "dogfood", use
- the <methodname>setQuery()</methodname> method when creating the query.
- </para>
- <programlisting language="php"><![CDATA[
- $query->setQuery("dogfood");
- ]]></programlisting>
- </sect3>
- <sect3 id="zend.gdata.event_retrieval.individual">
- <title>Retrieving Individual Events</title>
- <para>
- Individual events can be retrieved by specifying their event ID as part of the
- query. Instead of calling <methodname>getCalendarEventFeed()</methodname>,
- <methodname>getCalendarEventEntry()</methodname> should be called instead.
- </para>
- <programlisting language="php"><![CDATA[
- $query = $service->newEventQuery();
- $query->setUser('default');
- $query->setVisibility('private');
- $query->setProjection('full');
- $query->setEvent($eventId);
- try {
- $event = $service->getCalendarEventEntry($query);
- } catch (Zend_Gdata_App_Exception $e) {
- echo "Error: " . $e->getMessage();
- }
- ]]></programlisting>
- <para>
- In a similar fashion, if the event <acronym>URL</acronym> is known, it can be passed
- directly into <methodname>getCalendarEntry()</methodname> to retrieve a specific
- event. In this case, no query object is required since the event
- <acronym>URL</acronym> contains all the necessary information to retrieve the event.
- </para>
- <programlisting language="php"><![CDATA[
- $eventURL = "http://www.google.com/calendar/feeds/default/private"
- . "/full/g829on5sq4ag12se91d10uumko";
- try {
- $event = $service->getCalendarEventEntry($eventURL);
- } catch (Zend_Gdata_App_Exception $e) {
- echo "Error: " . $e->getMessage();
- }
- ]]></programlisting>
- </sect3>
- </sect2>
- <sect2 id="zend.gdata.calendar.creating_events">
- <title>Creating Events</title>
- <sect3 id="zend.gdata.calendar.creating_events.single">
- <title>Creating Single-Occurrence Events</title>
- <para>
- Events are added to a calendar by creating an instance of
- <classname>Zend_Gdata_EventEntry</classname> and populating it with the appropriate
- data. The calendar service instance (<classname>Zend_Gdata_Calendar</classname>) is
- then used to used to transparently covert the event into <acronym>XML</acronym> and
- POST it to the calendar server. Creating events requires either an AuthSub or
- ClientAuth authenticated connection to the calendar server.
- </para>
- <para>At a minimum, the following attributes should be set:</para>
- <itemizedlist>
- <listitem>
- <para>
- <firstterm>Title</firstterm>
- provides the headline that will appear above the event
- within the Google Calendar UI.
- </para>
- </listitem>
- <listitem>
- <para>
- <firstterm>When</firstterm>
- indicates the duration of the event and, optionally,
- any reminders that are associated with it. See the next
- section for more information on this attribute.
- </para>
- </listitem>
- </itemizedlist>
- <para>Other useful attributes that may optionally set include:</para>
- <itemizedlist>
- <listitem>
- <para>
- <firstterm>Author</firstterm>
- provides information about the user who created the
- event.
- </para>
- </listitem>
- <listitem>
- <para>
- <firstterm>Content</firstterm>
- provides additional information about the event which
- appears when the event details are requested from
- within Google Calendar.
- </para>
- </listitem>
- <listitem>
- <para>
- <firstterm>EventStatus</firstterm>
- indicates whether the event is confirmed, tentative, or
- canceled.
- </para>
- </listitem>
- <listitem>
- <para>
- <firstterm>Transparency</firstterm>
- indicates whether the event should be consume time on
- the user's free/busy list.
- </para>
- </listitem>
- <listitem>
- <para>
- <firstterm>WebContent</firstterm>
- allows links to external content to be provided within
- an event.
- </para>
- </listitem>
- <listitem>
- <para>
- <firstterm>Where</firstterm>
- indicates the location of the event.
- </para>
- </listitem>
- <listitem>
- <para>
- <firstterm>Visibility</firstterm>
- allows the event to be hidden from the public event
- lists.
- </para>
- </listitem>
- </itemizedlist>
- <para>
- For a complete list of event attributes, refer to the <ulink
- url="http://framework.zend.com/apidoc/core/">Zend Framework
- <acronym>API</acronym> Documentation</ulink> and the <ulink
- url="http://code.google.com/apis/gdata/reference.html">Calendar Protocol
- Reference</ulink>. Attributes that can contain multiple values, such as where,
- are implemented as arrays and need to be created accordingly. Be aware that all of
- these attributes require objects as parameters. Trying instead to populate them
- using strings or primitives will result in errors during conversion to
- <acronym>XML</acronym>.
- </para>
- <para>
- Once the event has been populated, it can be uploaded to the calendar server by
- passing it as an argument to the calendar service's
- <methodname>insertEvent()</methodname> function.
- </para>
- <programlisting language="php"><![CDATA[
- // Create a new entry using the calendar service's magic factory method
- $event= $service->newEventEntry();
- // Populate the event with the desired information
- // Note that each attribute is crated as an instance of a matching class
- $event->title = $service->newTitle("My Event");
- $event->where = array($service->newWhere("Mountain View, California"));
- $event->content =
- $service->newContent(" This is my awesome event. RSVP required.");
- // Set the date using RFC 3339 format.
- $startDate = "2008-01-20";
- $startTime = "14:00";
- $endDate = "2008-01-20";
- $endTime = "16:00";
- $tzOffset = "-08";
- $when = $service->newWhen();
- $when->startTime = "{$startDate}T{$startTime}:00.000{$tzOffset}:00";
- $when->endTime = "{$endDate}T{$endTime}:00.000{$tzOffset}:00";
- $event->when = array($when);
- // Upload the event to the calendar server
- // A copy of the event as it is recorded on the server is returned
- $newEvent = $service->insertEvent($event);
- ]]></programlisting>
- </sect3>
- <sect3 id="zend.gdata.calendar.creating_events.schedulers_reminders">
- <title>Event Schedules and Reminders</title>
- <para>
- An event's starting time and duration are determined by the value of its
- <property>when</property> property, which contains the properties
- <property>startTime</property>, <property>endTime</property>, and
- <property>valueString</property>. <emphasis>StartTime</emphasis> and
- <emphasis>EndTime</emphasis> control the duration of the
- event, while the <property>valueString</property> property is currently unused.
- </para>
- <para>
- All-day events can be scheduled by specifying only the date omitting the time when
- setting <property>startTime</property> and <property>endTime</property>. Likewise,
- zero-duration events can be specified by omitting the <property>endTime</property>.
- In all cases, date and time values should be provided in
- <ulink url="http://www.ietf.org/rfc/rfc3339.txt">RFC3339</ulink> format.
- </para>
- <programlisting language="php"><![CDATA[
- // Schedule the event to occur on December 05, 2007 at 2 PM PST (UTC-8)
- // with a duration of one hour.
- $when = $service->newWhen();
- $when->startTime = "2007-12-05T14:00:00-08:00";
- $when->endTime="2007-12-05T15:00:00:00-08:00";
- // Apply the when property to an event
- $event->when = array($when);
- ]]></programlisting>
- <para>
- The <property>when</property> attribute also controls when reminders are sent to a
- user. Reminders are stored in an array and each event may have up to find reminders
- associated with it.
- </para>
- <para>
- For a <emphasis>reminder</emphasis> to be valid, it needs to have two attributes
- set: <property>method</property> and a time. <emphasis>Method</emphasis> can accept
- one of the following strings: "alert", "email", or "sms". The time should be entered
- as an integer and can be set with either the property <property>minutes</property>,
- <property>hours</property>, <property>days</property>, or
- <property>absoluteTime</property>. However, a valid request may only have one of
- these attributes set. If a mixed time is desired, convert to the most precise unit
- available. For example, 1 hour and 30 minutes should be entered as 90 minutes.
- </para>
- <programlisting language="php"><![CDATA[
- // Create a new reminder object. It should be set to send an email
- // to the user 10 minutes beforehand.
- $reminder = $service->newReminder();
- $reminder->method = "email";
- $reminder->minutes = "10";
- // Apply the reminder to an existing event's when property
- $when = $event->when[0];
- $when->reminders = array($reminder);
- ]]></programlisting>
- </sect3>
- <sect3 id="zend.gdata.calendar.creating_events.recurring">
- <title>Creating Recurring Events</title>
- <para>
- Recurring events are created the same way as single-occurrence events, except a
- recurrence attribute should be provided instead of a where attribute. The
- recurrence attribute should hold a string describing the event's recurrence pattern
- using properties defined in the iCalendar standard (<ulink
- url="http://www.ietf.org/rfc/rfc2445.txt">RFC 2445</ulink>).
- </para>
- <para>
- Exceptions to the recurrence pattern will usually be specified by a distinct
- <property>recurrenceException</property> attribute. However, the iCalendar standard
- provides a secondary format for defining recurrences, and the possibility that
- either may be used must be accounted for.
- </para>
- <para>
- Due to the complexity of parsing recurrence patterns, further information on this
- them is outside the scope of this document. However, more information can be found
- in the <ulink
- url="http://code.google.com/apis/gdata/elements.html#gdRecurrence">Common
- Elements section of the Google Data <acronym>API</acronym>s Developer
- Guide</ulink>, as well as in <acronym>RFC</acronym> 2445.
- </para>
- <programlisting language="php"><![CDATA[
- // Create a new entry using the calendar service's magic factory method
- $event= $service->newEventEntry();
- // Populate the event with the desired information
- // Note that each attribute is crated as an instance of a matching class
- $event->title = $service->newTitle("My Recurring Event");
- $event->where = array($service->newWhere("Palo Alto, California"));
- $event->content =
- $service->newContent(' This is my other awesome event, ' .
- ' occurring all-day every Tuesday from ' .
- '2007-05-01 until 207-09-04. No RSVP required.');
- // Set the duration and frequency by specifying a recurrence pattern.
- $recurrence = "DTSTART;VALUE=DATE:20070501\r\n" .
- "DTEND;VALUE=DATE:20070502\r\n" .
- "RRULE:FREQ=WEEKLY;BYDAY=Tu;UNTIL=20070904\r\n";
- $event->recurrence = $service->newRecurrence($recurrence);
- // Upload the event to the calendar server
- // A copy of the event as it is recorded on the server is returned
- $newEvent = $service->insertEvent($event);
- ]]></programlisting>
- </sect3>
- <sect3 id="zend.gdata.calendar.creating_events.quickadd">
- <title>Using QuickAdd</title>
- <para>
- QuickAdd is a feature which allows events to be created using free-form text entry.
- For example, the string "Dinner at Joe's Diner on Thursday" would create an event
- with the title "Dinner", location "Joe's Diner", and date "Thursday". To take
- advantage of QuickAdd, create a new <property>QuickAdd</property> property set to
- <constant>TRUE</constant> and store the freeform text as a
- <property>content</property> property.
- </para>
- <programlisting language="php"><![CDATA[
- // Create a new entry using the calendar service's magic factory method
- $event= $service->newEventEntry();
- // Populate the event with the desired information
- $event->content= $service->newContent("Dinner at Joe's Diner on Thursday");
- $event->quickAdd = $service->newQuickAdd("true");
- // Upload the event to the calendar server
- // A copy of the event as it is recorded on the server is returned
- $newEvent = $service->insertEvent($event);
- ]]></programlisting>
- </sect3>
- </sect2>
- <sect2 id="zend.gdata.calendar.modifying_events">
- <title>Modifying Events</title>
- <para>
- Once an instance of an event has been obtained, the event's attributes can be locally
- modified in the same way as when creating an event. Once all modifications are
- complete, calling the event's <methodname>save()</methodname> method will upload the
- changes to the calendar server and return a copy of the event as it was created on the
- server.
- </para>
- <para>
- In the event another user has modified the event since the local copy was retrieved,
- <methodname>save()</methodname> will fail and the server will return a 409 (Conflict)
- status code. To resolve this a fresh copy of the event must be retrieved from the server
- before attempting to resubmit any modifications.
- </para>
- <programlisting language="php"><![CDATA[
- // Get the first event in the user's event list
- $event = $eventFeed[0];
- // Change the title to a new value
- $event->title = $service->newTitle("Woof!");
- // Upload the changes to the server
- try {
- $event->save();
- } catch (Zend_Gdata_App_Exception $e) {
- echo "Error: " . $e->getMessage();
- }
- ]]></programlisting>
- </sect2>
- <sect2 id="zend.gdata.calendar.deleting_events">
- <title>Deleting Events</title>
- <para>
- Calendar events can be deleted either by calling the calendar service's
- <methodname>delete()</methodname> method and providing the edit <acronym>URL</acronym>
- of an event or by calling an existing event's own <methodname>delete()</methodname>
- method.
- </para>
- <para>
- In either case, the deleted event will still show up on a user's private event feed if
- an <property>updateMin</property> query parameter is provided. Deleted events can be
- distinguished from regular events because they will have their
- <property>eventStatus</property> property set to
- "http://schemas.google.com/g/2005#event.canceled".
- </para>
- <programlisting language="php"><![CDATA[
- // Option 1: Events can be deleted directly
- $event->delete();
- ]]></programlisting>
- <programlisting language="php"><![CDATA[
- // Option 2: Events can be deleted supplying the edit URL of the event
- // to the calendar service, if known
- $service->delete($event->getEditLink()->href);
- ]]></programlisting>
- </sect2>
- <sect2 id="zend.gdata.calendar.comments">
- <title>Accessing Event Comments</title>
- <para>
- When using the full event view, comments are not directly stored within an entry.
- Instead, each event contains a <acronym>URL</acronym> to its associated comment feed
- which must be manually requested.
- </para>
- <para>
- Working with comments is fundamentally similar to working with events, with the only
- significant difference being that a different feed and event class should be used and
- that the additional meta-data for events such as where and when does not exist for
- comments. Specifically, the comment's author is stored in the
- <property>author</property> property, and the comment text is stored in the
- <property>content</property> property.
- </para>
- <programlisting language="php"><![CDATA[
- // Extract the comment URL from the first event in a user's feed list
- $event = $eventFeed[0];
- $commentUrl = $event->comments->feedLink->url;
- // Retrieve the comment list for the event
- try {
- $commentFeed = $service->getFeed($commentUrl);
- } catch (Zend_Gdata_App_Exception $e) {
- echo "Error: " . $e->getMessage();
- }
- // Output each comment as an HTML list
- echo "<ul>";
- foreach ($commentFeed as $comment) {
- echo "<li><em>Comment By: " . $comment->author->name "</em><br/>" .
- $comment->content . "</li>";
- }
- echo "</ul>";
- ]]></programlisting>
- </sect2>
- </sect1>
|