web/lib/Zend/Service/Technorati.php
changeset 64 162c1de6545a
parent 19 1c2f13fd785c
child 68 ecaf28ffe26e
equal deleted inserted replaced
63:5b37998e522e 64:162c1de6545a
       
     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 Technorati
       
    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: Technorati.php 20096 2010-01-06 02:05:09Z bkarwin $
       
    22  */
       
    23 
       
    24 
       
    25 /**
       
    26  * Zend_Service_Technorati provides an easy, intuitive and object-oriented interface
       
    27  * for using the Technorati API.
       
    28  *
       
    29  * It provides access to all available Technorati API queries
       
    30  * and returns the original XML response as a friendly PHP object.
       
    31  *
       
    32  * @category   Zend
       
    33  * @package    Zend_Service
       
    34  * @subpackage Technorati
       
    35  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    36  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    37  */
       
    38 class Zend_Service_Technorati
       
    39 {
       
    40     /** Base Technorati API URI */
       
    41     const API_URI_BASE = 'http://api.technorati.com';
       
    42 
       
    43     /** Query paths */
       
    44     const API_PATH_COSMOS           = '/cosmos';
       
    45     const API_PATH_SEARCH           = '/search';
       
    46     const API_PATH_TAG              = '/tag';
       
    47     const API_PATH_DAILYCOUNTS      = '/dailycounts';
       
    48     const API_PATH_TOPTAGS          = '/toptags';
       
    49     const API_PATH_BLOGINFO         = '/bloginfo';
       
    50     const API_PATH_BLOGPOSTTAGS     = '/blogposttags';
       
    51     const API_PATH_GETINFO          = '/getinfo';
       
    52     const API_PATH_KEYINFO          = '/keyinfo';
       
    53 
       
    54     /** Prevent magic numbers */
       
    55     const PARAM_LIMIT_MIN_VALUE = 1;
       
    56     const PARAM_LIMIT_MAX_VALUE = 100;
       
    57     const PARAM_DAYS_MIN_VALUE  = 1;
       
    58     const PARAM_DAYS_MAX_VALUE  = 180;
       
    59     const PARAM_START_MIN_VALUE = 1;
       
    60 
       
    61 
       
    62     /**
       
    63      * Technorati API key
       
    64      *
       
    65      * @var     string
       
    66      * @access  protected
       
    67      */
       
    68     protected $_apiKey;
       
    69 
       
    70     /**
       
    71      * Zend_Rest_Client instance
       
    72      *
       
    73      * @var     Zend_Rest_Client
       
    74      * @access  protected
       
    75      */
       
    76     protected $_restClient;
       
    77 
       
    78 
       
    79     /**
       
    80      * Constructs a new Zend_Service_Technorati instance
       
    81      * and setup character encoding.
       
    82      *
       
    83      * @param  string $apiKey  Your Technorati API key
       
    84      */
       
    85     public function __construct($apiKey)
       
    86     {
       
    87         iconv_set_encoding('output_encoding', 'UTF-8');
       
    88         iconv_set_encoding('input_encoding', 'UTF-8');
       
    89         iconv_set_encoding('internal_encoding', 'UTF-8');
       
    90 
       
    91         $this->_apiKey = $apiKey;
       
    92     }
       
    93 
       
    94 
       
    95     /**
       
    96      * Cosmos query lets you see what blogs are linking to a given URL.
       
    97      *
       
    98      * On the Technorati site, you can enter a URL in the searchbox and
       
    99      * it will return a list of blogs linking to it.
       
   100      * The API version allows more features and gives you a way
       
   101      * to use the cosmos on your own site.
       
   102      *
       
   103      * Query options include:
       
   104      *
       
   105      * 'type'       => (link|weblog)
       
   106      *      optional - A value of link returns the freshest links referencing your target URL.
       
   107      *      A value of weblog returns the last set of unique weblogs referencing your target URL.
       
   108      * 'limit'      => (int)
       
   109      *      optional - adjust the size of your result from the default value of 20
       
   110      *      to between 1 and 100 results.
       
   111      * 'start'      => (int)
       
   112      *      optional - adjust the range of your result set.
       
   113      *      Set this number to larger than zero and you will receive
       
   114      *      the portion of Technorati's total result set ranging from start to start+limit.
       
   115      *      The default start value is 1.
       
   116      * 'current'    => (true|false)
       
   117      *      optional - the default setting of true
       
   118      *      Technorati returns links that are currently on a weblog's homepage.
       
   119      *      Set this parameter to false if you would like to receive all links
       
   120      *      to the given URL regardless of their current placement on the source blog.
       
   121      *      Internally the value is converted in (yes|no).
       
   122      * 'claim'      => (true|false)
       
   123      *      optional - the default setting of FALSE returns no user information
       
   124      *      about each weblog included in the result set when available.
       
   125      *      Set this parameter to FALSE to include Technorati member data
       
   126      *      in the result set when a weblog in your result set
       
   127      *      has been successfully claimed by a member of Technorati.
       
   128      *      Internally the value is converted in (int).
       
   129      * 'highlight'  => (true|false)
       
   130      *      optional - the default setting of TRUE
       
   131      *      highlights the citation of the given URL within the weblog excerpt.
       
   132      *      Set this parameter to FALSE to apply no special markup to the blog excerpt.
       
   133      *      Internally the value is converted in (int).
       
   134      *
       
   135      * @param   string $url     the URL you are searching for. Prefixes http:// and www. are optional.
       
   136      * @param   array $options  additional parameters to refine your query
       
   137      * @return  Zend_Service_Technorati_CosmosResultSet
       
   138      * @throws  Zend_Service_Technorati_Exception
       
   139      * @link    http://technorati.com/developers/api/cosmos.html Technorati API: Cosmos Query reference
       
   140      */
       
   141     public function cosmos($url, $options = null)
       
   142     {
       
   143         static $defaultOptions = array( 'type'      => 'link',
       
   144                                         'start'     => 1,
       
   145                                         'limit'     => 20,
       
   146                                         'current'   => 'yes',
       
   147                                         'format'    => 'xml',
       
   148                                         'claim'     => 0,
       
   149                                         'highlight' => 1,
       
   150                                         );
       
   151 
       
   152         $options['url'] = $url;
       
   153 
       
   154         $options = $this->_prepareOptions($options, $defaultOptions);
       
   155         $this->_validateCosmos($options);
       
   156         $response = $this->_makeRequest(self::API_PATH_COSMOS, $options);
       
   157         $dom = $this->_convertResponseAndCheckContent($response);
       
   158 
       
   159         /**
       
   160          * @see Zend_Service_Technorati_CosmosResultSet
       
   161          */
       
   162         require_once 'Zend/Service/Technorati/CosmosResultSet.php';
       
   163         return new Zend_Service_Technorati_CosmosResultSet($dom, $options);
       
   164     }
       
   165 
       
   166     /**
       
   167      * Search lets you see what blogs contain a given search string.
       
   168      *
       
   169      * Query options include:
       
   170      *
       
   171      * 'language'   => (string)
       
   172      *      optional - a ISO 639-1 two character language code
       
   173      *      to retrieve results specific to that language.
       
   174      *      This feature is currently beta and may not work for all languages.
       
   175      * 'authority'  => (n|a1|a4|a7)
       
   176      *      optional - filter results to those from blogs with at least
       
   177      *      the Technorati Authority specified.
       
   178      *      Technorati calculates a blog's authority by how many people link to it.
       
   179      *      Filtering by authority is a good way to refine your search results.
       
   180      *      There are four settings:
       
   181      *      - n  => Any authority: All results.
       
   182      *      - a1 => A little authority: Results from blogs with at least one link.
       
   183      *      - a4 => Some authority: Results from blogs with a handful of links.
       
   184      *      - a7 => A lot of authority: Results from blogs with hundreds of links.
       
   185      * 'limit'      => (int)
       
   186      *      optional - adjust the size of your result from the default value of 20
       
   187      *      to between 1 and 100 results.
       
   188      * 'start'      => (int)
       
   189      *      optional - adjust the range of your result set.
       
   190      *      Set this number to larger than zero and you will receive
       
   191      *      the portion of Technorati's total result set ranging from start to start+limit.
       
   192      *      The default start value is 1.
       
   193      * 'claim'      => (true|false)
       
   194      *      optional - the default setting of FALSE returns no user information
       
   195      *      about each weblog included in the result set when available.
       
   196      *      Set this parameter to FALSE to include Technorati member data
       
   197      *      in the result set when a weblog in your result set
       
   198      *      has been successfully claimed by a member of Technorati.
       
   199      *      Internally the value is converted in (int).
       
   200      *
       
   201      * @param   string $query   the words you are searching for.
       
   202      * @param   array $options  additional parameters to refine your query
       
   203      * @return  Zend_Service_Technorati_SearchResultSet
       
   204      * @throws  Zend_Service_Technorati_Exception
       
   205      * @link    http://technorati.com/developers/api/search.html Technorati API: Search Query reference
       
   206      */
       
   207     public function search($query, $options = null)
       
   208     {
       
   209         static $defaultOptions = array( 'start'     => 1,
       
   210                                         'limit'     => 20,
       
   211                                         'format'    => 'xml',
       
   212                                         'claim'     => 0);
       
   213 
       
   214         $options['query'] = $query;
       
   215 
       
   216         $options = $this->_prepareOptions($options, $defaultOptions);
       
   217         $this->_validateSearch($options);
       
   218         $response = $this->_makeRequest(self::API_PATH_SEARCH, $options);
       
   219         $dom = $this->_convertResponseAndCheckContent($response);
       
   220 
       
   221         /**
       
   222          * @see Zend_Service_Technorati_SearchResultSet
       
   223          */
       
   224         require_once 'Zend/Service/Technorati/SearchResultSet.php';
       
   225         return new Zend_Service_Technorati_SearchResultSet($dom, $options);
       
   226     }
       
   227 
       
   228     /**
       
   229      * Tag lets you see what posts are associated with a given tag.
       
   230      *
       
   231      * Query options include:
       
   232      *
       
   233      * 'limit'          => (int)
       
   234      *      optional - adjust the size of your result from the default value of 20
       
   235      *      to between 1 and 100 results.
       
   236      * 'start'          => (int)
       
   237      *      optional - adjust the range of your result set.
       
   238      *      Set this number to larger than zero and you will receive
       
   239      *      the portion of Technorati's total result set ranging from start to start+limit.
       
   240      *      The default start value is 1.
       
   241      * 'excerptsize'    => (int)
       
   242      *      optional - number of word characters to include in the post excerpts.
       
   243      *      By default 100 word characters are returned.
       
   244      * 'topexcerptsize' => (int)
       
   245      *      optional - number of word characters to include in the first post excerpt.
       
   246      *      By default 150 word characters are returned.
       
   247      *
       
   248      * @param   string $tag     the tag term you are searching posts for.
       
   249      * @param   array $options  additional parameters to refine your query
       
   250      * @return  Zend_Service_Technorati_TagResultSet
       
   251      * @throws  Zend_Service_Technorati_Exception
       
   252      *  @link    http://technorati.com/developers/api/tag.html Technorati API: Tag Query reference
       
   253      */
       
   254     public function tag($tag, $options = null)
       
   255     {
       
   256         static $defaultOptions = array( 'start'          => 1,
       
   257                                         'limit'          => 20,
       
   258                                         'format'         => 'xml',
       
   259                                         'excerptsize'    => 100,
       
   260                                         'topexcerptsize' => 150);
       
   261 
       
   262         $options['tag'] = $tag;
       
   263 
       
   264         $options = $this->_prepareOptions($options, $defaultOptions);
       
   265         $this->_validateTag($options);
       
   266         $response = $this->_makeRequest(self::API_PATH_TAG, $options);
       
   267         $dom = $this->_convertResponseAndCheckContent($response);
       
   268 
       
   269         /**
       
   270          * @see Zend_Service_Technorati_TagResultSet
       
   271          */
       
   272         require_once 'Zend/Service/Technorati/TagResultSet.php';
       
   273         return new Zend_Service_Technorati_TagResultSet($dom, $options);
       
   274     }
       
   275 
       
   276     /**
       
   277      * TopTags provides daily counts of posts containing the queried keyword.
       
   278      *
       
   279      * Query options include:
       
   280      *
       
   281      * 'days'       => (int)
       
   282      *      optional - Used to specify the number of days in the past
       
   283      *      to request daily count data for.
       
   284      *      Can be any integer between 1 and 180, default is 180
       
   285      *
       
   286      * @param   string $q       the keyword query
       
   287      * @param   array $options  additional parameters to refine your query
       
   288      * @return  Zend_Service_Technorati_DailyCountsResultSet
       
   289      * @throws  Zend_Service_Technorati_Exception
       
   290      * @link    http://technorati.com/developers/api/dailycounts.html Technorati API: DailyCounts Query reference
       
   291      */
       
   292     public function dailyCounts($query, $options = null)
       
   293     {
       
   294         static $defaultOptions = array( 'days'      => 180,
       
   295                                         'format'    => 'xml'
       
   296                                         );
       
   297 
       
   298         $options['q'] = $query;
       
   299 
       
   300         $options = $this->_prepareOptions($options, $defaultOptions);
       
   301         $this->_validateDailyCounts($options);
       
   302         $response = $this->_makeRequest(self::API_PATH_DAILYCOUNTS, $options);
       
   303         $dom = $this->_convertResponseAndCheckContent($response);
       
   304 
       
   305         /**
       
   306          * @see Zend_Service_Technorati_DailyCountsResultSet
       
   307          */
       
   308         require_once 'Zend/Service/Technorati/DailyCountsResultSet.php';
       
   309         return new Zend_Service_Technorati_DailyCountsResultSet($dom);
       
   310     }
       
   311 
       
   312     /**
       
   313      * TopTags provides information on top tags indexed by Technorati.
       
   314      *
       
   315      * Query options include:
       
   316      *
       
   317      * 'limit'      => (int)
       
   318      *      optional - adjust the size of your result from the default value of 20
       
   319      *      to between 1 and 100 results.
       
   320      * 'start'      => (int)
       
   321      *      optional - adjust the range of your result set.
       
   322      *      Set this number to larger than zero and you will receive
       
   323      *      the portion of Technorati's total result set ranging from start to start+limit.
       
   324      *      The default start value is 1.
       
   325      *
       
   326      * @param   array $options  additional parameters to refine your query
       
   327      * @return  Zend_Service_Technorati_TagsResultSet
       
   328      * @throws  Zend_Service_Technorati_Exception
       
   329      * @link    http://technorati.com/developers/api/toptags.html Technorati API: TopTags Query reference
       
   330      */
       
   331     public function topTags($options = null)
       
   332     {
       
   333         static $defaultOptions = array( 'start'     => 1,
       
   334                                         'limit'     => 20,
       
   335                                         'format'    => 'xml'
       
   336                                         );
       
   337 
       
   338         $options = $this->_prepareOptions($options, $defaultOptions);
       
   339         $this->_validateTopTags($options);
       
   340         $response = $this->_makeRequest(self::API_PATH_TOPTAGS, $options);
       
   341         $dom = $this->_convertResponseAndCheckContent($response);
       
   342 
       
   343         /**
       
   344          * @see Zend_Service_Technorati_TagsResultSet
       
   345          */
       
   346         require_once 'Zend/Service/Technorati/TagsResultSet.php';
       
   347         return new Zend_Service_Technorati_TagsResultSet($dom);
       
   348     }
       
   349 
       
   350     /**
       
   351      * BlogInfo provides information on what blog, if any, is associated with a given URL.
       
   352      *
       
   353      * @param   string $url     the URL you are searching for. Prefixes http:// and www. are optional.
       
   354      *                          The URL must be recognized by Technorati as a blog.
       
   355      * @param   array $options  additional parameters to refine your query
       
   356      * @return  Zend_Service_Technorati_BlogInfoResult
       
   357      * @throws  Zend_Service_Technorati_Exception
       
   358      * @link    http://technorati.com/developers/api/bloginfo.html Technorati API: BlogInfo Query reference
       
   359      */
       
   360     public function blogInfo($url, $options = null)
       
   361     {
       
   362         static $defaultOptions = array( 'format'    => 'xml'
       
   363                                         );
       
   364 
       
   365         $options['url'] = $url;
       
   366 
       
   367         $options = $this->_prepareOptions($options, $defaultOptions);
       
   368         $this->_validateBlogInfo($options);
       
   369         $response = $this->_makeRequest(self::API_PATH_BLOGINFO, $options);
       
   370         $dom = $this->_convertResponseAndCheckContent($response);
       
   371 
       
   372         /**
       
   373          * @see Zend_Service_Technorati_BlogInfoResult
       
   374          */
       
   375         require_once 'Zend/Service/Technorati/BlogInfoResult.php';
       
   376         return new Zend_Service_Technorati_BlogInfoResult($dom);
       
   377     }
       
   378 
       
   379     /**
       
   380      * BlogPostTags provides information on the top tags used by a specific blog.
       
   381      *
       
   382      * Query options include:
       
   383      *
       
   384      * 'limit'      => (int)
       
   385      *      optional - adjust the size of your result from the default value of 20
       
   386      *      to between 1 and 100 results.
       
   387      * 'start'      => (int)
       
   388      *      optional - adjust the range of your result set.
       
   389      *      Set this number to larger than zero and you will receive
       
   390      *      the portion of Technorati's total result set ranging from start to start+limit.
       
   391      *      The default start value is 1.
       
   392      *      Note. This property is not documented.
       
   393      *
       
   394      * @param   string $url     the URL you are searching for. Prefixes http:// and www. are optional.
       
   395      *                          The URL must be recognized by Technorati as a blog.
       
   396      * @param   array $options  additional parameters to refine your query
       
   397      * @return  Zend_Service_Technorati_TagsResultSet
       
   398      * @throws  Zend_Service_Technorati_Exception
       
   399      * @link    http://technorati.com/developers/api/blogposttags.html Technorati API: BlogPostTags Query reference
       
   400      */
       
   401     public function blogPostTags($url, $options = null)
       
   402     {
       
   403         static $defaultOptions = array( 'start'     => 1,
       
   404                                         'limit'     => 20,
       
   405                                         'format'    => 'xml'
       
   406                                         );
       
   407 
       
   408         $options['url'] = $url;
       
   409 
       
   410         $options = $this->_prepareOptions($options, $defaultOptions);
       
   411         $this->_validateBlogPostTags($options);
       
   412         $response = $this->_makeRequest(self::API_PATH_BLOGPOSTTAGS, $options);
       
   413         $dom = $this->_convertResponseAndCheckContent($response);
       
   414 
       
   415         /**
       
   416          * @see Zend_Service_Technorati_TagsResultSet
       
   417          */
       
   418         require_once 'Zend/Service/Technorati/TagsResultSet.php';
       
   419         return new Zend_Service_Technorati_TagsResultSet($dom);
       
   420     }
       
   421 
       
   422     /**
       
   423      * GetInfo query tells you things that Technorati knows about a member.
       
   424      *
       
   425      * The returned info is broken up into two sections:
       
   426      * The first part describes some information that the user wants
       
   427      * to allow people to know about him- or herself.
       
   428      * The second part of the document is a listing of the weblogs
       
   429      * that the user has successfully claimed and the information
       
   430      * that Technorati knows about these weblogs.
       
   431      *
       
   432      * @param   string $username    the Technorati user name you are searching for
       
   433      * @param   array $options      additional parameters to refine your query
       
   434      * @return  Zend_Service_Technorati_GetInfoResult
       
   435      * @throws  Zend_Service_Technorati_Exception
       
   436      * @link    http://technorati.com/developers/api/getinfo.html Technorati API: GetInfo reference
       
   437      */
       
   438     public function getInfo($username, $options = null)
       
   439     {
       
   440         static $defaultOptions = array('format' => 'xml');
       
   441 
       
   442         $options['username'] = $username;
       
   443 
       
   444         $options = $this->_prepareOptions($options, $defaultOptions);
       
   445         $this->_validateGetInfo($options);
       
   446         $response = $this->_makeRequest(self::API_PATH_GETINFO, $options);
       
   447         $dom = $this->_convertResponseAndCheckContent($response);
       
   448 
       
   449         /**
       
   450          * @see Zend_Service_Technorati_GetInfoResult
       
   451          */
       
   452         require_once 'Zend/Service/Technorati/GetInfoResult.php';
       
   453         return new Zend_Service_Technorati_GetInfoResult($dom);
       
   454     }
       
   455 
       
   456     /**
       
   457      * KeyInfo query provides information on daily usage of an API key.
       
   458      * Key Info Queries do not count against a key's daily query limit.
       
   459      *
       
   460      * A day is defined as 00:00-23:59 Pacific time.
       
   461      *
       
   462      * @return  Zend_Service_Technorati_KeyInfoResult
       
   463      * @throws  Zend_Service_Technorati_Exception
       
   464      * @link    http://developers.technorati.com/wiki/KeyInfo Technorati API: Key Info reference
       
   465      */
       
   466     public function keyInfo()
       
   467     {
       
   468         static $defaultOptions = array();
       
   469 
       
   470         $options = $this->_prepareOptions(array(), $defaultOptions);
       
   471         // you don't need to validate this request
       
   472         // because key is the only mandatory element
       
   473         // and it's already set in #_prepareOptions
       
   474         $response = $this->_makeRequest(self::API_PATH_KEYINFO, $options);
       
   475         $dom = $this->_convertResponseAndCheckContent($response);
       
   476 
       
   477         /**
       
   478          * @see Zend_Service_Technorati_KeyInfoResult
       
   479          */
       
   480         require_once 'Zend/Service/Technorati/KeyInfoResult.php';
       
   481         return new Zend_Service_Technorati_KeyInfoResult($dom, $this->_apiKey);
       
   482     }
       
   483 
       
   484 
       
   485     /**
       
   486      * Returns Technorati API key.
       
   487      *
       
   488      * @return string   Technorati API key
       
   489      */
       
   490     public function getApiKey()
       
   491     {
       
   492         return $this->_apiKey;
       
   493     }
       
   494 
       
   495     /**
       
   496      * Returns a reference to the REST client object in use.
       
   497      *
       
   498      * If the reference hasn't being inizialized yet,
       
   499      * then a new Zend_Rest_Client instance is created.
       
   500      *
       
   501      * @return Zend_Rest_Client
       
   502      */
       
   503     public function getRestClient()
       
   504     {
       
   505         if ($this->_restClient === null) {
       
   506             /**
       
   507              * @see Zend_Rest_Client
       
   508              */
       
   509             require_once 'Zend/Rest/Client.php';
       
   510             $this->_restClient = new Zend_Rest_Client(self::API_URI_BASE);
       
   511         }
       
   512 
       
   513         return $this->_restClient;
       
   514     }
       
   515 
       
   516     /**
       
   517      * Sets Technorati API key.
       
   518      *
       
   519      * Be aware that this function doesn't validate the key.
       
   520      * The key is validated as soon as the first API request is sent.
       
   521      * If the key is invalid, the API request method will throw
       
   522      * a Zend_Service_Technorati_Exception exception with Invalid Key message.
       
   523      *
       
   524      * @param   string $key     Technorati API Key
       
   525      * @return  void
       
   526      * @link    http://technorati.com/developers/apikey.html How to get your Technorati API Key
       
   527      */
       
   528     public function setApiKey($key)
       
   529     {
       
   530         $this->_apiKey = $key;
       
   531         return $this;
       
   532     }
       
   533 
       
   534 
       
   535     /**
       
   536      * Validates Cosmos query options.
       
   537      *
       
   538      * @param   array $options
       
   539      * @return  void
       
   540      * @throws  Zend_Service_Technorati_Exception
       
   541      * @access  protected
       
   542      */
       
   543     protected function _validateCosmos(array $options)
       
   544     {
       
   545         static $validOptions = array('key', 'url',
       
   546             'type', 'limit', 'start', 'current', 'claim', 'highlight', 'format');
       
   547 
       
   548         // Validate keys in the $options array
       
   549         $this->_compareOptions($options, $validOptions);
       
   550         // Validate url (required)
       
   551         $this->_validateOptionUrl($options);
       
   552         // Validate limit (optional)
       
   553         $this->_validateOptionLimit($options);
       
   554         // Validate start (optional)
       
   555         $this->_validateOptionStart($options);
       
   556         // Validate format (optional)
       
   557         $this->_validateOptionFormat($options);
       
   558         // Validate type (optional)
       
   559         $this->_validateInArrayOption('type', $options, array('link', 'weblog'));
       
   560         // Validate claim (optional)
       
   561         $this->_validateOptionClaim($options);
       
   562         // Validate highlight (optional)
       
   563         $this->_validateIntegerOption('highlight', $options);
       
   564         // Validate current (optional)
       
   565         if (isset($options['current'])) {
       
   566             $tmp = (int) $options['current'];
       
   567             $options['current'] = $tmp ? 'yes' : 'no';
       
   568         }
       
   569 
       
   570     }
       
   571 
       
   572     /**
       
   573      * Validates Search query options.
       
   574      *
       
   575      * @param   array   $options
       
   576      * @return  void
       
   577      * @throws  Zend_Service_Technorati_Exception
       
   578      * @access  protected
       
   579      */
       
   580     protected function _validateSearch(array $options)
       
   581     {
       
   582         static $validOptions = array('key', 'query',
       
   583             'language', 'authority', 'limit', 'start', 'claim', 'format');
       
   584 
       
   585         // Validate keys in the $options array
       
   586         $this->_compareOptions($options, $validOptions);
       
   587         // Validate query (required)
       
   588         $this->_validateMandatoryOption('query', $options);
       
   589         // Validate authority (optional)
       
   590         $this->_validateInArrayOption('authority', $options, array('n', 'a1', 'a4', 'a7'));
       
   591         // Validate limit (optional)
       
   592         $this->_validateOptionLimit($options);
       
   593         // Validate start (optional)
       
   594         $this->_validateOptionStart($options);
       
   595         // Validate claim (optional)
       
   596         $this->_validateOptionClaim($options);
       
   597         // Validate format (optional)
       
   598         $this->_validateOptionFormat($options);
       
   599     }
       
   600 
       
   601     /**
       
   602      * Validates Tag query options.
       
   603      *
       
   604      * @param   array   $options
       
   605      * @return  void
       
   606      * @throws  Zend_Service_Technorati_Exception
       
   607      * @access  protected
       
   608      */
       
   609     protected function _validateTag(array $options)
       
   610     {
       
   611         static $validOptions = array('key', 'tag',
       
   612             'limit', 'start', 'excerptsize', 'topexcerptsize', 'format');
       
   613 
       
   614         // Validate keys in the $options array
       
   615         $this->_compareOptions($options, $validOptions);
       
   616         // Validate query (required)
       
   617         $this->_validateMandatoryOption('tag', $options);
       
   618         // Validate limit (optional)
       
   619         $this->_validateOptionLimit($options);
       
   620         // Validate start (optional)
       
   621         $this->_validateOptionStart($options);
       
   622         // Validate excerptsize (optional)
       
   623         $this->_validateIntegerOption('excerptsize', $options);
       
   624         // Validate excerptsize (optional)
       
   625         $this->_validateIntegerOption('topexcerptsize', $options);
       
   626         // Validate format (optional)
       
   627         $this->_validateOptionFormat($options);
       
   628     }
       
   629 
       
   630 
       
   631     /**
       
   632      * Validates DailyCounts query options.
       
   633      *
       
   634      * @param   array   $options
       
   635      * @return  void
       
   636      * @throws  Zend_Service_Technorati_Exception
       
   637      * @access  protected
       
   638      */
       
   639     protected function _validateDailyCounts(array $options)
       
   640     {
       
   641         static $validOptions = array('key', 'q',
       
   642             'days', 'format');
       
   643 
       
   644         // Validate keys in the $options array
       
   645         $this->_compareOptions($options, $validOptions);
       
   646         // Validate q (required)
       
   647         $this->_validateMandatoryOption('q', $options);
       
   648         // Validate format (optional)
       
   649         $this->_validateOptionFormat($options);
       
   650         // Validate days (optional)
       
   651         if (isset($options['days'])) {
       
   652             $options['days'] = (int) $options['days'];
       
   653             if ($options['days'] < self::PARAM_DAYS_MIN_VALUE ||
       
   654                 $options['days'] > self::PARAM_DAYS_MAX_VALUE) {
       
   655                 /**
       
   656                  * @see Zend_Service_Technorati_Exception
       
   657                  */
       
   658                 require_once 'Zend/Service/Technorati/Exception.php';
       
   659                 throw new Zend_Service_Technorati_Exception(
       
   660                             "Invalid value '" . $options['days'] . "' for 'days' option");
       
   661             }
       
   662         }
       
   663     }
       
   664 
       
   665     /**
       
   666      * Validates GetInfo query options.
       
   667      *
       
   668      * @param   array   $options
       
   669      * @return  void
       
   670      * @throws  Zend_Service_Technorati_Exception
       
   671      * @access  protected
       
   672      */
       
   673     protected function _validateGetInfo(array $options)
       
   674     {
       
   675         static $validOptions = array('key', 'username',
       
   676             'format');
       
   677 
       
   678         // Validate keys in the $options array
       
   679         $this->_compareOptions($options, $validOptions);
       
   680         // Validate username (required)
       
   681         $this->_validateMandatoryOption('username', $options);
       
   682         // Validate format (optional)
       
   683         $this->_validateOptionFormat($options);
       
   684     }
       
   685 
       
   686     /**
       
   687      * Validates TopTags query options.
       
   688      *
       
   689      * @param   array $options
       
   690      * @return  void
       
   691      * @throws  Zend_Service_Technorati_Exception
       
   692      * @access  protected
       
   693      */
       
   694     protected function _validateTopTags(array $options)
       
   695     {
       
   696         static $validOptions = array('key',
       
   697             'limit', 'start', 'format');
       
   698 
       
   699         // Validate keys in the $options array
       
   700         $this->_compareOptions($options, $validOptions);
       
   701         // Validate limit (optional)
       
   702         $this->_validateOptionLimit($options);
       
   703         // Validate start (optional)
       
   704         $this->_validateOptionStart($options);
       
   705         // Validate format (optional)
       
   706         $this->_validateOptionFormat($options);
       
   707     }
       
   708 
       
   709     /**
       
   710      * Validates BlogInfo query options.
       
   711      *
       
   712      * @param   array   $options
       
   713      * @return  void
       
   714      * @throws  Zend_Service_Technorati_Exception
       
   715      * @access  protected
       
   716      */
       
   717     protected function _validateBlogInfo(array $options)
       
   718     {
       
   719         static $validOptions = array('key', 'url',
       
   720             'format');
       
   721 
       
   722         // Validate keys in the $options array
       
   723         $this->_compareOptions($options, $validOptions);
       
   724         // Validate url (required)
       
   725         $this->_validateOptionUrl($options);
       
   726         // Validate format (optional)
       
   727         $this->_validateOptionFormat($options);
       
   728     }
       
   729 
       
   730     /**
       
   731      * Validates TopTags query options.
       
   732      *
       
   733      * @param   array $options
       
   734      * @return  void
       
   735      * @throws  Zend_Service_Technorati_Exception
       
   736      * @access  protected
       
   737      */
       
   738     protected function _validateBlogPostTags(array $options)
       
   739     {
       
   740         static $validOptions = array('key', 'url',
       
   741             'limit', 'start', 'format');
       
   742 
       
   743         // Validate keys in the $options array
       
   744         $this->_compareOptions($options, $validOptions);
       
   745         // Validate url (required)
       
   746         $this->_validateOptionUrl($options);
       
   747         // Validate limit (optional)
       
   748         $this->_validateOptionLimit($options);
       
   749         // Validate start (optional)
       
   750         $this->_validateOptionStart($options);
       
   751         // Validate format (optional)
       
   752         $this->_validateOptionFormat($options);
       
   753     }
       
   754 
       
   755     /**
       
   756      * Checks whether an option is in a given array.
       
   757      *
       
   758      * @param   string $name    option name
       
   759      * @param   array $options
       
   760      * @param   array $array    array of valid options
       
   761      * @return  void
       
   762      * @throws  Zend_Service_Technorati_Exception
       
   763      * @access  protected
       
   764      */
       
   765     protected function _validateInArrayOption($name, $options, array $array)
       
   766     {
       
   767         if (isset($options[$name]) && !in_array($options[$name], $array)) {
       
   768             /**
       
   769              * @see Zend_Service_Technorati_Exception
       
   770              */
       
   771             require_once 'Zend/Service/Technorati/Exception.php';
       
   772             throw new Zend_Service_Technorati_Exception(
       
   773                         "Invalid value '{$options[$name]}' for '$name' option");
       
   774         }
       
   775     }
       
   776 
       
   777     /**
       
   778      * Checks whether mandatory $name option exists and it's valid.
       
   779      *
       
   780      * @param   array $options
       
   781      * @return  void
       
   782      * @throws  Zend_Service_Technorati_Exception
       
   783      * @access  protected
       
   784      */
       
   785     protected function _validateMandatoryOption($name, $options)
       
   786     {
       
   787         if (!isset($options[$name]) || !trim($options[$name])) {
       
   788             /**
       
   789              * @see Zend_Service_Technorati_Exception
       
   790              */
       
   791             require_once 'Zend/Service/Technorati/Exception.php';
       
   792             throw new Zend_Service_Technorati_Exception(
       
   793                         "Empty value for '$name' option");
       
   794         }
       
   795     }
       
   796 
       
   797     /**
       
   798      * Checks whether $name option is a valid integer and casts it.
       
   799      *
       
   800      * @param   array $options
       
   801      * @return  void
       
   802      * @access  protected
       
   803      */
       
   804     protected function _validateIntegerOption($name, $options)
       
   805     {
       
   806         if (isset($options[$name])) {
       
   807             $options[$name] = (int) $options[$name];
       
   808         }
       
   809     }
       
   810 
       
   811     /**
       
   812      * Makes and HTTP GET request to given $path with $options.
       
   813      * HTTP Response is first validated, then returned.
       
   814      *
       
   815      * @param   string $path
       
   816      * @param   array $options
       
   817      * @return  Zend_Http_Response
       
   818      * @throws  Zend_Service_Technorati_Exception on failure
       
   819      * @access  protected
       
   820      */
       
   821     protected function _makeRequest($path, $options = array())
       
   822     {
       
   823         $restClient = $this->getRestClient();
       
   824         $restClient->getHttpClient()->resetParameters();
       
   825         $response = $restClient->restGet($path, $options);
       
   826         self::_checkResponse($response);
       
   827         return $response;
       
   828     }
       
   829 
       
   830     /**
       
   831      * Checks whether 'claim' option value is valid.
       
   832      *
       
   833      * @param   array $options
       
   834      * @return  void
       
   835      * @access  protected
       
   836      */
       
   837     protected function _validateOptionClaim(array $options)
       
   838     {
       
   839         $this->_validateIntegerOption('claim', $options);
       
   840     }
       
   841 
       
   842     /**
       
   843      * Checks whether 'format' option value is valid.
       
   844      * Be aware that Zend_Service_Technorati supports only XML as format value.
       
   845      *
       
   846      * @param   array $options
       
   847      * @return  void
       
   848      * @throws  Zend_Service_Technorati_Exception if 'format' value != XML
       
   849      * @access  protected
       
   850      */
       
   851     protected function _validateOptionFormat(array $options)
       
   852     {
       
   853         if (isset($options['format']) && $options['format'] != 'xml') {
       
   854             /**
       
   855              * @see Zend_Service_Technorati_Exception
       
   856              */
       
   857             require_once 'Zend/Service/Technorati/Exception.php';
       
   858             throw new Zend_Service_Technorati_Exception(
       
   859                         "Invalid value '" . $options['format'] . "' for 'format' option. " .
       
   860                         "Zend_Service_Technorati supports only 'xml'");
       
   861         }
       
   862     }
       
   863 
       
   864     /**
       
   865      * Checks whether 'limit' option value is valid.
       
   866      * Value must be an integer greater than PARAM_LIMIT_MIN_VALUE
       
   867      * and lower than PARAM_LIMIT_MAX_VALUE.
       
   868      *
       
   869      * @param   array $options
       
   870      * @return  void
       
   871      * @throws  Zend_Service_Technorati_Exception if 'limit' value is invalid
       
   872      * @access  protected
       
   873      */
       
   874     protected function _validateOptionLimit(array $options)
       
   875     {
       
   876         if (!isset($options['limit'])) return;
       
   877 
       
   878         $options['limit'] = (int) $options['limit'];
       
   879         if ($options['limit'] < self::PARAM_LIMIT_MIN_VALUE ||
       
   880             $options['limit'] > self::PARAM_LIMIT_MAX_VALUE) {
       
   881             /**
       
   882              * @see Zend_Service_Technorati_Exception
       
   883              */
       
   884             require_once 'Zend/Service/Technorati/Exception.php';
       
   885             throw new Zend_Service_Technorati_Exception(
       
   886                         "Invalid value '" . $options['limit'] . "' for 'limit' option");
       
   887         }
       
   888     }
       
   889 
       
   890     /**
       
   891      * Checks whether 'start' option value is valid.
       
   892      * Value must be an integer greater than 0.
       
   893      *
       
   894      * @param   array $options
       
   895      * @return  void
       
   896      * @throws  Zend_Service_Technorati_Exception if 'start' value is invalid
       
   897      * @access  protected
       
   898      */
       
   899     protected function _validateOptionStart(array $options)
       
   900     {
       
   901         if (!isset($options['start'])) return;
       
   902 
       
   903         $options['start'] = (int) $options['start'];
       
   904         if ($options['start'] < self::PARAM_START_MIN_VALUE) {
       
   905             /**
       
   906              * @see Zend_Service_Technorati_Exception
       
   907              */
       
   908             require_once 'Zend/Service/Technorati/Exception.php';
       
   909             throw new Zend_Service_Technorati_Exception(
       
   910                         "Invalid value '" . $options['start'] . "' for 'start' option");
       
   911         }
       
   912     }
       
   913 
       
   914     /**
       
   915      * Checks whether 'url' option value exists and is valid.
       
   916      * 'url' must be a valid HTTP(s) URL.
       
   917      *
       
   918      * @param   array $options
       
   919      * @return  void
       
   920      * @throws  Zend_Service_Technorati_Exception if 'url' value is invalid
       
   921      * @access  protected
       
   922      * @todo    support for Zend_Uri_Http
       
   923      */
       
   924     protected function _validateOptionUrl(array $options)
       
   925     {
       
   926         $this->_validateMandatoryOption('url', $options);
       
   927     }
       
   928 
       
   929     /**
       
   930      * Checks XML response content for errors.
       
   931      *
       
   932      * @param   DomDocument $dom    the XML response as a DOM document
       
   933      * @return  void
       
   934      * @throws  Zend_Service_Technorati_Exception
       
   935      * @link    http://technorati.com/developers/api/error.html Technorati API: Error response
       
   936      * @access  protected
       
   937      */
       
   938     protected static function _checkErrors(DomDocument $dom)
       
   939     {
       
   940         $xpath = new DOMXPath($dom);
       
   941 
       
   942         $result = $xpath->query("/tapi/document/result/error");
       
   943         if ($result->length >= 1) {
       
   944             $error = $result->item(0)->nodeValue;
       
   945             /**
       
   946              * @see Zend_Service_Technorati_Exception
       
   947              */
       
   948             require_once 'Zend/Service/Technorati/Exception.php';
       
   949             throw new Zend_Service_Technorati_Exception($error);
       
   950         }
       
   951     }
       
   952 
       
   953     /**
       
   954      * Converts $response body to a DOM object and checks it.
       
   955      *
       
   956      * @param   Zend_Http_Response $response
       
   957      * @return  DOMDocument
       
   958      * @throws  Zend_Service_Technorati_Exception if response content contains an error message
       
   959      * @access  protected
       
   960      */
       
   961     protected function _convertResponseAndCheckContent(Zend_Http_Response $response)
       
   962     {
       
   963         $dom = new DOMDocument();
       
   964         $dom->loadXML($response->getBody());
       
   965         self::_checkErrors($dom);
       
   966         return $dom;
       
   967     }
       
   968 
       
   969     /**
       
   970      * Checks ReST response for errors.
       
   971      *
       
   972      * @param   Zend_Http_Response $response    the ReST response
       
   973      * @return  void
       
   974      * @throws  Zend_Service_Technorati_Exception
       
   975      * @access  protected
       
   976      */
       
   977     protected static function _checkResponse(Zend_Http_Response $response)
       
   978     {
       
   979         if ($response->isError()) {
       
   980             /**
       
   981              * @see Zend_Service_Technorati_Exception
       
   982              */
       
   983             require_once 'Zend/Service/Technorati/Exception.php';
       
   984             throw new Zend_Service_Technorati_Exception(sprintf(
       
   985                         'Invalid response status code (HTTP/%s %s %s)',
       
   986                         $response->getVersion(), $response->getStatus(), $response->getMessage()));
       
   987         }
       
   988     }
       
   989 
       
   990     /**
       
   991      * Checks whether user given options are valid.
       
   992      *
       
   993      * @param   array $options        user options
       
   994      * @param   array $validOptions   valid options
       
   995      * @return  void
       
   996      * @throws  Zend_Service_Technorati_Exception
       
   997      * @access  protected
       
   998      */
       
   999     protected function _compareOptions(array $options, array $validOptions)
       
  1000     {
       
  1001         $difference = array_diff(array_keys($options), $validOptions);
       
  1002         if ($difference) {
       
  1003             /**
       
  1004              * @see Zend_Service_Technorati_Exception
       
  1005              */
       
  1006             require_once 'Zend/Service/Technorati/Exception.php';
       
  1007             throw new Zend_Service_Technorati_Exception(
       
  1008                         "The following parameters are invalid: '" .
       
  1009                         implode("', '", $difference) . "'");
       
  1010         }
       
  1011     }
       
  1012 
       
  1013     /**
       
  1014      * Prepares options for the request
       
  1015      *
       
  1016      * @param   array $options        user options
       
  1017      * @param   array $defaultOptions default options
       
  1018      * @return  array Merged array of user and default/required options.
       
  1019      * @access  protected
       
  1020      */
       
  1021     protected function _prepareOptions($options, array $defaultOptions)
       
  1022     {
       
  1023         $options = (array) $options; // force cast to convert null to array()
       
  1024         $options['key'] = $this->_apiKey;
       
  1025         $options = array_merge($defaultOptions, $options);
       
  1026         return $options;
       
  1027     }
       
  1028 }