]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - Zend/Gdata/Gapps.php
Release 6.5.0
[Github/sugarcrm.git] / Zend / Gdata / Gapps.php
1 <?php
2
3 /**
4  * Zend Framework
5  *
6  * LICENSE
7  *
8  * This source file is subject to the new BSD license that is bundled
9  * with this package in the file LICENSE.txt.
10  * It is also available through the world-wide-web at this URL:
11  * http://framework.zend.com/license/new-bsd
12  * If you did not receive a copy of the license and are unable to
13  * obtain it through the world-wide-web, please send an email
14  * to license@zend.com so we can send you a copy immediately.
15  *
16  * @category   Zend
17  * @package    Zend_Gdata
18  * @subpackage Gapps
19  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
20  * @license    http://framework.zend.com/license/new-bsd     New BSD License
21
22  */
23
24 /**
25  * @see Zend_Gdata
26  */
27 require_once 'Zend/Gdata.php';
28
29 /**
30  * @see Zend_Gdata_Gapps_UserFeed
31  */
32 require_once 'Zend/Gdata/Gapps/UserFeed.php';
33
34 /**
35  * @see Zend_Gdata_Gapps_NicknameFeed
36  */
37 require_once 'Zend/Gdata/Gapps/NicknameFeed.php';
38
39 /**
40  * @see Zend_Gdata_Gapps_GroupFeed
41  */
42 require_once 'Zend/Gdata/Gapps/GroupFeed.php';
43
44 /**
45  * @see Zend_Gdata_Gapps_MemberFeed
46  */
47 require_once 'Zend/Gdata/Gapps/MemberFeed.php';
48
49 /**
50  * @see Zend_Gdata_Gapps_OwnerFeed
51  */
52 require_once 'Zend/Gdata/Gapps/OwnerFeed.php';
53
54 /**
55  * @see Zend_Gdata_Gapps_EmailListFeed
56  */
57 require_once 'Zend/Gdata/Gapps/EmailListFeed.php';
58
59 /**
60  * @see Zend_Gdata_Gapps_EmailListRecipientFeed
61  */
62 require_once 'Zend/Gdata/Gapps/EmailListRecipientFeed.php';
63
64
65 /**
66  * Service class for interacting with the Google Apps Provisioning API.
67  *
68  * Like other service classes in this module, this class provides access via
69  * an HTTP client to Google servers for working with entries and feeds.
70  *
71  * Because of the nature of this API, all access must occur over an
72  * authenticated connection.
73  *
74  * @link http://code.google.com/apis/apps/gdata_provisioning_api_v2.0_reference.html
75  *
76  * @category   Zend
77  * @package    Zend_Gdata
78  * @subpackage Gapps
79  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
80  * @license    http://framework.zend.com/license/new-bsd     New BSD License
81  */
82 class Zend_Gdata_Gapps extends Zend_Gdata
83 {
84
85     const APPS_BASE_FEED_URI = 'https://apps-apis.google.com/a/feeds';
86     const AUTH_SERVICE_NAME = 'apps';
87
88     /**
89      * Path to user feeds on the Google Apps server.
90      */
91     const APPS_USER_PATH = '/user/2.0';
92
93     /**
94      * Path to nickname feeds on the Google Apps server.
95      */
96     const APPS_NICKNAME_PATH = '/nickname/2.0';
97
98     /**
99      * Path to group feeds on the Google Apps server.
100      */
101     const APPS_GROUP_PATH = '/group/2.0';
102
103     /**
104      * Path to email list feeds on the Google Apps server.
105      */
106     const APPS_EMAIL_LIST_PATH = '/emailList/2.0';
107
108     /**
109      * Path to email list recipient feeds on the Google Apps server.
110      */
111     const APPS_EMAIL_LIST_RECIPIENT_POSTFIX = '/recipient';
112
113     /**
114      * The domain which is being administered via the Provisioning API.
115      *
116      * @var string
117      */
118     protected $_domain = null;
119
120     /**
121      * Namespaces used for Zend_Gdata_Gapps
122      *
123      * @var array
124      */
125     public static $namespaces = array(
126         array('apps', 'http://schemas.google.com/apps/2006', 1, 0)
127     );
128
129     /**
130      * Create Gdata_Gapps object
131      *
132      * @param Zend_Http_Client $client (optional) The HTTP client to use when
133      *          when communicating with the Google Apps servers.
134      * @param string $domain (optional) The Google Apps domain which is to be
135      *          accessed.
136      * @param string $applicationId The identity of the app in the form of Company-AppName-Version
137      */
138     public function __construct($client = null, $domain = null, $applicationId = 'MyCompany-MyApp-1.0')
139     {
140         $this->registerPackage('Zend_Gdata_Gapps');
141         $this->registerPackage('Zend_Gdata_Gapps_Extension');
142         parent::__construct($client, $applicationId);
143         $this->_httpClient->setParameterPost('service', self::AUTH_SERVICE_NAME);
144         $this->_domain = $domain;
145     }
146
147     /**
148      * Convert an exception to an ServiceException if an AppsForYourDomain
149      * XML document is contained within the original exception's HTTP
150      * response. If conversion fails, throw the original error.
151      *
152      * @param Zend_Gdata_Exception $e The exception to convert.
153      * @throws Zend_Gdata_Gapps_ServiceException
154      * @throws mixed
155      */
156     public static function throwServiceExceptionIfDetected($e) {
157         // Check to make sure that there actually response!
158         // This can happen if the connection dies before the request
159         // completes. (See ZF-5949)
160         $response = $e->getResponse();
161         if (!$response) {
162           require_once('Zend/Gdata/App/IOException.php');
163           throw new Zend_Gdata_App_IOException('No HTTP response received (possible connection failure)');
164         }
165
166         try {
167             // Check to see if there is an AppsForYourDomainErrors
168             // datastructure in the response. If so, convert it to
169             // an exception and throw it.
170             require_once 'Zend/Gdata/Gapps/ServiceException.php';
171             $error = new Zend_Gdata_Gapps_ServiceException();
172             $error->importFromString($response->getBody());
173             throw $error;
174         } catch (Zend_Gdata_App_Exception $e2) {
175             // Unable to convert the response to a ServiceException,
176             // most likely because the server didn't return an
177             // AppsForYourDomainErrors document. Throw the original
178             // exception.
179             throw $e;
180         }
181     }
182
183     /**
184      * Imports a feed located at $uri.
185      * This method overrides the default behavior of Zend_Gdata_App,
186      * providing support for Zend_Gdata_Gapps_ServiceException.
187      *
188      * @param  string $uri
189      * @param  Zend_Http_Client $client (optional) The client used for
190      *          communication
191      * @param  string $className (optional) The class which is used as the
192      *          return type
193      * @throws Zend_Gdata_App_Exception
194      * @throws Zend_Gdata_App_HttpException
195      * @throws Zend_Gdata_Gapps_ServiceException
196      * @return Zend_Gdata_App_Feed
197      */
198     public static function import($uri, $client = null, $className='Zend_Gdata_App_Feed')
199     {
200         try {
201             return parent::import($uri, $client, $className);
202         } catch (Zend_Gdata_App_HttpException $e) {
203             self::throwServiceExceptionIfDetected($e);
204         }
205     }
206
207     /**
208      * GET a URI using client object.
209      * This method overrides the default behavior of Zend_Gdata_App,
210      * providing support for Zend_Gdata_Gapps_ServiceException.
211      *
212      * @param string $uri GET URI
213      * @param array $extraHeaders Extra headers to add to the request, as an
214      *        array of string-based key/value pairs.
215      * @throws Zend_Gdata_App_HttpException
216      * @throws Zend_Gdata_Gapps_ServiceException
217      * @return Zend_Http_Response
218      */
219     public function get($uri, $extraHeaders = array())
220     {
221         try {
222             return parent::get($uri, $extraHeaders);
223         } catch (Zend_Gdata_App_HttpException $e) {
224             self::throwServiceExceptionIfDetected($e);
225         }
226     }
227
228     /**
229      * POST data with client object.
230      * This method overrides the default behavior of Zend_Gdata_App,
231      * providing support for Zend_Gdata_Gapps_ServiceException.
232      *
233      * @param mixed $data The Zend_Gdata_App_Entry or XML to post
234      * @param string $uri (optional) POST URI
235      * @param integer $remainingRedirects (optional)
236      * @param string $contentType Content-type of the data
237      * @param array $extraHaders Extra headers to add tot he request
238      * @return Zend_Http_Response
239      * @throws Zend_Gdata_App_HttpException
240      * @throws Zend_Gdata_App_InvalidArgumentException
241      * @throws Zend_Gdata_Gapps_ServiceException
242      */
243     public function post($data, $uri = null, $remainingRedirects = null,
244             $contentType = null, $extraHeaders = null)
245     {
246         try {
247             return parent::post($data, $uri, $remainingRedirects, $contentType, $extraHeaders);
248         } catch (Zend_Gdata_App_HttpException $e) {
249             self::throwServiceExceptionIfDetected($e);
250         }
251     }
252
253     /**
254      * PUT data with client object
255      * This method overrides the default behavior of Zend_Gdata_App,
256      * providing support for Zend_Gdata_Gapps_ServiceException.
257      *
258      * @param mixed $data The Zend_Gdata_App_Entry or XML to post
259      * @param string $uri (optional) PUT URI
260      * @param integer $remainingRedirects (optional)
261      * @param string $contentType Content-type of the data
262      * @param array $extraHaders Extra headers to add tot he request
263      * @return Zend_Http_Response
264      * @throws Zend_Gdata_App_HttpException
265      * @throws Zend_Gdata_App_InvalidArgumentException
266      * @throws Zend_Gdata_Gapps_ServiceException
267      */
268     public function put($data, $uri = null, $remainingRedirects = null,
269             $contentType = null, $extraHeaders = null)
270     {
271         try {
272             return parent::put($data, $uri, $remainingRedirects, $contentType, $extraHeaders);
273         } catch (Zend_Gdata_App_HttpException $e) {
274             self::throwServiceExceptionIfDetected($e);
275         }
276     }
277
278     /**
279      * DELETE entry with client object
280      * This method overrides the default behavior of Zend_Gdata_App,
281      * providing support for Zend_Gdata_Gapps_ServiceException.
282      *
283      * @param mixed $data The Zend_Gdata_App_Entry or URL to delete
284      * @param integer $remainingRedirects (optional)
285      * @return void
286      * @throws Zend_Gdata_App_HttpException
287      * @throws Zend_Gdata_App_InvalidArgumentException
288      * @throws Zend_Gdata_Gapps_ServiceException
289      */
290     public function delete($data, $remainingRedirects = null)
291     {
292         try {
293             return parent::delete($data, $remainingRedirects);
294         } catch (Zend_Gdata_App_HttpException $e) {
295             self::throwServiceExceptionIfDetected($e);
296         }
297     }
298
299     /**
300      * Set domain for this service instance. This should be a fully qualified
301      * domain, such as 'foo.example.com'.
302      *
303      * This value is used when calculating URLs for retrieving and posting
304      * entries. If no value is specified, a URL will have to be manually
305      * constructed prior to using any methods which interact with the Google
306      * Apps provisioning service.
307      *
308      * @param string $value The domain to be used for this session.
309      */
310     public function setDomain($value)
311     {
312         $this->_domain = $value;
313     }
314
315     /**
316      * Get domain for this service instance. This should be a fully qualified
317      * domain, such as 'foo.example.com'. If no domain is set, null will be
318      * returned.
319      *
320      * @return string The domain to be used for this session, or null if not
321      *          set.
322      */
323     public function getDomain()
324     {
325         return $this->_domain;
326     }
327
328     /**
329      * Returns the base URL used to access the Google Apps service, based
330      * on the current domain. The current domain can be temporarily
331      * overridden by providing a fully qualified domain as $domain.
332      *
333      * @param string $domain (optional) A fully-qualified domain to use
334      *          instead of the default domain for this service instance.
335      * @throws Zend_Gdata_App_InvalidArgumentException
336      */
337      public function getBaseUrl($domain = null)
338      {
339          if ($domain !== null) {
340              return self::APPS_BASE_FEED_URI . '/' . $domain;
341          } else if ($this->_domain !== null) {
342              return self::APPS_BASE_FEED_URI . '/' . $this->_domain;
343          } else {
344              require_once 'Zend/Gdata/App/InvalidArgumentException.php';
345              throw new Zend_Gdata_App_InvalidArgumentException(
346                      'Domain must be specified.');
347          }
348      }
349
350     /**
351      * Retrieve a UserFeed containing multiple UserEntry objects.
352      *
353      * @param mixed $location (optional) The location for the feed, as a URL
354      *          or Query.
355      * @return Zend_Gdata_Gapps_UserFeed
356      * @throws Zend_Gdata_App_Exception
357      * @throws Zend_Gdata_App_HttpException
358      * @throws Zend_Gdata_Gapps_ServiceException
359      */
360     public function getUserFeed($location = null)
361     {
362         if ($location === null) {
363             $uri = $this->getBaseUrl() . self::APPS_USER_PATH;
364         } else if ($location instanceof Zend_Gdata_Query) {
365             $uri = $location->getQueryUrl();
366         } else {
367             $uri = $location;
368         }
369         return parent::getFeed($uri, 'Zend_Gdata_Gapps_UserFeed');
370     }
371
372     /**
373      * Retreive NicknameFeed object containing multiple NicknameEntry objects.
374      *
375      * @param mixed $location (optional) The location for the feed, as a URL
376      *          or Query.
377      * @return Zend_Gdata_Gapps_NicknameFeed
378      * @throws Zend_Gdata_App_Exception
379      * @throws Zend_Gdata_App_HttpException
380      * @throws Zend_Gdata_Gapps_ServiceException
381      */
382     public function getNicknameFeed($location = null)
383     {
384         if ($location === null) {
385             $uri = $this->getBaseUrl() . self::APPS_NICKNAME_PATH;
386         } else if ($location instanceof Zend_Gdata_Query) {
387             $uri = $location->getQueryUrl();
388         } else {
389             $uri = $location;
390         }
391         return parent::getFeed($uri, 'Zend_Gdata_Gapps_NicknameFeed');
392     }
393
394     /**
395      * Retreive GroupFeed object containing multiple GroupEntry
396      * objects.
397      *
398      * @param mixed $location (optional) The location for the feed, as a URL
399      *          or Query.
400      * @return Zend_Gdata_Gapps_GroupFeed
401      * @throws Zend_Gdata_App_Exception
402      * @throws Zend_Gdata_App_HttpException
403      * @throws Zend_Gdata_Gapps_ServiceException
404      */
405     public function getGroupFeed($location = null)
406     {
407         if ($location === null) {
408             $uri  = self::APPS_BASE_FEED_URI . self::APPS_GROUP_PATH . '/';
409             $uri .= $this->getDomain();
410         } else if ($location instanceof Zend_Gdata_Query) {
411             $uri = $location->getQueryUrl();
412         } else {
413             $uri = $location;
414         }
415         return parent::getFeed($uri, 'Zend_Gdata_Gapps_GroupFeed');
416     }
417
418     /**
419      * Retreive MemberFeed object containing multiple MemberEntry
420      * objects.
421      *
422      * @param mixed $location (optional) The location for the feed, as a URL
423      *          or Query.
424      * @return Zend_Gdata_Gapps_MemberFeed
425      * @throws Zend_Gdata_App_Exception
426      * @throws Zend_Gdata_App_HttpException
427      * @throws Zend_Gdata_Gapps_ServiceException
428      */
429     public function getMemberFeed($location = null)
430     {
431         if ($location === null) {
432             require_once 'Zend/Gdata/App/InvalidArgumentException.php';
433             throw new Zend_Gdata_App_InvalidArgumentException(
434                     'Location must not be null');
435         } else if ($location instanceof Zend_Gdata_Query) {
436             $uri = $location->getQueryUrl();
437         } else {
438             $uri = $location;
439         }
440         return parent::getFeed($uri, 'Zend_Gdata_Gapps_MemberFeed');
441     }
442
443     /**
444      * Retreive OwnerFeed object containing multiple OwnerEntry
445      * objects.
446      *
447      * @param mixed $location (optional) The location for the feed, as a URL
448      *          or Query.
449      * @return Zend_Gdata_Gapps_OwnerFeed
450      * @throws Zend_Gdata_App_Exception
451      * @throws Zend_Gdata_App_HttpException
452      * @throws Zend_Gdata_Gapps_ServiceException
453      */
454     public function getOwnerFeed($location = null)
455     {
456         if ($location === null) {
457             require_once 'Zend/Gdata/App/InvalidArgumentException.php';
458             throw new Zend_Gdata_App_InvalidArgumentException(
459                     'Location must not be null');
460         } else if ($location instanceof Zend_Gdata_Query) {
461             $uri = $location->getQueryUrl();
462         } else {
463             $uri = $location;
464         }
465         return parent::getFeed($uri, 'Zend_Gdata_Gapps_OwnerFeed');
466     }
467
468     /**
469      * Retreive EmailListFeed object containing multiple EmailListEntry
470      * objects.
471      *
472      * @param mixed $location (optional) The location for the feed, as a URL
473      *          or Query.
474      * @return Zend_Gdata_Gapps_EmailListFeed
475      * @throws Zend_Gdata_App_Exception
476      * @throws Zend_Gdata_App_HttpException
477      * @throws Zend_Gdata_Gapps_ServiceException
478      */
479     public function getEmailListFeed($location = null)
480     {
481         if ($location === null) {
482             $uri = $this->getBaseUrl() . self::APPS_NICKNAME_PATH;
483         } else if ($location instanceof Zend_Gdata_Query) {
484             $uri = $location->getQueryUrl();
485         } else {
486             $uri = $location;
487         }
488         return parent::getFeed($uri, 'Zend_Gdata_Gapps_EmailListFeed');
489     }
490
491     /**
492      * Retreive EmailListRecipientFeed object containing multiple
493      * EmailListRecipientEntry objects.
494      *
495      * @param mixed $location The location for the feed, as a URL or Query.
496      * @return Zend_Gdata_Gapps_EmailListRecipientFeed
497      * @throws Zend_Gdata_App_Exception
498      * @throws Zend_Gdata_App_HttpException
499      * @throws Zend_Gdata_Gapps_ServiceException
500      */
501     public function getEmailListRecipientFeed($location)
502     {
503         if ($location === null) {
504             require_once 'Zend/Gdata/App/InvalidArgumentException.php';
505             throw new Zend_Gdata_App_InvalidArgumentException(
506                     'Location must not be null');
507         } else if ($location instanceof Zend_Gdata_Query) {
508             $uri = $location->getQueryUrl();
509         } else {
510             $uri = $location;
511         }
512         return parent::getFeed($uri, 'Zend_Gdata_Gapps_EmailListRecipientFeed');
513     }
514
515     /**
516      * Retreive a single UserEntry object.
517      *
518      * @param mixed $location The location for the feed, as a URL or Query.
519      * @return Zend_Gdata_Gapps_UserEntry
520      * @throws Zend_Gdata_App_Exception
521      * @throws Zend_Gdata_App_HttpException
522      * @throws Zend_Gdata_Gapps_ServiceException
523      */
524     public function getUserEntry($location)
525     {
526         if ($location === null) {
527             require_once 'Zend/Gdata/App/InvalidArgumentException.php';
528             throw new Zend_Gdata_App_InvalidArgumentException(
529                     'Location must not be null');
530         } else if ($location instanceof Zend_Gdata_Query) {
531             $uri = $location->getQueryUrl();
532         } else {
533             $uri = $location;
534         }
535         return parent::getEntry($uri, 'Zend_Gdata_Gapps_UserEntry');
536     }
537
538     /**
539      * Retreive a single NicknameEntry object.
540      *
541      * @param mixed $location The location for the feed, as a URL or Query.
542      * @return Zend_Gdata_Gapps_NicknameEntry
543      * @throws Zend_Gdata_App_Exception
544      * @throws Zend_Gdata_App_HttpException
545      * @throws Zend_Gdata_Gapps_ServiceException
546      */
547     public function getNicknameEntry($location)
548     {
549         if ($location === null) {
550             require_once 'Zend/Gdata/App/InvalidArgumentException.php';
551             throw new Zend_Gdata_App_InvalidArgumentException(
552                     'Location must not be null');
553         } else if ($location instanceof Zend_Gdata_Query) {
554             $uri = $location->getQueryUrl();
555         } else {
556             $uri = $location;
557         }
558         return parent::getEntry($uri, 'Zend_Gdata_Gapps_NicknameEntry');
559     }
560
561     /**
562      * Retreive a single GroupEntry object.
563      *
564      * @param mixed $location The location for the feed, as a URL or Query.
565      * @return Zend_Gdata_Gapps_GroupEntry
566      * @throws Zend_Gdata_App_Exception
567      * @throws Zend_Gdata_App_HttpException
568      * @throws Zend_Gdata_Gapps_ServiceException
569      */
570     public function getGroupEntry($location = null)
571     {
572         if ($location === null) {
573             require_once 'Zend/Gdata/App/InvalidArgumentException.php';
574             throw new Zend_Gdata_App_InvalidArgumentException(
575                     'Location must not be null');
576         } else if ($location instanceof Zend_Gdata_Query) {
577             $uri = $location->getQueryUrl();
578         } else {
579             $uri = $location;
580         }
581         return parent::getEntry($uri, 'Zend_Gdata_Gapps_GroupEntry');
582     }
583
584     /**
585      * Retreive a single MemberEntry object.
586      *
587      * @param mixed $location The location for the feed, as a URL or Query.
588      * @return Zend_Gdata_Gapps_MemberEntry
589      * @throws Zend_Gdata_App_Exception
590      * @throws Zend_Gdata_App_HttpException
591      * @throws Zend_Gdata_Gapps_ServiceException
592      */
593     public function getMemberEntry($location = null)
594     {
595         if ($location === null) {
596             require_once 'Zend/Gdata/App/InvalidArgumentException.php';
597             throw new Zend_Gdata_App_InvalidArgumentException(
598                     'Location must not be null');
599         } else if ($location instanceof Zend_Gdata_Query) {
600             $uri = $location->getQueryUrl();
601         } else {
602             $uri = $location;
603         }
604         return parent::getEntry($uri, 'Zend_Gdata_Gapps_MemberEntry');
605     }
606
607     /**
608      * Retreive a single OwnerEntry object.
609      *
610      * @param mixed $location The location for the feed, as a URL or Query.
611      * @return Zend_Gdata_Gapps_OwnerEntry
612      * @throws Zend_Gdata_App_Exception
613      * @throws Zend_Gdata_App_HttpException
614      * @throws Zend_Gdata_Gapps_ServiceException
615      */
616     public function getOwnerEntry($location = null)
617     {
618         if ($location === null) {
619             require_once 'Zend/Gdata/App/InvalidArgumentException.php';
620             throw new Zend_Gdata_App_InvalidArgumentException(
621                     'Location must not be null');
622         } else if ($location instanceof Zend_Gdata_Query) {
623             $uri = $location->getQueryUrl();
624         } else {
625             $uri = $location;
626         }
627         return parent::getEntry($uri, 'Zend_Gdata_Gapps_OwnerEntry');
628     }
629
630     /**
631      * Retreive a single EmailListEntry object.
632      *
633      * @param mixed $location The location for the feed, as a URL or Query.
634      * @return Zend_Gdata_Gapps_EmailListEntry
635      * @throws Zend_Gdata_App_Exception
636      * @throws Zend_Gdata_App_HttpException
637      * @throws Zend_Gdata_Gapps_ServiceException
638      */
639     public function getEmailListEntry($location)
640     {
641         if ($location === null) {
642             require_once 'Zend/Gdata/App/InvalidArgumentException.php';
643             throw new Zend_Gdata_App_InvalidArgumentException(
644                     'Location must not be null');
645         } else if ($location instanceof Zend_Gdata_Query) {
646             $uri = $location->getQueryUrl();
647         } else {
648             $uri = $location;
649         }
650         return parent::getEntry($uri, 'Zend_Gdata_Gapps_EmailListEntry');
651     }
652
653     /**
654      * Retreive a single EmailListRecipientEntry object.
655      *
656      * @param mixed $location The location for the feed, as a URL or Query.
657      * @return Zend_Gdata_Gapps_EmailListRecipientEntry
658      * @throws Zend_Gdata_App_Exception
659      * @throws Zend_Gdata_App_HttpException
660      * @throws Zend_Gdata_Gapps_ServiceException
661      */
662     public function getEmailListRecipientEntry($location)
663     {
664         if ($location === null) {
665             require_once 'Zend/Gdata/App/InvalidArgumentException.php';
666             throw new Zend_Gdata_App_InvalidArgumentException(
667                     'Location must not be null');
668         } else if ($location instanceof Zend_Gdata_Query) {
669             $uri = $location->getQueryUrl();
670         } else {
671             $uri = $location;
672         }
673         return parent::getEntry($uri, 'Zend_Gdata_Gapps_EmailListRecipientEntry');
674     }
675
676     /**
677      * Create a new user from a UserEntry.
678      *
679      * @param Zend_Gdata_Gapps_UserEntry $user The user entry to insert.
680      * @param string $uri (optional) The URI where the user should be
681      *          uploaded to. If null, the default user creation URI for
682      *          this domain will be used.
683      * @return Zend_Gdata_Gapps_UserEntry The inserted user entry as
684      *          returned by the server.
685      * @throws Zend_Gdata_App_Exception
686      * @throws Zend_Gdata_App_HttpException
687      * @throws Zend_Gdata_Gapps_ServiceException
688      */
689     public function insertUser($user, $uri = null)
690     {
691         if ($uri === null) {
692             $uri = $this->getBaseUrl() . self::APPS_USER_PATH;
693         }
694         $newEntry = $this->insertEntry($user, $uri, 'Zend_Gdata_Gapps_UserEntry');
695         return $newEntry;
696     }
697
698     /**
699      * Create a new nickname from a NicknameEntry.
700      *
701      * @param Zend_Gdata_Gapps_NicknameEntry $nickname The nickname entry to
702      *          insert.
703      * @param string $uri (optional) The URI where the nickname should be
704      *          uploaded to. If null, the default nickname creation URI for
705      *          this domain will be used.
706      * @return Zend_Gdata_Gapps_NicknameEntry The inserted nickname entry as
707      *          returned by the server.
708      * @throws Zend_Gdata_App_Exception
709      * @throws Zend_Gdata_App_HttpException
710      * @throws Zend_Gdata_Gapps_ServiceException
711      */
712     public function insertNickname($nickname, $uri = null)
713     {
714         if ($uri === null) {
715             $uri = $this->getBaseUrl() . self::APPS_NICKNAME_PATH;
716         }
717         $newEntry = $this->insertEntry($nickname, $uri, 'Zend_Gdata_Gapps_NicknameEntry');
718         return $newEntry;
719     }
720
721     /**
722      * Create a new group from a GroupEntry.
723      *
724      * @param Zend_Gdata_Gapps_GroupEntry $group The group entry to insert.
725      * @param string $uri (optional) The URI where the group should be
726      *          uploaded to. If null, the default user creation URI for
727      *          this domain will be used.
728      * @return Zend_Gdata_Gapps_GroupEntry The inserted group entry as
729      *          returned by the server.
730      * @throws Zend_Gdata_App_Exception
731      * @throws Zend_Gdata_App_HttpException
732      * @throws Zend_Gdata_Gapps_ServiceException
733      */
734     public function insertGroup($group, $uri = null)
735     {
736         if ($uri === null) {
737             $uri  = self::APPS_BASE_FEED_URI . self::APPS_GROUP_PATH . '/';
738             $uri .= $this->getDomain();
739         }
740         $newEntry = $this->insertEntry($group, $uri, 'Zend_Gdata_Gapps_GroupEntry');
741         return $newEntry;
742     }
743
744     /**
745      * Create a new member from a MemberEntry.
746      *
747      * @param Zend_Gdata_Gapps_MemberEntry $member The member entry to insert.
748      * @param string $uri (optional) The URI where the group should be
749      *          uploaded to. If null, the default user creation URI for
750      *          this domain will be used.
751      * @return Zend_Gdata_Gapps_MemberEntry The inserted member entry as
752      *          returned by the server.
753      * @throws Zend_Gdata_App_Exception
754      * @throws Zend_Gdata_App_HttpException
755      * @throws Zend_Gdata_Gapps_ServiceException
756      */
757     public function insertMember($member, $uri = null)
758     {
759         if ($uri === null) {
760             require_once 'Zend/Gdata/App/InvalidArgumentException.php';
761             throw new Zend_Gdata_App_InvalidArgumentException(
762                     'URI must not be null');
763         }
764         $newEntry = $this->insertEntry($member, $uri, 'Zend_Gdata_Gapps_MemberEntry');
765         return $newEntry;
766     }
767
768     /**
769      * Create a new group from a OwnerEntry.
770      *
771      * @param Zend_Gdata_Gapps_OwnerEntry $owner The owner entry to insert.
772      * @param string $uri (optional) The URI where the owner should be
773      *          uploaded to. If null, the default user creation URI for
774      *          this domain will be used.
775      * @return Zend_Gdata_Gapps_OwnerEntry The inserted owner entry as
776      *          returned by the server.
777      * @throws Zend_Gdata_App_Exception
778      * @throws Zend_Gdata_App_HttpException
779      * @throws Zend_Gdata_Gapps_ServiceException
780      */
781     public function insertOwner($owner, $uri = null)
782     {
783         if ($uri === null) {
784             require_once 'Zend/Gdata/App/InvalidArgumentException.php';
785             throw new Zend_Gdata_App_InvalidArgumentException(
786                     'URI must not be null');
787         }
788         $newEntry = $this->insertEntry($owner, $uri, 'Zend_Gdata_Gapps_OwnerEntry');
789         return $newEntry;
790     }
791
792     /**
793      * Create a new email list from an EmailListEntry.
794      *
795      * @param Zend_Gdata_Gapps_EmailListEntry $emailList The email list entry
796      *          to insert.
797      * @param string $uri (optional) The URI where the email list should be
798      *          uploaded to. If null, the default email list creation URI for
799      *          this domain will be used.
800      * @return Zend_Gdata_Gapps_EmailListEntry The inserted email list entry
801      *          as returned by the server.
802      * @throws Zend_Gdata_App_Exception
803      * @throws Zend_Gdata_App_HttpException
804      * @throws Zend_Gdata_Gapps_ServiceException
805      */
806     public function insertEmailList($emailList, $uri = null)
807     {
808         if ($uri === null) {
809             $uri = $this->getBaseUrl() . self::APPS_EMAIL_LIST_PATH;
810         }
811         $newEntry = $this->insertEntry($emailList, $uri, 'Zend_Gdata_Gapps_EmailListEntry');
812         return $newEntry;
813     }
814
815     /**
816      * Create a new email list recipient from an EmailListRecipientEntry.
817      *
818      * @param Zend_Gdata_Gapps_EmailListRecipientEntry $recipient The recipient
819      *          entry to insert.
820      * @param string $uri (optional) The URI where the recipient should be
821      *          uploaded to. If null, the default recipient creation URI for
822      *          this domain will be used.
823      * @return Zend_Gdata_Gapps_EmailListRecipientEntry The inserted
824      *          recipient entry as returned by the server.
825      * @throws Zend_Gdata_App_Exception
826      * @throws Zend_Gdata_App_HttpException
827      * @throws Zend_Gdata_Gapps_ServiceException
828      */
829     public function insertEmailListRecipient($recipient, $uri = null)
830     {
831         if ($uri === null) {
832             require_once 'Zend/Gdata/App/InvalidArgumentException.php';
833             throw new Zend_Gdata_App_InvalidArgumentException(
834                     'URI must not be null');
835         } elseif ($uri instanceof Zend_Gdata_Gapps_EmailListEntry) {
836             $uri = $uri->getLink('edit')->href;
837         }
838         $newEntry = $this->insertEntry($recipient, $uri, 'Zend_Gdata_Gapps_EmailListRecipientEntry');
839         return $newEntry;
840     }
841
842     /**
843      * Provides a magic factory method to instantiate new objects with
844      * shorter syntax than would otherwise be required by the Zend Framework
845      * naming conventions. For more information, see Zend_Gdata_App::__call().
846      *
847      * This overrides the default behavior of __call() so that query classes
848      * do not need to have their domain manually set when created with
849      * a magic factory method.
850      *
851      * @see Zend_Gdata_App::__call()
852      * @param string $method The method name being called
853      * @param array $args The arguments passed to the call
854      * @throws Zend_Gdata_App_Exception
855      */
856     public function __call($method, $args) {
857         if (preg_match('/^new(\w+Query)/', $method, $matches)) {
858             $class = $matches[1];
859             $foundClassName = null;
860             foreach ($this->_registeredPackages as $name) {
861                  try {
862                      // Autoloading disabled on next line for compatibility
863                      // with magic factories. See ZF-6660.
864                      if (!class_exists($name . '_' . $class, false)) {
865                         require_once 'Zend/Loader.php';
866                         @Zend_Loader::loadClass($name . '_' . $class);
867                      }
868                      $foundClassName = $name . '_' . $class;
869                      break;
870                  } catch (Zend_Exception $e) {
871                      // package wasn't here- continue searching
872                  }
873             }
874             if ($foundClassName != null) {
875                 $reflectionObj = new ReflectionClass($foundClassName);
876                 // Prepend the domain to the query
877                 $args = array_merge(array($this->getDomain()), $args);
878                 return $reflectionObj->newInstanceArgs($args);
879             } else {
880                 require_once 'Zend/Gdata/App/Exception.php';
881                 throw new Zend_Gdata_App_Exception(
882                         "Unable to find '${class}' in registered packages");
883             }
884         } else {
885             return parent::__call($method, $args);
886         }
887
888     }
889
890     // Convenience methods
891     // Specified at http://code.google.com/apis/apps/gdata_provisioning_api_v2.0_reference.html#appendix_e
892
893     /**
894      * Create a new user entry and send it to the Google Apps servers.
895      *
896      * @param string $username The username for the new user.
897      * @param string $givenName The given name for the new user.
898      * @param string $familyName The family name for the new user.
899      * @param string $password The password for the new user as a plaintext string
900      *                 (if $passwordHashFunction is null) or a SHA-1 hashed
901      *                 value (if $passwordHashFunction = 'SHA-1').
902      * @param string $quotaLimitInMB (optional) The quota limit for the new user in MB.
903      * @return Zend_Gdata_Gapps_UserEntry (optional) The new user entry as returned by
904      *                 server.
905      * @throws Zend_Gdata_App_Exception
906      * @throws Zend_Gdata_App_HttpException
907      * @throws Zend_Gdata_Gapps_ServiceException
908      */
909     public function createUser ($username, $givenName, $familyName, $password,
910             $passwordHashFunction = null, $quotaLimitInMB = null) {
911         $user = $this->newUserEntry();
912         $user->login = $this->newLogin();
913         $user->login->username = $username;
914         $user->login->password = $password;
915         $user->login->hashFunctionName = $passwordHashFunction;
916         $user->name = $this->newName();
917         $user->name->givenName = $givenName;
918         $user->name->familyName = $familyName;
919         if ($quotaLimitInMB !== null) {
920             $user->quota = $this->newQuota();
921             $user->quota->limit = $quotaLimitInMB;
922         }
923         return $this->insertUser($user);
924     }
925
926     /**
927      * Retrieve a user based on their username.
928      *
929      * @param string $username The username to search for.
930      * @return Zend_Gdata_Gapps_UserEntry The username to search for, or null
931      *              if no match found.
932      * @throws Zend_Gdata_App_InvalidArgumentException
933      * @throws Zend_Gdata_App_HttpException
934      */
935     public function retrieveUser ($username) {
936         $query = $this->newUserQuery($username);
937         try {
938             $user = $this->getUserEntry($query);
939         } catch (Zend_Gdata_Gapps_ServiceException $e) {
940             // Set the user to null if not found
941             if ($e->hasError(Zend_Gdata_Gapps_Error::ENTITY_DOES_NOT_EXIST)) {
942                 $user = null;
943             } else {
944                 throw $e;
945             }
946         }
947         return $user;
948     }
949
950     /**
951      * Retrieve a page of users in alphabetical order, starting with the
952      * provided username.
953      *
954      * @param string $startUsername (optional) The first username to retrieve.
955      *          If null or not declared, the page will begin with the first
956      *          user in the domain.
957      * @return Zend_Gdata_Gapps_UserFeed Collection of Zend_Gdata_UserEntry
958      *              objects representing all users in the domain.
959      * @throws Zend_Gdata_App_Exception
960      * @throws Zend_Gdata_App_HttpException
961      * @throws Zend_Gdata_Gapps_ServiceException
962      */
963     public function retrievePageOfUsers ($startUsername = null) {
964         $query = $this->newUserQuery();
965         $query->setStartUsername($startUsername);
966         return $this->getUserFeed($query);
967     }
968
969     /**
970      * Retrieve all users in the current domain. Be aware that
971      * calling this function on a domain with many users will take a
972      * signifigant amount of time to complete. On larger domains this may
973      * may cause execution to timeout without proper precautions in place.
974      *
975      * @return Zend_Gdata_Gapps_UserFeed Collection of Zend_Gdata_UserEntry
976      *              objects representing all users in the domain.
977      * @throws Zend_Gdata_App_Exception
978      * @throws Zend_Gdata_App_HttpException
979      * @throws Zend_Gdata_Gapps_ServiceException
980      */
981     public function retrieveAllUsers () {
982         return $this->retrieveAllEntriesForFeed($this->retrievePageOfUsers());
983     }
984
985     /**
986      * Overwrite a specified username with the provided UserEntry.  The
987      * UserEntry does not need to contain an edit link.
988      *
989      * This method is provided for compliance with the Google Apps
990      * Provisioning API specification. Normally users will instead want to
991      * call UserEntry::save() instead.
992      *
993      * @see Zend_Gdata_App_Entry::save
994      * @param string $username The username whose data will be overwritten.
995      * @param Zend_Gdata_Gapps_UserEntry $userEntry The user entry which
996      *          will be overwritten.
997      * @return Zend_Gdata_Gapps_UserEntry The UserEntry returned by the
998      *          server.
999      * @throws Zend_Gdata_App_Exception
1000      * @throws Zend_Gdata_App_HttpException
1001      * @throws Zend_Gdata_Gapps_ServiceException
1002      */
1003     public function updateUser($username, $userEntry) {
1004         return $this->updateEntry($userEntry, $this->getBaseUrl() .
1005             self::APPS_USER_PATH . '/' . $username);
1006     }
1007
1008     /**
1009      * Mark a given user as suspended.
1010      *
1011      * @param string $username The username associated with the user who
1012      *          should be suspended.
1013      * @return Zend_Gdata_Gapps_UserEntry The UserEntry for the modified
1014      *          user.
1015      * @throws Zend_Gdata_App_Exception
1016      * @throws Zend_Gdata_App_HttpException
1017      * @throws Zend_Gdata_Gapps_ServiceException
1018      */
1019     public function suspendUser($username) {
1020         $user = $this->retrieveUser($username);
1021         $user->login->suspended = true;
1022         return $user->save();
1023     }
1024
1025     /**
1026      * Mark a given user as not suspended.
1027      *
1028      * @param string $username The username associated with the user who
1029      *          should be restored.
1030      * @return Zend_Gdata_Gapps_UserEntry The UserEntry for the modified
1031      *          user.
1032      * @throws Zend_Gdata_App_Exception
1033      * @throws Zend_Gdata_App_HttpException
1034      * @throws Zend_Gdata_Gapps_ServiceException
1035      */
1036     public function restoreUser($username) {
1037         $user = $this->retrieveUser($username);
1038         $user->login->suspended = false;
1039         return $user->save();
1040     }
1041
1042     /**
1043      * Delete a user by username.
1044      *
1045      * @param string $username The username associated with the user who
1046      *          should be deleted.
1047      * @throws Zend_Gdata_App_Exception
1048      * @throws Zend_Gdata_App_HttpException
1049      * @throws Zend_Gdata_Gapps_ServiceException
1050      */
1051     public function deleteUser($username) {
1052         $this->delete($this->getBaseUrl() . self::APPS_USER_PATH . '/' .
1053             $username);
1054     }
1055
1056     /**
1057      * Create a nickname for a given user.
1058      *
1059      * @param string $username The username to which the new nickname should
1060      *          be associated.
1061      * @param string $nickname The new nickname to be created.
1062      * @return Zend_Gdata_Gapps_NicknameEntry The nickname entry which was
1063      *          created by the server.
1064      * @throws Zend_Gdata_App_Exception
1065      * @throws Zend_Gdata_App_HttpException
1066      * @throws Zend_Gdata_Gapps_ServiceException
1067      */
1068     public function createNickname($username, $nickname) {
1069         $entry = $this->newNicknameEntry();
1070         $nickname = $this->newNickname($nickname);
1071         $login = $this->newLogin($username);
1072         $entry->nickname = $nickname;
1073         $entry->login = $login;
1074         return $this->insertNickname($entry);
1075     }
1076
1077     /**
1078      * Retrieve the entry for a specified nickname.
1079      *
1080      * @param string $nickname The nickname to be retrieved.
1081      * @return Zend_Gdata_Gapps_NicknameEntry The requested nickname entry.
1082      * @throws Zend_Gdata_App_Exception
1083      * @throws Zend_Gdata_App_HttpException
1084      * @throws Zend_Gdata_Gapps_ServiceException
1085      */
1086     public function retrieveNickname($nickname) {
1087         $query = $this->newNicknameQuery();
1088         $query->setNickname($nickname);
1089         try {
1090             $nickname = $this->getNicknameEntry($query);
1091         } catch (Zend_Gdata_Gapps_ServiceException $e) {
1092             // Set the nickname to null if not found
1093             if ($e->hasError(Zend_Gdata_Gapps_Error::ENTITY_DOES_NOT_EXIST)) {
1094                 $nickname = null;
1095             } else {
1096                 throw $e;
1097             }
1098         }
1099         return $nickname;
1100     }
1101
1102     /**
1103      * Retrieve all nicknames associated with a specific username.
1104      *
1105      * @param string $username The username whose nicknames should be
1106      *          returned.
1107      * @return Zend_Gdata_Gapps_NicknameFeed A feed containing all nicknames
1108      *          for the given user, or null if
1109      * @throws Zend_Gdata_App_Exception
1110      * @throws Zend_Gdata_App_HttpException
1111      * @throws Zend_Gdata_Gapps_ServiceException
1112      */
1113     public function retrieveNicknames($username) {
1114         $query = $this->newNicknameQuery();
1115         $query->setUsername($username);
1116         $nicknameFeed = $this->retrieveAllEntriesForFeed(
1117             $this->getNicknameFeed($query));
1118         return $nicknameFeed;
1119     }
1120
1121     /**
1122      * Retrieve a page of nicknames in alphabetical order, starting with the
1123      * provided nickname.
1124      *
1125      * @param string $startNickname (optional) The first nickname to
1126      *          retrieve. If null or not declared, the page will begin with
1127      *          the first nickname in the domain.
1128      * @return Zend_Gdata_Gapps_NicknameFeed Collection of Zend_Gdata_NicknameEntry
1129      *              objects representing all nicknames in the domain.
1130      * @throws Zend_Gdata_App_Exception
1131      * @throws Zend_Gdata_App_HttpException
1132      * @throws Zend_Gdata_Gapps_ServiceException
1133      */
1134     public function retrievePageOfNicknames ($startNickname = null) {
1135         $query = $this->newNicknameQuery();
1136         $query->setStartNickname($startNickname);
1137         return $this->getNicknameFeed($query);
1138     }
1139
1140     /**
1141      * Retrieve all nicknames in the current domain. Be aware that
1142      * calling this function on a domain with many nicknames will take a
1143      * signifigant amount of time to complete. On larger domains this may
1144      * may cause execution to timeout without proper precautions in place.
1145      *
1146      * @return Zend_Gdata_Gapps_NicknameFeed Collection of Zend_Gdata_NicknameEntry
1147      *              objects representing all nicknames in the domain.
1148      * @throws Zend_Gdata_App_Exception
1149      * @throws Zend_Gdata_App_HttpException
1150      * @throws Zend_Gdata_Gapps_ServiceException
1151      */
1152     public function retrieveAllNicknames () {
1153         return $this->retrieveAllEntriesForFeed($this->retrievePageOfNicknames());
1154     }
1155
1156     /**
1157      * Delete a specified nickname.
1158      *
1159      * @param string $nickname The name of the nickname to be deleted.
1160      * @throws Zend_Gdata_App_Exception
1161      * @throws Zend_Gdata_App_HttpException
1162      * @throws Zend_Gdata_Gapps_ServiceException
1163      */
1164     public function deleteNickname($nickname) {
1165         $this->delete($this->getBaseUrl() . self::APPS_NICKNAME_PATH . '/' . $nickname);
1166     }
1167
1168     /**
1169      * Create a new group.
1170      *
1171      * @param string $groupId A unique identifier for the group
1172      * @param string $groupName The name of the group
1173      * @param string $description A description of the group
1174      * @param string $emailPermission The subscription permission of the group
1175      * @return Zend_Gdata_Gapps_GroupEntry The group entry as created on the server.
1176      */
1177     public function createGroup($groupId, $groupName, $description = null, $emailPermission = null)
1178     {
1179         $i = 0;
1180         $group = $this->newGroupEntry();
1181         
1182         $properties[$i] = $this->newProperty();
1183         $properties[$i]->name = 'groupId';
1184         $properties[$i]->value = $groupId;
1185         $i++;
1186         $properties[$i] = $this->newProperty();
1187         $properties[$i]->name = 'groupName';
1188         $properties[$i]->value = $groupName;
1189         $i++;
1190
1191         if($description != null) {
1192             $properties[$i] = $this->newProperty();
1193             $properties[$i]->name = 'description';
1194             $properties[$i]->value = $description;
1195             $i++;
1196         }
1197
1198         if($emailPermission != null) {
1199             $properties[$i] = $this->newProperty();
1200             $properties[$i]->name = 'emailPermission';
1201             $properties[$i]->value = $emailPermission;
1202             $i++;
1203         }        
1204         
1205         $group->property = $properties;
1206
1207         return $this->insertGroup($group);
1208     }
1209
1210     /**
1211      * Retrieves a group based on group id
1212      *
1213      * @param string $groupId The unique identifier for the group
1214      * @return Zend_Gdata_Gapps_GroupEntry The group entry as returned by the server.
1215      */
1216     public function retrieveGroup($groupId)
1217     {
1218         $query = $this->newGroupQuery($groupId);
1219         //$query->setGroupId($groupId);
1220
1221         try {
1222             $group = $this->getGroupEntry($query);
1223         } catch (Zend_Gdata_Gapps_ServiceException $e) {
1224             // Set the group to null if not found
1225             if ($e->hasError(Zend_Gdata_Gapps_Error::ENTITY_DOES_NOT_EXIST)) {
1226                 $group = null;
1227             } else {
1228                 throw $e;
1229             }
1230         }
1231         return $group;
1232     }
1233
1234     /**
1235      * Retrieve all groups in the current domain. Be aware that
1236      * calling this function on a domain with many groups will take a
1237      * signifigant amount of time to complete. On larger domains this may
1238      * may cause execution to timeout without proper precautions in place.
1239      *
1240      * @return Zend_Gdata_Gapps_GroupFeed Collection of Zend_Gdata_GroupEntry objects
1241      *              representing all groups apart of the domain.
1242      */
1243     public function retrieveAllGroups() 
1244     {
1245         return $this->retrieveAllEntriesForFeed($this->retrievePageOfGroups());
1246     }
1247
1248     /**
1249      * Delete a group
1250      *
1251      * @param string $groupId The unique identifier for the group
1252      */
1253     public function deleteGroup($groupId)
1254     {
1255         $uri  = self::APPS_BASE_FEED_URI . self::APPS_GROUP_PATH . '/';
1256         $uri .= $this->getDomain() . '/' . $groupId;
1257
1258         $this->delete($uri);
1259     }
1260     
1261     /**
1262      * Check to see if a member id or group id is a member of group
1263      *
1264      * @param string $memberId Member id or group group id
1265      * @param string $groupId Group to be checked for
1266      * @return bool True, if given entity is a member
1267      */
1268     public function isMember($memberId, $groupId)
1269     {
1270         $uri  = self::APPS_BASE_FEED_URI . self::APPS_GROUP_PATH . '/';
1271         $uri .= $this->getDomain() . '/' . $groupId . '/member/' . $memberId;
1272         
1273         //if the enitiy is not a member, an exception is thrown
1274         try {
1275             $results = $this->get($uri);
1276         } catch (Exception $e) {
1277             $results = false;
1278         }
1279
1280         if($results) {
1281             return TRUE;
1282         } else {
1283             return FALSE;
1284         }
1285     }
1286
1287     /**
1288      * Add an email address to a group as a member
1289      *
1290      * @param string $recipientAddress Email address, member id, or group id
1291      * @param string $groupId The unique id of the group
1292      * @return Zend_Gdata_Gapps_MemberEntry The member entry returned by the server
1293      */
1294     public function addMemberToGroup($recipientAddress, $groupId)
1295     {
1296         $member = $this->newMemberEntry();
1297
1298         $properties[] = $this->newProperty();
1299         $properties[0]->name = 'memberId';
1300         $properties[0]->value = $recipientAddress;
1301
1302         $member->property = $properties;
1303
1304         $uri  = self::APPS_BASE_FEED_URI . self::APPS_GROUP_PATH . '/';
1305         $uri .= $this->getDomain() . '/' . $groupId . '/member';
1306
1307         return $this->insertMember($member, $uri);
1308     }
1309
1310     /**
1311      * Remove a member id from a group
1312      *
1313      * @param string $memberId Member id or group id
1314      * @param string $groupId The unique id of the group
1315      */
1316     public function removeMemberFromGroup($memberId, $groupId)
1317     {
1318         $uri  = self::APPS_BASE_FEED_URI . self::APPS_GROUP_PATH . '/';
1319         $uri .= $this->getDomain() . '/' . $groupId . '/member/' . $memberId;
1320
1321         return $this->delete($uri);
1322     }
1323
1324     /**
1325      * Retrieves all the members of a group
1326      *
1327      * @param string $groupId The unique id of the group
1328      * @return Zend_Gdata_Gapps_MemberFeed Collection of MemberEntry objects
1329      *              representing all members apart of the group.
1330      */
1331     public function retrieveAllMembers($groupId)
1332     {
1333         return $this->retrieveAllEntriesForFeed(
1334                 $this->retrievePageOfMembers($groupId));
1335     }
1336
1337     /**
1338      * Add an email as an owner of a group
1339      *
1340      * @param string $email Owner's email
1341      * @param string $groupId Group ownership to be checked for
1342      * @return Zend_Gdata_Gapps_OwnerEntry The OwnerEntry returned by the server
1343      */
1344     public function addOwnerToGroup($email, $groupId)
1345     {
1346         $owner = $this->newOwnerEntry();
1347
1348         $properties[] = $this->newProperty();
1349         $properties[0]->name = 'email';
1350         $properties[0]->value = $email;
1351
1352         $owner->property = $properties;
1353
1354         $uri  = self::APPS_BASE_FEED_URI . self::APPS_GROUP_PATH . '/';
1355         $uri .= $this->getDomain() . '/' . $groupId . '/owner';
1356         
1357         return $this->insertOwner($owner, $uri);
1358     }
1359
1360     /**
1361      * Retrieves all the owners of a group
1362      *
1363      * @param string $groupId The unique identifier for the group
1364      * @return Zend_Gdata_Gapps_OwnerFeed Collection of Zend_Gdata_OwnerEntry
1365      *              objects representing all owners apart of the group.
1366      */
1367     public function retrieveGroupOwners($groupId)
1368     {
1369         $uri  = self::APPS_BASE_FEED_URI . self::APPS_GROUP_PATH . '/';
1370         $uri .= $this->getDomain() . '/' . $groupId . '/owner';
1371
1372         return $this->getOwnerFeed($uri);
1373     }
1374
1375     /**
1376      * Checks to see if an email is an owner of a group
1377      *
1378      * @param string $email Owner's email
1379      * @param string $groupId Group ownership to be checked for
1380      * @return bool True, if given entity is an owner
1381      */
1382     public function isOwner($email, $groupId)
1383     {
1384         $uri  = self::APPS_BASE_FEED_URI . self::APPS_GROUP_PATH . '/';
1385         $uri .= $this->getDomain() . '/' . $groupId . '/owner/' . $email;
1386         
1387         //if the enitiy is not an owner of the group, an exception is thrown
1388         try {            
1389             $results = $this->get($uri);
1390         } catch (Exception $e) {
1391             $results = false;
1392         }
1393
1394         if($results) {
1395             return TRUE;
1396         } else {
1397             return FALSE;
1398         }
1399     }
1400
1401     /**
1402      * Remove email as an owner of a group
1403      *
1404      * @param string $email Owner's email
1405      * @param string $groupId The unique identifier for the group
1406      */
1407     public function removeOwnerFromGroup($email, $groupId)
1408     {
1409         $uri  = self::APPS_BASE_FEED_URI . self::APPS_GROUP_PATH . '/';
1410         $uri .= $this->getDomain() . '/' . $groupId . '/owner/' . $email;
1411
1412         return $this->delete($uri);
1413     }
1414
1415     /**
1416      * Update group properties with new values. any property not defined will not
1417      * be updated
1418      *
1419      * @param string $groupId A unique identifier for the group
1420      * @param string $groupName The name of the group
1421      * @param string $description A description of the group
1422      * @param string $emailPermission The subscription permission of the group
1423      * @return Zend_Gdata_Gapps_GroupEntry The group entry as updated on the server.
1424      */
1425     public function updateGroup($groupId, $groupName = null, $description = null,
1426             $emailPermission = null)
1427     {
1428         $i = 0;
1429         $group = $this->newGroupEntry();
1430         
1431         $properties[$i] = $this->newProperty();
1432         $properties[$i]->name = 'groupId';
1433         $properties[$i]->value = $groupId;
1434         $i++;
1435
1436         if($groupName != null) {
1437             $properties[$i] = $this->newProperty();
1438             $properties[$i]->name = 'groupName';
1439             $properties[$i]->value = $groupName;
1440             $i++;
1441         }
1442
1443         if($description != null) {
1444             $properties[$i] = $this->newProperty();
1445             $properties[$i]->name = 'description';
1446             $properties[$i]->value = $description;
1447             $i++;
1448         }
1449
1450         if($emailPermission != null) {
1451             $properties[$i] = $this->newProperty();
1452             $properties[$i]->name = 'emailPermission';
1453             $properties[$i]->value = $emailPermission;
1454             $i++;
1455         }
1456         
1457         $group->property = $properties;
1458
1459         $uri  = self::APPS_BASE_FEED_URI . self::APPS_GROUP_PATH . '/';
1460         $uri .= $this->getDomain() . '/' . $groupId;
1461
1462         return $this->updateEntry($group, $uri, 'Zend_Gdata_Gapps_GroupEntry');        
1463     }
1464
1465     /**
1466      * Retrieve all of the groups that a user is a member of
1467      *
1468      * @param string $memberId Member username
1469      * @param bool $directOnly (Optional) If true, members with direct association 
1470      *             only will be considered
1471      * @return Zend_Gdata_Gapps_GroupFeed Collection of Zend_Gdata_GroupEntry
1472      *              objects representing all groups member is apart of in the domain.
1473      */
1474     public function retrieveGroups($memberId, $directOnly = null)
1475     {
1476         $query = $this->newGroupQuery();
1477         $query->setMember($memberId);
1478         if($directOnly != null) {
1479             $query->setDirectOnly($directOnly);
1480         }
1481         return $this->getGroupFeed($query);
1482     }
1483
1484     /**
1485      * Retrieve a page of groups in alphabetical order, starting with the
1486      * provided group.
1487      *
1488      * @param string $startGroup (optional) The first group to
1489      *              retrieve. If null or not defined, the page will begin
1490      *              with the first group in the domain.
1491      * @return Zend_Gdata_Gapps_GroupFeed Collection of Zend_Gdata_GroupEntry
1492      *              objects representing the groups in the domain.
1493      * @throws Zend_Gdata_App_Exception
1494      * @throws Zend_Gdata_App_HttpException
1495      * @throws Zend_Gdata_Gapps_ServiceException
1496      */
1497     public function retrievePageOfGroups ($startGroup = null)
1498     {
1499         $query = $this->newGroupQuery();
1500         $query->setStartGroupId($startGroup);
1501         return $this->getGroupFeed($query);
1502     }
1503
1504     /**
1505      * Gets page of Members
1506      *
1507      * @param string $groupId The group id which should be searched.
1508      * @param string $startMember (optinal) The address of the first member,
1509      *              or null to start with the first member in the list.
1510      * @return Zend_Gdata_Gapps_MemberFeed Collection of Zend_Gdata_MemberEntry
1511      *              objects
1512      */
1513     public function retrievePageOfMembers($groupId, $startMember = null)
1514     {
1515         $query = $this->newMemberQuery($groupId);
1516         $query->setStartMemberId($startMember);
1517         return $this->getMemberFeed($query);
1518     }
1519
1520     /**
1521      * Create a new email list.
1522      *
1523      * @param string $emailList The name of the email list to be created.
1524      * @return Zend_Gdata_Gapps_EmailListEntry The email list entry
1525      *          as created on the server.
1526      * @throws Zend_Gdata_App_Exception
1527      * @throws Zend_Gdata_App_HttpException
1528      * @throws Zend_Gdata_Gapps_ServiceException
1529      */
1530     public function createEmailList($emailList) {
1531         $entry = $this->newEmailListEntry();
1532         $list = $this->newEmailList();
1533         $list->name = $emailList;
1534         $entry->emailList = $list;
1535         return $this->insertEmailList($entry);
1536     }
1537
1538     /**
1539      * Retrieve all email lists associated with a recipient.
1540      *
1541      * @param string $username The recipient whose associated email lists
1542      *          should be returned.
1543      * @return Zend_Gdata_Gapps_EmailListFeed The list of email lists found as
1544      *          Zend_Gdata_EmailListEntry objects.
1545      * @throws Zend_Gdata_App_Exception
1546      * @throws Zend_Gdata_App_HttpException
1547      * @throws Zend_Gdata_Gapps_ServiceException
1548      */
1549     public function retrieveEmailLists($recipient) {
1550         $query = $this->newEmailListQuery();
1551         $query->recipient = $recipient;
1552         return $this->getEmailListFeed($query);
1553     }
1554
1555     /**
1556      * Retrieve a page of email lists in alphabetical order, starting with the
1557      * provided email list.
1558      *
1559      * @param string $startEmailListName (optional) The first list to
1560      *              retrieve. If null or not defined, the page will begin
1561      *              with the first email list in the domain.
1562      * @return Zend_Gdata_Gapps_EmailListFeed Collection of Zend_Gdata_EmailListEntry
1563      *              objects representing all nicknames in the domain.
1564      * @throws Zend_Gdata_App_Exception
1565      * @throws Zend_Gdata_App_HttpException
1566      * @throws Zend_Gdata_Gapps_ServiceException
1567      */
1568     public function retrievePageOfEmailLists ($startNickname = null) {
1569         $query = $this->newEmailListQuery();
1570         $query->setStartEmailListName($startNickname);
1571         return $this->getEmailListFeed($query);
1572     }
1573
1574     /**
1575      * Retrieve all email lists associated with the curent domain. Be aware that
1576      * calling this function on a domain with many email lists will take a
1577      * signifigant amount of time to complete. On larger domains this may
1578      * may cause execution to timeout without proper precautions in place.
1579      *
1580      * @return Zend_Gdata_Gapps_EmailListFeed The list of email lists found
1581      *              as Zend_Gdata_Gapps_EmailListEntry objects.
1582      * @throws Zend_Gdata_App_Exception
1583      * @throws Zend_Gdata_App_HttpException
1584      * @throws Zend_Gdata_Gapps_ServiceException
1585      */
1586     public function retrieveAllEmailLists() {
1587         return $this->retrieveAllEntriesForFeed($this->retrievePageOfEmailLists());
1588     }
1589
1590     /**
1591      * Delete a specified email list.
1592      *
1593      * @param string $emailList The name of the emailList to be deleted.
1594      * @throws Zend_Gdata_App_Exception
1595      * @throws Zend_Gdata_App_HttpException
1596      * @throws Zend_Gdata_Gapps_ServiceException
1597      */
1598     public function deleteEmailList($emailList) {
1599         $this->delete($this->getBaseUrl() . self::APPS_EMAIL_LIST_PATH . '/'
1600             . $emailList);
1601     }
1602
1603     /**
1604      * Add a specified recipient to an existing emailList.
1605      *
1606      * @param string $recipientAddress The address of the recipient to be
1607      *              added to the email list.
1608      * @param string $emailList The name of the email address to which the
1609      *              recipient should be added.
1610      * @return Zend_Gdata_Gapps_EmailListRecipientEntry The recipient entry
1611      *              created by the server.
1612      * @throws Zend_Gdata_App_Exception
1613      * @throws Zend_Gdata_App_HttpException
1614      * @throws Zend_Gdata_Gapps_ServiceException
1615      */
1616     public function addRecipientToEmailList($recipientAddress, $emailList) {
1617         $entry = $this->newEmailListRecipientEntry();
1618         $who = $this->newWho();
1619         $who->email = $recipientAddress;
1620         $entry->who = $who;
1621         $address = $this->getBaseUrl() .  self::APPS_EMAIL_LIST_PATH . '/' .
1622             $emailList . self::APPS_EMAIL_LIST_RECIPIENT_POSTFIX . '/';
1623         return $this->insertEmailListRecipient($entry, $address);
1624     }
1625
1626     /**
1627      * Retrieve a page of email list recipients in alphabetical order,
1628      * starting with the provided email list recipient.
1629      *
1630      * @param string $emaiList The email list which should be searched.
1631      * @param string $startRecipient (optinal) The address of the first
1632      *              recipient, or null to start with the first recipient in
1633      *              the list.
1634      * @return Zend_Gdata_Gapps_EmailListRecipientFeed Collection of
1635      *              Zend_Gdata_EmailListRecipientEntry objects representing all
1636      *              recpients in the specified list.
1637      * @throws Zend_Gdata_App_Exception
1638      * @throws Zend_Gdata_App_HttpException
1639      * @throws Zend_Gdata_Gapps_ServiceException
1640      */
1641     public function retrievePageOfRecipients ($emailList,
1642             $startRecipient = null) {
1643         $query = $this->newEmailListRecipientQuery();
1644         $query->setEmailListName($emailList);
1645         $query->setStartRecipient($startRecipient);
1646         return $this->getEmailListRecipientFeed($query);
1647     }
1648
1649     /**
1650      * Retrieve all recipients associated with an email list. Be aware that
1651      * calling this function on a domain with many email lists will take a
1652      * signifigant amount of time to complete. On larger domains this may
1653      * may cause execution to timeout without proper precautions in place.
1654      *
1655      * @param string $emaiList The email list which should be searched.
1656      * @return Zend_Gdata_Gapps_EmailListRecipientFeed The list of email lists
1657      *              found as Zend_Gdata_Gapps_EmailListRecipientEntry objects.
1658      * @throws Zend_Gdata_App_Exception
1659      * @throws Zend_Gdata_App_HttpException
1660      * @throws Zend_Gdata_Gapps_ServiceException
1661      */
1662     public function retrieveAllRecipients($emailList) {
1663         return $this->retrieveAllEntriesForFeed(
1664                 $this->retrievePageOfRecipients($emailList));
1665     }
1666
1667     /**
1668      * Remove a specified recipient from an email list.
1669      *
1670      * @param string $recipientAddress The recipient to be removed.
1671      * @param string $emailList The list from which the recipient should
1672      *              be removed.
1673      * @throws Zend_Gdata_App_Exception
1674      * @throws Zend_Gdata_App_HttpException
1675      * @throws Zend_Gdata_Gapps_ServiceException
1676      */
1677     public function removeRecipientFromEmailList($recipientAddress, $emailList) {
1678         $this->delete($this->getBaseUrl() . self::APPS_EMAIL_LIST_PATH . '/'
1679             . $emailList . self::APPS_EMAIL_LIST_RECIPIENT_POSTFIX . '/'
1680             . $recipientAddress);
1681     }
1682
1683 }