web/Zend/Service/Flickr.php
changeset 0 4eba9c11703f
equal deleted inserted replaced
-1:000000000000 0:4eba9c11703f
       
     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_Service
       
    18  * @subpackage Flickr
       
    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  * @version    $Id: Flickr.php 22598 2010-07-16 21:24:14Z mikaelkael $
       
    22  */
       
    23 
       
    24 
       
    25 /**
       
    26  * @category   Zend
       
    27  * @package    Zend_Service
       
    28  * @subpackage Flickr
       
    29  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    30  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    31  */
       
    32 class Zend_Service_Flickr
       
    33 {
       
    34     /**
       
    35      * Base URI for the REST client
       
    36      */
       
    37     const URI_BASE = 'http://www.flickr.com';
       
    38 
       
    39     /**
       
    40      * Your Flickr API key
       
    41      *
       
    42      * @var string
       
    43      */
       
    44     public $apiKey;
       
    45 
       
    46     /**
       
    47      * Reference to REST client object
       
    48      *
       
    49      * @var Zend_Rest_Client
       
    50      */
       
    51     protected $_restClient = null;
       
    52 
       
    53 
       
    54     /**
       
    55      * Performs object initializations
       
    56      *
       
    57      *  # Sets up character encoding
       
    58      *  # Saves the API key
       
    59      *
       
    60      * @param  string $apiKey Your Flickr API key
       
    61      * @return void
       
    62      */
       
    63     public function __construct($apiKey)
       
    64     {
       
    65         $this->apiKey = (string) $apiKey;
       
    66     }
       
    67 
       
    68 
       
    69     /**
       
    70      * Find Flickr photos by tag.
       
    71      *
       
    72      * Query options include:
       
    73      *
       
    74      *  # per_page:        how many results to return per query
       
    75      *  # page:            the starting page offset.  first result will be (page - 1) * per_page + 1
       
    76      *  # tag_mode:        Either 'any' for an OR combination of tags,
       
    77      *                     or 'all' for an AND combination. Default is 'any'.
       
    78      *  # min_upload_date: Minimum upload date to search on.  Date should be a unix timestamp.
       
    79      *  # max_upload_date: Maximum upload date to search on.  Date should be a unix timestamp.
       
    80      *  # min_taken_date:  Minimum upload date to search on.  Date should be a MySQL datetime.
       
    81      *  # max_taken_date:  Maximum upload date to search on.  Date should be a MySQL datetime.
       
    82      *
       
    83      * @param  string|array $query   A single tag or an array of tags.
       
    84      * @param  array        $options Additional parameters to refine your query.
       
    85      * @return Zend_Service_Flickr_ResultSet
       
    86      * @throws Zend_Service_Exception
       
    87      */
       
    88     public function tagSearch($query, array $options = array())
       
    89     {
       
    90         static $method = 'flickr.photos.search';
       
    91         static $defaultOptions = array('per_page' => 10,
       
    92                                        'page'     => 1,
       
    93                                        'tag_mode' => 'or',
       
    94                                        'extras'   => 'license, date_upload, date_taken, owner_name, icon_server');
       
    95 
       
    96         $options['tags'] = is_array($query) ? implode(',', $query) : $query;
       
    97 
       
    98         $options = $this->_prepareOptions($method, $options, $defaultOptions);
       
    99 
       
   100         $this->_validateTagSearch($options);
       
   101 
       
   102         // now search for photos
       
   103         $restClient = $this->getRestClient();
       
   104         $restClient->getHttpClient()->resetParameters();
       
   105         $response = $restClient->restGet('/services/rest/', $options);
       
   106 
       
   107         if ($response->isError()) {
       
   108             /**
       
   109              * @see Zend_Service_Exception
       
   110              */
       
   111             require_once 'Zend/Service/Exception.php';
       
   112             throw new Zend_Service_Exception('An error occurred sending request. Status code: '
       
   113                                            . $response->getStatus());
       
   114         }
       
   115 
       
   116         $dom = new DOMDocument();
       
   117         $dom->loadXML($response->getBody());
       
   118 
       
   119         self::_checkErrors($dom);
       
   120 
       
   121         /**
       
   122          * @see Zend_Service_Flickr_ResultSet
       
   123          */
       
   124         require_once 'Zend/Service/Flickr/ResultSet.php';
       
   125         return new Zend_Service_Flickr_ResultSet($dom, $this);
       
   126     }
       
   127 
       
   128 
       
   129     /**
       
   130      * Finds photos by a user's username or email.
       
   131      *
       
   132      * Additional query options include:
       
   133      *
       
   134      *  # per_page:        how many results to return per query
       
   135      *  # page:            the starting page offset.  first result will be (page - 1) * per_page + 1
       
   136      *  # min_upload_date: Minimum upload date to search on.  Date should be a unix timestamp.
       
   137      *  # max_upload_date: Maximum upload date to search on.  Date should be a unix timestamp.
       
   138      *  # min_taken_date:  Minimum upload date to search on.  Date should be a MySQL datetime.
       
   139      *  # max_taken_date:  Maximum upload date to search on.  Date should be a MySQL datetime.
       
   140      *
       
   141      * @param  string $query   username or email
       
   142      * @param  array  $options Additional parameters to refine your query.
       
   143      * @return Zend_Service_Flickr_ResultSet
       
   144      * @throws Zend_Service_Exception
       
   145      */
       
   146     public function userSearch($query, array $options = null)
       
   147     {
       
   148         static $method = 'flickr.people.getPublicPhotos';
       
   149         static $defaultOptions = array('per_page' => 10,
       
   150                                        'page'     => 1,
       
   151                                        'extras'   => 'license, date_upload, date_taken, owner_name, icon_server');
       
   152 
       
   153 
       
   154         // can't access by username, must get ID first
       
   155         if (strchr($query, '@')) {
       
   156             // optimistically hope this is an email
       
   157             $options['user_id'] = $this->getIdByEmail($query);
       
   158         } else {
       
   159             // we can safely ignore this exception here
       
   160             $options['user_id'] = $this->getIdByUsername($query);
       
   161         }
       
   162 
       
   163         $options = $this->_prepareOptions($method, $options, $defaultOptions);
       
   164         $this->_validateUserSearch($options);
       
   165 
       
   166         // now search for photos
       
   167         $restClient = $this->getRestClient();
       
   168         $restClient->getHttpClient()->resetParameters();
       
   169         $response = $restClient->restGet('/services/rest/', $options);
       
   170 
       
   171         if ($response->isError()) {
       
   172             /**
       
   173              * @see Zend_Service_Exception
       
   174              */
       
   175             require_once 'Zend/Service/Exception.php';
       
   176             throw new Zend_Service_Exception('An error occurred sending request. Status code: '
       
   177                                            . $response->getStatus());
       
   178         }
       
   179 
       
   180         $dom = new DOMDocument();
       
   181         $dom->loadXML($response->getBody());
       
   182 
       
   183         self::_checkErrors($dom);
       
   184 
       
   185         /**
       
   186          * @see Zend_Service_Flickr_ResultSet
       
   187          */
       
   188         require_once 'Zend/Service/Flickr/ResultSet.php';
       
   189         return new Zend_Service_Flickr_ResultSet($dom, $this);
       
   190     }
       
   191 
       
   192     /**
       
   193      * Finds photos in a group's pool.
       
   194      *
       
   195      * @param  string $query   group id
       
   196      * @param  array  $options Additional parameters to refine your query.
       
   197      * @return Zend_Service_Flickr_ResultSet
       
   198      * @throws Zend_Service_Exception
       
   199      */
       
   200     public function groupPoolGetPhotos($query, array $options = array())
       
   201     {
       
   202         static $method = 'flickr.groups.pools.getPhotos';
       
   203         static $defaultOptions = array('per_page' => 10,
       
   204                                        'page'     => 1,
       
   205                                        'extras'   => 'license, date_upload, date_taken, owner_name, icon_server');
       
   206 
       
   207         if (empty($query) || !is_string($query)) {
       
   208             /**
       
   209              * @see Zend_Service_Exception
       
   210              */
       
   211             require_once 'Zend/Service/Exception.php';
       
   212             throw new Zend_Service_Exception('You must supply a group id');
       
   213         }
       
   214 
       
   215         $options['group_id'] = $query;
       
   216 
       
   217         $options = $this->_prepareOptions($method, $options, $defaultOptions);
       
   218 
       
   219         $this->_validateGroupPoolGetPhotos($options);
       
   220 
       
   221         // now search for photos
       
   222         $restClient = $this->getRestClient();
       
   223         $restClient->getHttpClient()->resetParameters();
       
   224         $response = $restClient->restGet('/services/rest/', $options);
       
   225 
       
   226         if ($response->isError()) {
       
   227             /**
       
   228             * @see Zend_Service_Exception
       
   229             */
       
   230             require_once 'Zend/Service/Exception.php';
       
   231             throw new Zend_Service_Exception('An error occurred sending request. Status code: '
       
   232                                            . $response->getStatus());
       
   233         }
       
   234 
       
   235         $dom = new DOMDocument();
       
   236         $dom->loadXML($response->getBody());
       
   237 
       
   238         self::_checkErrors($dom);
       
   239 
       
   240         /**
       
   241         * @see Zend_Service_Flickr_ResultSet
       
   242         */
       
   243         require_once 'Zend/Service/Flickr/ResultSet.php';
       
   244         return new Zend_Service_Flickr_ResultSet($dom, $this);
       
   245     }
       
   246 
       
   247 
       
   248 
       
   249     /**
       
   250      * Utility function to find Flickr User IDs for usernames.
       
   251      *
       
   252      * (You can only find a user's photo with their NSID.)
       
   253      *
       
   254      * @param  string $username the username
       
   255      * @return string the NSID (userid)
       
   256      * @throws Zend_Service_Exception
       
   257      */
       
   258     public function getIdByUsername($username)
       
   259     {
       
   260         static $method = 'flickr.people.findByUsername';
       
   261 
       
   262         $options = array('api_key' => $this->apiKey, 'method' => $method, 'username' => (string) $username);
       
   263 
       
   264         if (empty($username)) {
       
   265             /**
       
   266              * @see Zend_Service_Exception
       
   267              */
       
   268             require_once 'Zend/Service/Exception.php';
       
   269             throw new Zend_Service_Exception('You must supply a username');
       
   270         }
       
   271 
       
   272         $restClient = $this->getRestClient();
       
   273         $restClient->getHttpClient()->resetParameters();
       
   274         $response = $restClient->restGet('/services/rest/', $options);
       
   275 
       
   276         if ($response->isError()) {
       
   277             /**
       
   278              * @see Zend_Service_Exception
       
   279              */
       
   280             require_once 'Zend/Service/Exception.php';
       
   281             throw new Zend_Service_Exception('An error occurred sending request. Status code: '
       
   282                                            . $response->getStatus());
       
   283         }
       
   284 
       
   285         $dom = new DOMDocument();
       
   286         $dom->loadXML($response->getBody());
       
   287         self::_checkErrors($dom);
       
   288         $xpath = new DOMXPath($dom);
       
   289         return (string) $xpath->query('//user')->item(0)->getAttribute('id');
       
   290     }
       
   291 
       
   292 
       
   293     /**
       
   294      * Utility function to find Flickr User IDs for emails.
       
   295      *
       
   296      * (You can only find a user's photo with their NSID.)
       
   297      *
       
   298      * @param  string $email the email
       
   299      * @return string the NSID (userid)
       
   300      * @throws Zend_Service_Exception
       
   301      */
       
   302     public function getIdByEmail($email)
       
   303     {
       
   304         static $method = 'flickr.people.findByEmail';
       
   305 
       
   306         if (empty($email)) {
       
   307             /**
       
   308              * @see Zend_Service_Exception
       
   309              */
       
   310             require_once 'Zend/Service/Exception.php';
       
   311             throw new Zend_Service_Exception('You must supply an e-mail address');
       
   312         }
       
   313 
       
   314         $options = array('api_key' => $this->apiKey, 'method' => $method, 'find_email' => (string) $email);
       
   315 
       
   316         $restClient = $this->getRestClient();
       
   317         $restClient->getHttpClient()->resetParameters();
       
   318         $response = $restClient->restGet('/services/rest/', $options);
       
   319 
       
   320         if ($response->isError()) {
       
   321             /**
       
   322              * @see Zend_Service_Exception
       
   323              */
       
   324             require_once 'Zend/Service/Exception.php';
       
   325             throw new Zend_Service_Exception('An error occurred sending request. Status code: '
       
   326                                            . $response->getStatus());
       
   327         }
       
   328 
       
   329         $dom = new DOMDocument();
       
   330         $dom->loadXML($response->getBody());
       
   331         self::_checkErrors($dom);
       
   332         $xpath = new DOMXPath($dom);
       
   333         return (string) $xpath->query('//user')->item(0)->getAttribute('id');
       
   334     }
       
   335 
       
   336 
       
   337     /**
       
   338      * Returns Flickr photo details by for the given photo ID
       
   339      *
       
   340      * @param  string $id the NSID
       
   341      * @return array of Zend_Service_Flickr_Image, details for the specified image
       
   342      * @throws Zend_Service_Exception
       
   343      */
       
   344     public function getImageDetails($id)
       
   345     {
       
   346         static $method = 'flickr.photos.getSizes';
       
   347 
       
   348         if (empty($id)) {
       
   349             /**
       
   350              * @see Zend_Service_Exception
       
   351              */
       
   352             require_once 'Zend/Service/Exception.php';
       
   353             throw new Zend_Service_Exception('You must supply a photo ID');
       
   354         }
       
   355 
       
   356         $options = array('api_key' => $this->apiKey, 'method' => $method, 'photo_id' => $id);
       
   357 
       
   358         $restClient = $this->getRestClient();
       
   359         $restClient->getHttpClient()->resetParameters();
       
   360         $response = $restClient->restGet('/services/rest/', $options);
       
   361 
       
   362         $dom = new DOMDocument();
       
   363         $dom->loadXML($response->getBody());
       
   364         $xpath = new DOMXPath($dom);
       
   365         self::_checkErrors($dom);
       
   366         $retval = array();
       
   367         /**
       
   368          * @see Zend_Service_Flickr_Image
       
   369          */
       
   370         require_once 'Zend/Service/Flickr/Image.php';
       
   371         foreach ($xpath->query('//size') as $size) {
       
   372             $label = (string) $size->getAttribute('label');
       
   373             $retval[$label] = new Zend_Service_Flickr_Image($size);
       
   374         }
       
   375 
       
   376         return $retval;
       
   377     }
       
   378 
       
   379 
       
   380     /**
       
   381      * Returns a reference to the REST client, instantiating it if necessary
       
   382      *
       
   383      * @return Zend_Rest_Client
       
   384      */
       
   385     public function getRestClient()
       
   386     {
       
   387         if (null === $this->_restClient) {
       
   388             /**
       
   389              * @see Zend_Rest_Client
       
   390              */
       
   391             require_once 'Zend/Rest/Client.php';
       
   392             $this->_restClient = new Zend_Rest_Client(self::URI_BASE);
       
   393         }
       
   394 
       
   395         return $this->_restClient;
       
   396     }
       
   397 
       
   398 
       
   399     /**
       
   400      * Validate User Search Options
       
   401      *
       
   402      * @param  array $options
       
   403      * @return void
       
   404      * @throws Zend_Service_Exception
       
   405      */
       
   406     protected function _validateUserSearch(array $options)
       
   407     {
       
   408         $validOptions = array('api_key', 'method', 'user_id', 'per_page', 'page', 'extras', 'min_upload_date',
       
   409                               'min_taken_date', 'max_upload_date', 'max_taken_date', 'safe_search');
       
   410 
       
   411         $this->_compareOptions($options, $validOptions);
       
   412 
       
   413         /**
       
   414          * @see Zend_Validate_Between
       
   415          */
       
   416         require_once 'Zend/Validate/Between.php';
       
   417         $between = new Zend_Validate_Between(1, 500, true);
       
   418         if (!$between->isValid($options['per_page'])) {
       
   419             /**
       
   420              * @see Zend_Service_Exception
       
   421              */
       
   422             require_once 'Zend/Service/Exception.php';
       
   423             throw new Zend_Service_Exception($options['per_page'] . ' is not valid for the "per_page" option');
       
   424         }
       
   425 
       
   426         /**
       
   427          * @see Zend_Validate_Int
       
   428          */
       
   429         require_once 'Zend/Validate/Int.php';
       
   430         $int = new Zend_Validate_Int();
       
   431         if (!$int->isValid($options['page'])) {
       
   432             /**
       
   433              * @see Zend_Service_Exception
       
   434              */
       
   435             require_once 'Zend/Service/Exception.php';
       
   436             throw new Zend_Service_Exception($options['page'] . ' is not valid for the "page" option');
       
   437         }
       
   438 
       
   439         // validate extras, which are delivered in csv format
       
   440         if ($options['extras']) {
       
   441             $extras = explode(',', $options['extras']);
       
   442             $validExtras = array('license', 'date_upload', 'date_taken', 'owner_name', 'icon_server');
       
   443             foreach($extras as $extra) {
       
   444                 /**
       
   445                  * @todo The following does not do anything [yet], so it is commented out.
       
   446                  */
       
   447                 //in_array(trim($extra), $validExtras);
       
   448             }
       
   449         }
       
   450     }
       
   451 
       
   452 
       
   453     /**
       
   454      * Validate Tag Search Options
       
   455      *
       
   456      * @param  array $options
       
   457      * @return void
       
   458      * @throws Zend_Service_Exception
       
   459      */
       
   460     protected function _validateTagSearch(array $options)
       
   461     {
       
   462         $validOptions = array('method', 'api_key', 'user_id', 'tags', 'tag_mode', 'text', 'min_upload_date',
       
   463                               'max_upload_date', 'min_taken_date', 'max_taken_date', 'license', 'sort',
       
   464                               'privacy_filter', 'bbox', 'accuracy', 'safe_search', 'content_type', 'machine_tags',
       
   465                               'machine_tag_mode', 'group_id', 'contacts', 'woe_id', 'place_id', 'media', 'has_geo',
       
   466                               'geo_context', 'lat', 'lon', 'radius', 'radius_units', 'is_commons', 'is_gallery',
       
   467                               'extras', 'per_page', 'page');
       
   468 
       
   469         $this->_compareOptions($options, $validOptions);
       
   470 
       
   471         /**
       
   472          * @see Zend_Validate_Between
       
   473          */
       
   474         require_once 'Zend/Validate/Between.php';
       
   475         $between = new Zend_Validate_Between(1, 500, true);
       
   476         if (!$between->isValid($options['per_page'])) {
       
   477             /**
       
   478              * @see Zend_Service_Exception
       
   479              */
       
   480             require_once 'Zend/Service/Exception.php';
       
   481             throw new Zend_Service_Exception($options['per_page'] . ' is not valid for the "per_page" option');
       
   482         }
       
   483 
       
   484         /**
       
   485          * @see Zend_Validate_Int
       
   486          */
       
   487         require_once 'Zend/Validate/Int.php';
       
   488         $int = new Zend_Validate_Int();
       
   489         if (!$int->isValid($options['page'])) {
       
   490             /**
       
   491              * @see Zend_Service_Exception
       
   492              */
       
   493             require_once 'Zend/Service/Exception.php';
       
   494             throw new Zend_Service_Exception($options['page'] . ' is not valid for the "page" option');
       
   495         }
       
   496 
       
   497         // validate extras, which are delivered in csv format
       
   498         if ($options['extras']) {
       
   499             $extras = explode(',', $options['extras']);
       
   500             $validExtras = array('license', 'date_upload', 'date_taken', 'owner_name', 'icon_server');
       
   501             foreach($extras as $extra) {
       
   502                 /**
       
   503                  * @todo The following does not do anything [yet], so it is commented out.
       
   504                  */
       
   505                 //in_array(trim($extra), $validExtras);
       
   506             }
       
   507         }
       
   508 
       
   509     }
       
   510 
       
   511 
       
   512     /**
       
   513     * Validate Group Search Options
       
   514     *
       
   515     * @param  array $options
       
   516     * @throws Zend_Service_Exception
       
   517     * @return void
       
   518     */
       
   519     protected function _validateGroupPoolGetPhotos(array $options)
       
   520     {
       
   521         $validOptions = array('api_key', 'tags', 'method', 'group_id', 'per_page', 'page', 'extras', 'user_id');
       
   522 
       
   523         $this->_compareOptions($options, $validOptions);
       
   524 
       
   525         /**
       
   526         * @see Zend_Validate_Between
       
   527         */
       
   528         require_once 'Zend/Validate/Between.php';
       
   529         $between = new Zend_Validate_Between(1, 500, true);
       
   530         if (!$between->isValid($options['per_page'])) {
       
   531             /**
       
   532             * @see Zend_Service_Exception
       
   533             */
       
   534             require_once 'Zend/Service/Exception.php';
       
   535             throw new Zend_Service_Exception($options['per_page'] . ' is not valid for the "per_page" option');
       
   536         }
       
   537 
       
   538         /**
       
   539         * @see Zend_Validate_Int
       
   540         */
       
   541         require_once 'Zend/Validate/Int.php';
       
   542         $int = new Zend_Validate_Int();
       
   543 
       
   544         if (!$int->isValid($options['page'])) {
       
   545             /**
       
   546             * @see Zend_Service_Exception
       
   547             */
       
   548             require_once 'Zend/Service/Exception.php';
       
   549             throw new Zend_Service_Exception($options['page'] . ' is not valid for the "page" option');
       
   550         }
       
   551 
       
   552         // validate extras, which are delivered in csv format
       
   553         if (isset($options['extras'])) {
       
   554             $extras = explode(',', $options['extras']);
       
   555             $validExtras = array('license', 'date_upload', 'date_taken', 'owner_name', 'icon_server');
       
   556             foreach($extras as $extra) {
       
   557                 /**
       
   558                 * @todo The following does not do anything [yet], so it is commented out.
       
   559                 */
       
   560                 //in_array(trim($extra), $validExtras);
       
   561             }
       
   562         }
       
   563     }
       
   564 
       
   565 
       
   566     /**
       
   567      * Throws an exception if and only if the response status indicates a failure
       
   568      *
       
   569      * @param  DOMDocument $dom
       
   570      * @return void
       
   571      * @throws Zend_Service_Exception
       
   572      */
       
   573     protected static function _checkErrors(DOMDocument $dom)
       
   574     {
       
   575         if ($dom->documentElement->getAttribute('stat') === 'fail') {
       
   576             $xpath = new DOMXPath($dom);
       
   577             $err = $xpath->query('//err')->item(0);
       
   578             /**
       
   579              * @see Zend_Service_Exception
       
   580              */
       
   581             require_once 'Zend/Service/Exception.php';
       
   582             throw new Zend_Service_Exception('Search failed due to error: ' . $err->getAttribute('msg')
       
   583                                            . ' (error #' . $err->getAttribute('code') . ')');
       
   584         }
       
   585     }
       
   586 
       
   587 
       
   588     /**
       
   589      * Prepare options for the request
       
   590      *
       
   591      * @param  string $method         Flickr Method to call
       
   592      * @param  array  $options        User Options
       
   593      * @param  array  $defaultOptions Default Options
       
   594      * @return array Merged array of user and default/required options
       
   595      */
       
   596     protected function _prepareOptions($method, array $options, array $defaultOptions)
       
   597     {
       
   598         $options['method']  = (string) $method;
       
   599         $options['api_key'] = $this->apiKey;
       
   600 
       
   601         return array_merge($defaultOptions, $options);
       
   602     }
       
   603 
       
   604 
       
   605     /**
       
   606      * Throws an exception if and only if any user options are invalid
       
   607      *
       
   608      * @param  array $options      User options
       
   609      * @param  array $validOptions Valid options
       
   610      * @return void
       
   611      * @throws Zend_Service_Exception
       
   612      */
       
   613     protected function _compareOptions(array $options, array $validOptions)
       
   614     {
       
   615         $difference = array_diff(array_keys($options), $validOptions);
       
   616         if ($difference) {
       
   617             /**
       
   618              * @see Zend_Service_Exception
       
   619              */
       
   620             require_once 'Zend/Service/Exception.php';
       
   621             throw new Zend_Service_Exception('The following parameters are invalid: ' . implode(',', $difference));
       
   622         }
       
   623     }
       
   624 }
       
   625