Technorati.php 38 KB

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