PageRenderTime 42ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/library/external/fork_api.php

http://github.com/forkcms/forkcms
PHP | 543 lines | 193 code | 101 blank | 249 comment | 37 complexity | 38fb88db5b64f70db17e22e6f4d64bbf MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, MIT, AGPL-3.0, LGPL-2.1, BSD-3-Clause
  1. <?php
  2. /**
  3. * ForkAPI class
  4. *
  5. * This source file can be used to communicate with ForkAPI (http://api.fork-cms.be)
  6. *
  7. * The class is documented in the file itself. If you find any bugs help me out and report them. Reporting can be done by sending an email to php-fork-api-bugs[at]verkoyen[dot]eu.
  8. * If you report a bug, make sure you give me enough information (include your code).
  9. *
  10. *
  11. * License
  12. * Copyright (c) 2010, Tijs Verkoyen. All rights reserved.
  13. *
  14. * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
  15. *
  16. * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  17. * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  18. * 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
  19. *
  20. * This software is provided by the author "as is" and any express or implied warranties, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose are disclaimed. In no event shall the author be liable for any direct, indirect, incidental, special, exemplary, or consequential damages (including, but not limited to, procurement of substitute goods or services; loss of use, data, or profits; or business interruption) however caused and on any theory of liability, whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this software, even if advised of the possibility of such damage.
  21. *
  22. * @author Tijs Verkoyen <php-fork-api@verkoyen.eu>
  23. * @version 1.0.1
  24. *
  25. * @copyright Copyright (c) 2008, Tijs Verkoyen. All rights reserved.
  26. * @license BSD License
  27. */
  28. class ForkAPI
  29. {
  30. // internal constant to enable/disable debugging
  31. const DEBUG = false;
  32. // url for the fork-api
  33. const API_URL = 'http://api.fork-cms.be';
  34. // port for the fork-API
  35. const API_PORT = 80;
  36. // Fork-API version
  37. const API_VERSION = '2.0';
  38. // current version
  39. const VERSION = '1.0.0';
  40. /**
  41. * The public key to use
  42. *
  43. * @var string
  44. */
  45. private $publicKey;
  46. /**
  47. * The private key
  48. *
  49. * @var string
  50. */
  51. private $privateKey;
  52. /**
  53. * The timeout
  54. *
  55. * @var int
  56. */
  57. private $timeOut = 20;
  58. /**
  59. * The user agent
  60. *
  61. * @var string
  62. */
  63. private $userAgent;
  64. // class methods
  65. /**
  66. * Default constructor
  67. *
  68. * @return void
  69. * @param string[optional] $publicKey The public-key of the keypair.
  70. * @param string[optional] $privateKey The private-key of the keypair.
  71. */
  72. public function __construct($publicKey = null, $privateKey = null)
  73. {
  74. if($publicKey !== null) $this->setPublicKey($publicKey);
  75. if($publicKey !== null) $this->setPrivateKey($privateKey);
  76. }
  77. /**
  78. * Make the call
  79. *
  80. * @return string
  81. * @param string $method The method to call.
  82. * @param array[optional] $parameters The parameters to pass.
  83. * @param bool[optional] $authenticate Should we authenticate?
  84. * @param bool[optional] $usePOST Should we use POST?
  85. */
  86. private function doCall($method, $parameters = array(), $authenticate = true, $usePOST = false)
  87. {
  88. // redefine
  89. $method = (string) $method;
  90. $parameters = (array) $parameters;
  91. $authenticate = (bool) $authenticate;
  92. // add required parameters
  93. $queryStringParameters['method'] = (string) $method;
  94. // authentication stuff
  95. if($authenticate)
  96. {
  97. // get keys
  98. $publicKey = $this->getPublicKey();
  99. $privateKey = $this->getPrivateKey();
  100. // validate
  101. if($publicKey == '' || $privateKey == '') throw new ForkAPIException('This method ('. $method .') requires authentication, provide a public and private key.');
  102. // add prams
  103. $queryStringParameters['public_key'] = $publicKey;
  104. $queryStringParameters['nonce'] = time();
  105. $queryStringParameters['secret'] = md5($publicKey . $privateKey . $queryStringParameters['nonce']);
  106. }
  107. // build URL
  108. $url = self::API_URL .'/'. self::API_VERSION .'/rest.php?'. http_build_query($queryStringParameters, null, '&', PHP_QUERY_RFC3986);
  109. // use POST?
  110. if($usePOST)
  111. {
  112. // set POST
  113. $options[CURLOPT_POST] = true;
  114. // add data if needed
  115. if(!empty($parameters)) $options[CURLOPT_POSTFIELDS] = array('data' => json_encode($parameters));
  116. }
  117. else
  118. {
  119. // any data if needed
  120. if(!empty($parameters))
  121. {
  122. // build querystring
  123. $queryString = http_build_query(array('data' => json_encode($parameters)), null, '&', PHP_QUERY_RFC3986);
  124. // prepend
  125. $url .= '&'. $queryString;
  126. }
  127. }
  128. // set options
  129. $options[CURLOPT_URL] = $url;
  130. $options[CURLOPT_PORT] = self::API_PORT;
  131. $options[CURLOPT_USERAGENT] = $this->getUserAgent();
  132. if(ini_get('open_basedir') == '' && ini_get('safe_mode' == 'Off')) $options[CURLOPT_FOLLOWLOCATION] = true;
  133. $options[CURLOPT_RETURNTRANSFER] = true;
  134. $options[CURLOPT_TIMEOUT] = (int) $this->getTimeOut();
  135. // init
  136. $curl = curl_init();
  137. // set options
  138. curl_setopt_array($curl, $options);
  139. // execute
  140. $response = curl_exec($curl);
  141. $headers = curl_getinfo($curl);
  142. // fetch errors
  143. $errorNumber = curl_errno($curl);
  144. $errorMessage = curl_error($curl);
  145. // close
  146. curl_close($curl);
  147. // we expect XML so decode it
  148. $xml = @simplexml_load_string($response, null, LIBXML_NOCDATA);
  149. // validate XML
  150. if($xml === false) throw new ForkAPIException('Invalid XML-response.');
  151. // is error?
  152. if(!isset($xml['status']) || (string) $xml['status'] != 'ok')
  153. {
  154. // is it a response error
  155. if(isset($xml->error)) throw new ForkAPIException((string) $xml->error);
  156. // invalid json?
  157. else throw new ForkAPIException('Invalid XML-response.');
  158. }
  159. // return
  160. return $xml;
  161. }
  162. /**
  163. * Get the private key
  164. *
  165. * @return string
  166. */
  167. private function getPrivateKey()
  168. {
  169. return (string) $this->privateKey;
  170. }
  171. /**
  172. * Get the public key
  173. *
  174. * @return string
  175. */
  176. private function getPublicKey()
  177. {
  178. return (string) $this->publicKey;
  179. }
  180. /**
  181. * Get the timeout that will be used
  182. *
  183. * @return int
  184. */
  185. public function getTimeOut()
  186. {
  187. return (int) $this->timeOut;
  188. }
  189. /**
  190. * Get the useragent that will be used. Our version will be prepended to yours.
  191. * It will look like: "PHP ForkAPI/<version> <your-user-agent>"
  192. *
  193. * @return string
  194. */
  195. public function getUserAgent()
  196. {
  197. return (string) 'PHP ForkAPI/'. self::VERSION .' '. $this->userAgent;
  198. }
  199. /**
  200. * Set the private key
  201. *
  202. * @return void
  203. * @param string $key The private key.
  204. */
  205. public function setPrivateKey($key)
  206. {
  207. $this->privateKey = (string) $key;
  208. }
  209. /**
  210. * Set the public key
  211. *
  212. * @return void
  213. * @param string $key The public key.
  214. */
  215. public function setPublicKey($key)
  216. {
  217. $this->publicKey = (string) $key;
  218. }
  219. /**
  220. * Set the timeout
  221. * After this time the request will stop. You should handle any errors triggered by this.
  222. *
  223. * @return void
  224. * @param int $seconds The timeout in seconds.
  225. */
  226. public function setTimeOut($seconds)
  227. {
  228. $this->timeOut = (int) $seconds;
  229. }
  230. /**
  231. * Set the user-agent for you application
  232. * It will be appended to ours, the result will look like: "PHP ForkAPI/<version> <your-user-agent>"
  233. *
  234. * @return void
  235. * @param string $userAgent Your user-agent, it should look like <app-name>/<app-version>.
  236. */
  237. public function setUserAgent($userAgent)
  238. {
  239. $this->userAgent = (string) $userAgent;
  240. }
  241. // core methods
  242. /**
  243. * Request public private key-pair
  244. *
  245. * @return array
  246. * @param string $siteUrl The URL of the site.
  247. * @param string $email The e-mail adress of the site.
  248. */
  249. public function coreRequestKeys($siteUrl, $email)
  250. {
  251. // build parameters
  252. $parameters['site_url'] = (string) $siteUrl;
  253. $parameters['email'] = (string) $email;
  254. // make the call
  255. $response = $this->doCall('core.requestKeys', $parameters, false);
  256. // init var
  257. $return = array();
  258. // validate response
  259. if(!isset($response->keys->public)) throw new ForkAPIException('Invalid XML-response.');
  260. if(!isset($response->keys->private)) throw new ForkAPIException('Invalid XML-response.');
  261. // loop services
  262. $return['public'] = (string) $response->keys->public;
  263. $return['private'] = (string) $response->keys->private;
  264. // return
  265. return $return;
  266. }
  267. // apple methods
  268. /**
  269. * Push a notification to apple
  270. *
  271. * @return array The device tokens that aren't valid.
  272. * @param mixed $deviceTokens The device token(s) for the receiver.
  273. * @param mixed $alert The message/dictonary to send.
  274. * @param int[optional] $badge The number for the badge.
  275. * @param string[optional] $sound The sound that should be played.
  276. * @param array[optional] $extraDictionaries Extra dictionaries.
  277. */
  278. public function applePush($deviceTokens, $alert, $badge = null, $sound = null, array $extraDictionaries = null)
  279. {
  280. // build parameters
  281. $parameters['device_token'] = (array) $deviceTokens;
  282. $parameters['alert'] = $alert;
  283. if($badge !== null) $parameters['badge'] = (int) $badge;
  284. if($sound !== null) $parameters['sound'] = (string) $sound;
  285. if($extraDictionaries !== null) $parameters['extra_dictionaries'] = $extraDictionaries;
  286. // make the call
  287. $response = $this->doCall('apple.push', $parameters, true, true);
  288. // validate
  289. if(!isset($response->failed_device_tokens)) throw new ForkAPIException('Invalid XML-response.');
  290. // init var
  291. $return = array();
  292. // available devices?
  293. if(isset($response->failed_device_tokens->device))
  294. {
  295. // loop and add to return
  296. foreach($response->failed_device_tokens->device as $device) $return[] = (string) $device['token'];
  297. }
  298. // return
  299. return $return;
  300. }
  301. /**
  302. * Register a new/old Apple device within the Fork API
  303. *
  304. * @return bool
  305. * @param string $deviceToken The device token to register.
  306. */
  307. public function appleRegisterDevice($deviceToken)
  308. {
  309. // build parameters
  310. $parameters['device_token'] = str_replace(' ', '', (string) $deviceToken);
  311. // make the call
  312. $this->doCall('apple.registerDevice', $parameters, true, true);
  313. // return
  314. return true;
  315. }
  316. // message methods
  317. /**
  318. * Get messages from the server
  319. *
  320. * @return array
  321. */
  322. public function messagesGet()
  323. {
  324. // make the call
  325. $response = $this->doCall('messages.get');
  326. // init var
  327. $return = array();
  328. // validate response
  329. if(!isset($response->messages->message)) throw new ForkAPIException('Invalid XML-response.');
  330. // loop services
  331. foreach($response->messages->message as $message)
  332. {
  333. // add into array
  334. $return[] = array('id' => (string) $message['id'],
  335. 'sent_on' => (int) strtotime((string) $message['sent_on']),
  336. 'subject' => (string) $message->subject,
  337. 'body' => (string) $message->body);
  338. }
  339. // return
  340. return $return;
  341. }
  342. // microsoft methods
  343. /**
  344. * Push a notification to microsoft
  345. *
  346. * @return array The device tokens that aren't valid.
  347. * @param mixed $channelUri The channel URI(s) for the receiver.
  348. * @param string $title The title for the tile to send.
  349. * @param string[optional] $count The count for the tile to send.
  350. * @param string[optional] $image The image for the tile to send.
  351. * @param string[optional] $backTitle The title for the tile backtround to send.
  352. * @param string[optional] $backText The text for the tile background to send.
  353. * @param string[optional] $backImage The image for the tile background to send.
  354. * @param string[optional] $tile The secondary tile to update.
  355. * @param string[optional] $uri The application uri to navigate to.
  356. */
  357. public function microsoftPush($channelUri, $title, $count = null, $image = null, $backTitle = null, $backText = null, $backImage = null, $tile = null, $uri = null)
  358. {
  359. // build parameters
  360. $parameters['channel_uri'] = (array) $channelUri;
  361. $parameters['title'] = (string) $title;
  362. if($count !== null) $parameters['count'] = (int) $count;
  363. if($image !== null) $parameters['image'] = (string) $image;
  364. if($backTitle !== null) $parameters['back_title'] = (string) $backTitle;
  365. if($backText !== null) $parameters['back_text'] = (string) $backText;
  366. if($backImage !== null) $parameters['back_image'] = (string) $backImage;
  367. if($tile !== null) $parameters['tile'] = (string) $tile;
  368. if($uri !== null) $parameters['uri'] = (string) $uri;
  369. // make the call
  370. $this->doCall('microsoft.push', $parameters, true, true);
  371. }
  372. /**
  373. * Register a new/old Microsoft device within the Fork API
  374. *
  375. * @return bool
  376. * @param string $channelUri The channel uri to register.
  377. */
  378. public function microsoftRegisterDevice($channelUri)
  379. {
  380. // build parameters
  381. $parameters['channel_uri'] = (string) $channelUri;
  382. // make the call
  383. $this->doCall('microsoft.registerDevice', $parameters, true, true);
  384. // return
  385. return true;
  386. }
  387. // ping methods
  388. /**
  389. * Get the ping services
  390. *
  391. * @return array
  392. */
  393. public function pingGetServices()
  394. {
  395. // make the call
  396. $response = $this->doCall('ping.getServices');
  397. // init var
  398. $return = array();
  399. // validate response
  400. if(!isset($response->services->service)) throw new ForkAPIException('Invalid XML-response.');
  401. // loop services
  402. foreach($response->services->service as $service) $return[] = array('url' => (string) $service['url'], 'port' => (int) $service['port'], 'type' => (string) $service['type']);
  403. // return
  404. return $return;
  405. }
  406. // statistics methods
  407. /**
  408. * Get the search engines
  409. *
  410. * @return array
  411. */
  412. public function statisticsGetSearchEngines()
  413. {
  414. // make the call
  415. $response = $this->doCall('statistics.getSearchEngines');
  416. // init var
  417. $return = array();
  418. // validate response
  419. if(!isset($response->search_engines->engine)) throw new ForkAPIException('Invalid XML-response.');
  420. // loop services
  421. foreach($response->search_engines->engine as $engine)
  422. {
  423. // init var
  424. $urls = array();
  425. // loop urls
  426. foreach($engine->urls->url as $url) $urls[] = (string) $url;
  427. // add to return
  428. $return[] = array('name' => (string) $engine->name, 'splitchar' => (string) $engine->splitchar, 'urls' => $urls);
  429. }
  430. // return
  431. return $return;
  432. }
  433. }
  434. /**
  435. * ForkAPI Exception class
  436. *
  437. * @author Tijs Verkoyen <php-fork-api@verkoyen.eu>
  438. */
  439. class ForkAPIException extends Exception
  440. {
  441. }
  442. ?>