Technorati.php 38 KB

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