/sfOAuth.class.php

https://github.com/sglessard/OAuthBase · PHP · 1353 lines · 503 code · 127 blank · 723 comment · 40 complexity · 8b2f01ba638088df05c0e261e02a935d MD5 · raw file

  1. <?php
  2. /**
  3. * Abstract class for both version of OAuth 1 and 2
  4. *
  5. * @author Maxime Picaud
  6. * @since 21 août 2010
  7. */
  8. abstract class sfOAuth
  9. {
  10. /**
  11. * version of OAuth used
  12. *
  13. * @var integer $version
  14. */
  15. protected $version;
  16. /**
  17. * the key retrieve from the service
  18. *
  19. * @var string $key
  20. */
  21. protected $key;
  22. /**
  23. * the secret key retrieve from the service
  24. *
  25. * @var string $secret
  26. */
  27. protected $secret;
  28. /**
  29. * Can be access token or request token. Is the current token
  30. *
  31. * @var Token
  32. */
  33. protected $token;
  34. /**
  35. * URL to request authorization
  36. *
  37. * @var string $request_auth_url
  38. */
  39. protected $request_auth_url;
  40. /**
  41. * Url to retrieve the access token
  42. *
  43. * @var string $access_token_url
  44. */
  45. protected $access_token_url;
  46. /**
  47. * Method to retrieve the access token (GET, POST)
  48. *
  49. * @var string $access_token_method
  50. */
  51. protected $access_token_method;
  52. /**
  53. * Namespaces used to access api
  54. *
  55. * @var array $namespaces
  56. */
  57. protected $namespaces = array();
  58. /**
  59. * The current namespace. By default is the 'default' namespace.
  60. *
  61. * @var string $current_namespace
  62. */
  63. protected $current_namespace;
  64. /**
  65. * the symfony controller
  66. *
  67. * @var sfFrontWebController $controller
  68. */
  69. protected $controller;
  70. /**
  71. * the symfony logger
  72. *
  73. * @var sfLogger $logger
  74. */
  75. protected $logger;
  76. /**
  77. * the symfony context
  78. *
  79. * @var sfContext
  80. */
  81. protected $context;
  82. /**
  83. * The name of the instance. used to store in the database and recognize it
  84. *
  85. * @var string $name
  86. */
  87. protected $name;
  88. /**
  89. * Callback to use after request Auth. can be an internal routing rule like @homepage
  90. *
  91. * @var string $callback
  92. */
  93. protected $callback;
  94. /**
  95. * parameters passed for each api request.
  96. *
  97. * @var array $parameters
  98. */
  99. protected $access_parameters = array();
  100. /**
  101. * parameters passed for each api request.
  102. *
  103. * @var array $parameters
  104. */
  105. protected $auth_parameters = array();
  106. /**
  107. * parameters passed for each api request.
  108. *
  109. * @var array $parameters
  110. */
  111. protected $call_parameters = array();
  112. /**
  113. * parameters passed for each api request.
  114. *
  115. * @var array $parameters
  116. */
  117. protected $aliases = array();
  118. /**
  119. * @var string $output_format
  120. */
  121. protected $output_format = 'json';
  122. /**
  123. * @var array $config
  124. */
  125. protected $config;
  126. /**
  127. *
  128. * @param string $key
  129. * @param string $secret
  130. * @param Token $token
  131. * @param array $config
  132. *
  133. * Constructor
  134. *
  135. * @author Maxime Picaud
  136. * @since 21 août 2010
  137. */
  138. public function __construct($key, $secret, $token = null, $config = array())
  139. {
  140. $this->setKey($key);
  141. $this->setSecret($secret);
  142. $this->setToken($token);
  143. $this->setConfig($config);
  144. $this->init($config, 'callback');
  145. $this->init($config, 'request_auth_url');
  146. $this->init($config, 'access_token_url');
  147. $this->init($config, 'namespaces');
  148. $this->init($config, 'current_namespace');
  149. $this->init($config, 'context');
  150. $this->init($config, 'controller');
  151. $this->init($config, 'logger');
  152. $this->init($config, 'name');
  153. $this->init($config, 'callback');
  154. $this->init($config, 'auth_parameters', 'add');
  155. $this->init($config, 'call_parameters', 'add');
  156. $this->init($config, 'access_parameters', 'add');
  157. $this->init($config, 'aliases', 'add');
  158. $this->init($config, 'output_format');
  159. $this->initialize($config);
  160. }
  161. /**
  162. *
  163. * @param array $config
  164. * @param mixed $key
  165. *
  166. * to init config parameters
  167. *
  168. * @author Maxime Picaud
  169. * @since 21 août 2010
  170. */
  171. protected function init($config, $key, $prefix = 'set')
  172. {
  173. if(isset($config[$key]))
  174. {
  175. $method = $prefix.sfInflector::classify($key);
  176. $this->$method($config[$key]);
  177. }
  178. }
  179. /**
  180. *
  181. * @param array $config
  182. *
  183. * Initialize child classes
  184. *
  185. * @author Maxime Picaud
  186. * @since 21 août 2010
  187. */
  188. protected function initialize($config)
  189. {
  190. }
  191. /**
  192. *
  193. * @param Token $token
  194. *
  195. * Initialize when token is set
  196. *
  197. * @author Maxime Picaud
  198. * @since 10 sept. 2010
  199. */
  200. protected function initializeFromToken($token)
  201. {
  202. }
  203. /**
  204. * implemented by child classes to request auth
  205. *
  206. * @author Maxime Picaud
  207. * @since 21 août 2010
  208. */
  209. abstract public function requestAuth($parameters = array());
  210. /**
  211. *
  212. * @param string $verifier
  213. *
  214. * get the access token with the verification code
  215. *
  216. * @author Maxime Picaud
  217. * @since 21 août 2010
  218. */
  219. abstract public function getAccessToken($verifier, $parameters = array());
  220. /**
  221. * Identifier is used to create user with unique name. must be override in child classes
  222. * to have user id of the service for example
  223. *
  224. * @author Maxime Picaud
  225. * @since 21 août 2010
  226. */
  227. public function getIdentifier()
  228. {
  229. return mt_rand(0, 99999999999);
  230. }
  231. /**
  232. * Could be overriden in child classes for those need to refresh their tokens
  233. *
  234. * @author Maxime Picaud
  235. * @since 21 août 2010
  236. */
  237. public function refreshToken()
  238. {
  239. }
  240. /**
  241. *
  242. * @param Token $token
  243. *
  244. * Idem as refreshToken
  245. *
  246. * @author Maxime Picaud
  247. * @since 21 août 2010
  248. */
  249. protected function setExpire(&$token)
  250. {
  251. }
  252. /**
  253. * getter $version
  254. *
  255. * @return integer
  256. *
  257. * @author Maxime Picaud
  258. * @since 21 août 2010
  259. */
  260. public function getVersion()
  261. {
  262. return $this->version;
  263. }
  264. /**
  265. * getter $key
  266. *
  267. * @return string
  268. *
  269. * @author Maxime Picaud
  270. * @since 21 août 2010
  271. */
  272. public function getKey()
  273. {
  274. return $this->key;
  275. }
  276. /**
  277. *
  278. * @param string $key
  279. *
  280. * setter $key
  281. *
  282. * @author Maxime Picaud
  283. * @since 21 août 2010
  284. */
  285. public function setKey($key)
  286. {
  287. $this->key = $key;
  288. }
  289. /**
  290. * getter $secret
  291. *
  292. * @return string
  293. *
  294. * @author Maxime Picaud
  295. * @since 21 août 2010
  296. */
  297. public function getSecret()
  298. {
  299. return $this->secret;
  300. }
  301. /**
  302. *
  303. * @param string $secret
  304. *
  305. * setter $secret
  306. *
  307. * @author Maxime Picaud
  308. * @since 21 août 2010
  309. */
  310. public function setSecret($secret)
  311. {
  312. $this->secret = $secret;
  313. }
  314. /**
  315. * @param string $format
  316. *
  317. * format can be 'oauth' to retrieve en OAuthToken Object
  318. * getter $token
  319. *
  320. * @return Token
  321. *
  322. * @author Maxime Picaud
  323. * @since 12 août 2010
  324. */
  325. public function getToken($format = 'token')
  326. {
  327. if($format == 'oauth')
  328. {
  329. if(!is_null($this->token))
  330. {
  331. return $this->token->toOAuthToken();
  332. }
  333. else
  334. {
  335. return null;
  336. }
  337. }
  338. return $this->token;
  339. }
  340. /**
  341. *
  342. * @param Token $token
  343. *
  344. * setter $token
  345. *
  346. * @author Maxime Picaud
  347. * @since 21 août 2010
  348. */
  349. public function setToken($token)
  350. {
  351. $this->token = $token;
  352. $this->initializeFromToken($token);
  353. }
  354. public function getConfigParameter($key, $default = null)
  355. {
  356. return isset($this->config[$key])?$this->config[$key]:$default;
  357. }
  358. /**
  359. * getter $config
  360. *
  361. * @return string
  362. *
  363. * @author Maxime Picaud
  364. * @since 28 août 2010
  365. */
  366. public function getConfig()
  367. {
  368. return $this->config;
  369. }
  370. /**
  371. *
  372. * @param string $config
  373. *
  374. * setter $config
  375. *
  376. * @author Maxime Picaud
  377. * @since 21 août 2010
  378. */
  379. public function setConfig($config)
  380. {
  381. $this->config = $config;
  382. $this->initialize($config);
  383. }
  384. /**
  385. * getter $output_format
  386. *
  387. * @return string
  388. *
  389. * @author Maxime Picaud
  390. * @since 21 août 2010
  391. */
  392. public function getOutputFormat()
  393. {
  394. return $this->output_format;
  395. }
  396. /**
  397. *
  398. * @param string $output_format
  399. *
  400. * setter $output_format
  401. *
  402. * @author Maxime Picaud
  403. * @since 21 août 2010
  404. */
  405. public function setOutputFormat($output_format)
  406. {
  407. $this->output_format = $output_format;
  408. }
  409. /**
  410. * getter $request_auth_url
  411. *
  412. * @return string
  413. *
  414. * @author Maxime Picaud
  415. * @since 21 août 2010
  416. */
  417. public function getRequestAuthUrl()
  418. {
  419. return $this->request_auth_url;
  420. }
  421. /**
  422. *
  423. * @param string $request_auth_url
  424. *
  425. * setter $request_auth_url
  426. *
  427. * @author Maxime Picaud
  428. * @since 21 août 2010
  429. */
  430. public function setRequestAuthUrl($request_auth_url)
  431. {
  432. $this->request_auth_url = $request_auth_url;
  433. }
  434. /**
  435. * getter $access_token_url
  436. *
  437. * @return string
  438. *
  439. * @author Maxime Picaud
  440. * @since 21 août 2010
  441. */
  442. public function getAccessTokenUrl()
  443. {
  444. return $this->access_token_url;
  445. }
  446. /**
  447. *
  448. * @param string $access_token_url
  449. *
  450. * setter $access_token_url
  451. *
  452. * @author Maxime Picaud
  453. * @since 21 août 2010
  454. */
  455. public function setAccessTokenUrl($access_token_url)
  456. {
  457. $this->access_token_url = $access_token_url;
  458. }
  459. /**
  460. * getter $access_token_method
  461. *
  462. * @return string (default to 'GET' for backward compatibility)
  463. *
  464. * @author Simon Guillem-Lessard
  465. * @since 27 septembre 2012
  466. */
  467. public function getAccessTokenMethod()
  468. {
  469. return $this->access_token_method == null ? 'GET' : $this->access_token_method;
  470. }
  471. /**
  472. *
  473. * @param string $access_token_method
  474. *
  475. * setter $access_token_method
  476. *
  477. * @author Simon Guillem-Lessard
  478. * @since 27 septembre 2012
  479. */
  480. public function setAccessTokenMethod($access_token_method)
  481. {
  482. $this->access_token_method = $access_token_method;
  483. }
  484. /**
  485. * getter $context.
  486. *
  487. *
  488. * @return sfContext
  489. *
  490. * @author Maxime Picaud
  491. * @since 19 sept. 2010
  492. */
  493. public function getContext()
  494. {
  495. if(is_null($this->context) && sfContext::hasInstance())
  496. {
  497. $this->context = sfContext::getInstance();
  498. }
  499. return $this->context;
  500. }
  501. /**
  502. *
  503. * @param sfContext $context
  504. *
  505. * setter $context
  506. *
  507. * @author Maxime Picaud
  508. * @since 19 sept 2010
  509. */
  510. public function setContext(sfContext $context)
  511. {
  512. $this->context = $context;
  513. }
  514. /**
  515. * getter $controller. If not set call to the default context
  516. *
  517. *
  518. * @return sfFrontWebController
  519. *
  520. * @author Maxime Picaud
  521. * @since 21 août 2010
  522. */
  523. public function getController()
  524. {
  525. if(is_null($this->controller) && !is_null($this->getContext()))
  526. {
  527. $this->controller = $this->getContext()->getController();
  528. }
  529. return $this->controller;
  530. }
  531. /**
  532. *
  533. * @param sfFrontWebController $controller
  534. *
  535. * setter $controller
  536. *
  537. * @author Maxime Picaud
  538. * @since 21 août 2010
  539. */
  540. public function setController(sfFrontWebController $controller)
  541. {
  542. $this->controller = $controller;
  543. }
  544. /**
  545. * getter $logger
  546. *
  547. *
  548. * @return sfLogger
  549. *
  550. * @author Maxime Picaud
  551. * @since 19 sept 2010
  552. */
  553. public function getLogger()
  554. {
  555. if(is_null($this->logger) && !is_null($this->getContext()))
  556. {
  557. $this->logger = $this->getContext()->getLogger();
  558. }
  559. return $this->logger;
  560. }
  561. /**
  562. *
  563. * @param sfLogger $logger
  564. *
  565. * setter $logger
  566. *
  567. * @author Maxime Picaud
  568. * @since 19 sept 2010
  569. */
  570. public function setLogger(sfLogger $logger)
  571. {
  572. $this->logger = $logger;
  573. }
  574. /**
  575. * getter $callback
  576. *
  577. * @return string
  578. *
  579. * @author Maxime Picaud
  580. * @since 21 août 2010
  581. */
  582. public function getCallback()
  583. {
  584. return $this->callback;
  585. }
  586. /**
  587. *
  588. * @param string $callback
  589. *
  590. * setter callback - url or rouging rule like @homepage
  591. *
  592. * @author Maxime Picaud
  593. * @since 21 août 2010
  594. */
  595. public function setCallback($callback)
  596. {
  597. if(strpos($callback, '@') !== false)
  598. {
  599. $callback = $this->getController()->genUrl($callback, true);
  600. }
  601. $this->getController()->convertUrlStringToParameters($callback);
  602. $this->callback = $callback;
  603. }
  604. /**
  605. * getter $name
  606. *
  607. * @return string
  608. *
  609. * @author Maxime Picaud
  610. * @since 21 août 2010
  611. */
  612. public function getName()
  613. {
  614. return $this->name;
  615. }
  616. /**
  617. *
  618. * @param string $name
  619. *
  620. * setter $name
  621. *
  622. * @author Maxime Picaud
  623. * @since 21 août 2010
  624. */
  625. public function setName($name)
  626. {
  627. $this->name = $name;
  628. }
  629. /**
  630. *
  631. * @param array $parameters
  632. *
  633. * setter $parameters
  634. *
  635. * @author Maxime Picaud
  636. * @since 21 août 2010
  637. */
  638. public function setAuthParameters($parameters)
  639. {
  640. $this->auth_parameters = $parameters;
  641. }
  642. /**
  643. *
  644. * @param mixed $key
  645. * @param mixed $value
  646. *
  647. * set a parameter
  648. *
  649. * @author Maxime Picaud
  650. * @since 21 août 2010
  651. */
  652. public function setAuthParameter($key, $value)
  653. {
  654. $this->auth_parameters[$key] = $value;
  655. }
  656. /**
  657. * getter $parameters
  658. *
  659. * @return array
  660. *
  661. * @author Maxime Picaud
  662. * @since 21 août 2010
  663. */
  664. public function getAuthParameters()
  665. {
  666. return $this->auth_parameters;
  667. }
  668. /**
  669. *
  670. * @param mixed $key
  671. * @param mixed $default
  672. *
  673. * Retrieve a parameter by its key and return $default if is undefined
  674. *
  675. * @return mixed
  676. *
  677. * @author Maxime Picaud
  678. * @since 21 août 2010
  679. */
  680. public function getAuthParameter($key, $default = null)
  681. {
  682. return isset($this->auth_parameters[$key])?$this->auth_parameters[$key]:$default;
  683. }
  684. /**
  685. *
  686. * @param array $parameters
  687. *
  688. * merge current parameters with this $parameters
  689. *
  690. * @author Maxime Picaud
  691. * @since 21 août 2010
  692. */
  693. public function addAuthParameters($parameters)
  694. {
  695. $this->auth_parameters = array_merge($this->auth_parameters, $parameters);
  696. }
  697. /**
  698. *
  699. * @param array $parameters
  700. *
  701. * setter $parameters
  702. *
  703. * @author Maxime Picaud
  704. * @since 21 août 2010
  705. */
  706. public function setAccessParameters($parameters)
  707. {
  708. $this->access_parameters = $parameters;
  709. }
  710. /**
  711. *
  712. * @param mixed $key
  713. * @param mixed $value
  714. *
  715. * set a parameter
  716. *
  717. * @author Maxime Picaud
  718. * @since 21 août 2010
  719. */
  720. public function setAccessParameter($key, $value)
  721. {
  722. $this->access_parameters[$key] = $value;
  723. }
  724. /**
  725. * getter $parameters
  726. *
  727. * @return array
  728. *
  729. * @author Maxime Picaud
  730. * @since 21 août 2010
  731. */
  732. public function getAccessParameters()
  733. {
  734. return $this->access_parameters;
  735. }
  736. /**
  737. *
  738. * @param mixed $key
  739. * @param mixed $default
  740. *
  741. * Retrieve a parameter by its key and return $default if is undefined
  742. *
  743. * @return mixed
  744. *
  745. * @author Maxime Picaud
  746. * @since 21 août 2010
  747. */
  748. public function getAccessParameter($key, $default = null)
  749. {
  750. return isset($this->access_parameters[$key])?$this->access_parameters[$key]:$default;
  751. }
  752. /**
  753. *
  754. * @param array $parameters
  755. *
  756. * merge current parameters with this $parameters
  757. *
  758. * @author Maxime Picaud
  759. * @since 21 août 2010
  760. */
  761. public function addAccessParameters($parameters)
  762. {
  763. $this->access_parameters = array_merge($this->access_parameters, $parameters);
  764. }
  765. /**
  766. *
  767. * @param array $parameters
  768. *
  769. * setter $parameters
  770. *
  771. * @author Maxime Picaud
  772. * @since 21 août 2010
  773. */
  774. public function setCallParameters($parameters)
  775. {
  776. $this->call_parameters = $parameters;
  777. }
  778. /**
  779. *
  780. * @param mixed $key
  781. * @param mixed $value
  782. *
  783. * set a parameter
  784. *
  785. * @author Maxime Picaud
  786. * @since 21 août 2010
  787. */
  788. public function setCallParameter($key, $value)
  789. {
  790. $this->call_parameters[$key] = $value;
  791. }
  792. /**
  793. * getter $parameters
  794. *
  795. * @return array
  796. *
  797. * @author Maxime Picaud
  798. * @since 21 août 2010
  799. */
  800. public function getCallParameters()
  801. {
  802. return $this->call_parameters;
  803. }
  804. /**
  805. *
  806. * @param mixed $key
  807. * @param mixed $default
  808. *
  809. * Retrieve a parameter by its key and return $default if is undefined
  810. *
  811. * @return mixed
  812. *
  813. * @author Maxime Picaud
  814. * @since 21 août 2010
  815. */
  816. public function getCallParameter($key, $default = null)
  817. {
  818. return isset($this->call_parameters[$key])?$this->call_parameters[$key]:$default;
  819. }
  820. /**
  821. *
  822. * @param array $parameters
  823. *
  824. * merge current parameters with this $parameters
  825. *
  826. * @author Maxime Picaud
  827. * @since 21 août 2010
  828. */
  829. public function addCallParameters($parameters)
  830. {
  831. if(is_array($parameters))
  832. {
  833. if(is_array($this->call_parameters))
  834. {
  835. $this->call_parameters = array_merge($this->call_parameters, $parameters);
  836. }
  837. else
  838. {
  839. $this->setCallParameters($parameters);
  840. }
  841. }
  842. }
  843. /**
  844. *
  845. * @param array $parameters
  846. *
  847. * setter $parameters
  848. *
  849. * @author Maxime Picaud
  850. * @since 21 août 2010
  851. */
  852. public function setAliases($aliases)
  853. {
  854. $this->aliases = $aliases;
  855. }
  856. /**
  857. *
  858. * @param mixed $key
  859. * @param mixed $value
  860. *
  861. * set an alias
  862. *
  863. * @author Maxime Picaud
  864. * @since 21 août 2010
  865. */
  866. public function setAlias($key, $value)
  867. {
  868. $this->aliases[$key] = $value;
  869. }
  870. /**
  871. * getter $aliases
  872. *
  873. * @return array
  874. *
  875. * @author Maxime Picaud
  876. * @since 21 août 2010
  877. */
  878. public function getAliases()
  879. {
  880. return $this->aliases;
  881. }
  882. /**
  883. *
  884. * @param mixed $key
  885. * @param mixed $default
  886. *
  887. * Retrieve an alias by its key and return $default if is undefined
  888. *
  889. * @return mixed
  890. *
  891. * @author Maxime Picaud
  892. * @since 21 août 2010
  893. */
  894. public function getAlias($key, $default = null)
  895. {
  896. return isset($this->aliases[$key])?$this->aliases[$key]:$default;
  897. }
  898. /**
  899. *
  900. * @param array $aliases
  901. *
  902. * merge current aliases with this $aliases
  903. *
  904. * @author Maxime Picaud
  905. * @since 21 août 2010
  906. */
  907. public function addAliases($aliases)
  908. {
  909. $this->aliases = array_merge($this->aliases, $aliases);
  910. }
  911. /**
  912. *
  913. * @param array $namespaces
  914. *
  915. * setter $namespaces
  916. *
  917. * @author Maxime Picaud
  918. * @since 21 août 2010
  919. */
  920. public function setNamespaces($namespaces)
  921. {
  922. $this->namespaces = $namespaces;
  923. }
  924. /**
  925. *
  926. * @param mixed $key
  927. * @param string $value
  928. *
  929. * set a specific namespace
  930. *
  931. * @author Maxime Picaud
  932. * @since 21 août 2010
  933. */
  934. public function setNamespace($key, $value)
  935. {
  936. $this->namespaces[$key] = $value;
  937. }
  938. /**
  939. * getter $namespaces
  940. *
  941. * @return array
  942. *
  943. * @author Maxime Picaud
  944. * @since 21 août 2010
  945. */
  946. public function getNamespaces()
  947. {
  948. return $this->namespaces;
  949. }
  950. /**
  951. *
  952. * @param mixed $key
  953. *
  954. * return a specifi namespace
  955. *
  956. * @return string
  957. *
  958. * @author Maxime Picaud
  959. * @since 21 août 2010
  960. */
  961. public function getNamespace($key)
  962. {
  963. return isset($this->namespaces[$key])?$this->namespaces[$key]:$default;
  964. }
  965. /**
  966. *
  967. * @param array $namespaces
  968. *
  969. * mixed with existing namespaces
  970. *
  971. * @author Maxime Picaud
  972. * @since 21 août 2010
  973. */
  974. public function addNamespaces($namespaces)
  975. {
  976. $this->namespaces = array_merge($this->namespaces, $namespaces);
  977. }
  978. /**
  979. *
  980. * @param string $url
  981. * @param array $params
  982. * @param string $method
  983. *
  984. * call REST Api
  985. *
  986. * @author Maxime Picaud
  987. * @since 21 août 2010
  988. */
  989. protected function call($url, $url_params = null, $post_params = null, $method = 'POST')
  990. {
  991. $ci = curl_init();
  992. if ($this->getVersion() == 1.5 && isset($url_params['access_token']))
  993. {
  994. $headers = array('Accept: application/json', 'Authorization: WRAP access_token='.$url_params['access_token']);
  995. curl_setopt($ci, CURLOPT_HTTPHEADER, $headers);
  996. $this->getLogger()->info(sprintf('{OAuth} headers "%s"',
  997. print_r($headers, true)
  998. )
  999. );
  1000. unset($url_params['access_token'], $url_params['format']);
  1001. }
  1002. if(is_array($url_params) && count($url_params) > 0)
  1003. {
  1004. $url_params = http_build_query($url_params);
  1005. }
  1006. if(in_array($method, array('PUT', 'DELETE')))
  1007. {
  1008. curl_setopt($ci, CURLOPT_CUSTOMREQUEST, $method);
  1009. }
  1010. elseif($method == 'POST')
  1011. {
  1012. curl_setopt($ci, CURLOPT_POST, true);
  1013. }
  1014. elseif($method == 'GET' && !empty($url_params))
  1015. {
  1016. $url = $this->appendToUrl($url, $url_params);
  1017. }
  1018. if(in_array($method, array('PUT', 'DELETE', 'POST')))
  1019. {
  1020. if(!is_null($post_params))
  1021. {
  1022. $url = $this->appendToUrl($url, $url_params);
  1023. curl_setopt($ci, CURLOPT_POSTFIELDS, $post_params);
  1024. }
  1025. else
  1026. {
  1027. curl_setopt($ci, CURLOPT_POSTFIELDS, $url_params);
  1028. }
  1029. }
  1030. curl_setopt($ci, CURLOPT_HEADER, false);
  1031. curl_setopt($ci, CURLOPT_URL, $url);
  1032. curl_setopt($ci, CURLOPT_RETURNTRANSFER, true);
  1033. $response = curl_exec($ci);
  1034. curl_close ($ci);
  1035. if($this->getLogger())
  1036. {
  1037. $this->getLogger()->info(sprintf('{OAuth} call url "%s" with params "%s" post "%s" by method "%s" give response "%s"',
  1038. $url,
  1039. $url_params,
  1040. $post_params,
  1041. $method,
  1042. $response
  1043. )
  1044. );
  1045. }
  1046. return $response;
  1047. }
  1048. /**
  1049. *
  1050. * @param string $namespace
  1051. * @throws sfException
  1052. *
  1053. * Choose the current namespace
  1054. *
  1055. * @author Maxime Picaud
  1056. * @since 21 août 2010
  1057. */
  1058. public function ns($namespace)
  1059. {
  1060. if(in_array($namespace, array_keys($this->namespaces)))
  1061. {
  1062. $this->current_namespace = $namespace;
  1063. }
  1064. else
  1065. {
  1066. throw new sfException(sprintf('Namespace "%s" is not defined for Melody "%s"', $namespace, get_class($this)));
  1067. }
  1068. return $this;
  1069. }
  1070. /**
  1071. * getter $current_namespace
  1072. *
  1073. * @author Maxime Picaud
  1074. * @since 21 août 2010
  1075. */
  1076. public function getCurrentNamespace()
  1077. {
  1078. if(is_null($this->current_namespace))
  1079. {
  1080. $this->current_namespace = 'default';
  1081. }
  1082. return $this->current_namespace;
  1083. }
  1084. /**
  1085. *
  1086. * @param string $url
  1087. * @param array $url_params
  1088. *
  1089. * apply aliases on the url
  1090. *
  1091. * @author Maxime Picaud
  1092. * @since 21 août 2010
  1093. */
  1094. public function applyUrlAliases($url, $aliases)
  1095. {
  1096. foreach($aliases as $key => $alias)
  1097. {
  1098. $url = preg_replace('/\/'.$key.'(\/|$)/', '/'.$alias.'$1', $url);
  1099. }
  1100. return $url;
  1101. }
  1102. /**
  1103. *
  1104. * @param string $method
  1105. * @param array $arguments
  1106. *
  1107. * Used for api call
  1108. *
  1109. * @author Maxime Picaud
  1110. * @since 21 août 2010
  1111. */
  1112. public function __call($method, $arguments)
  1113. {
  1114. $params = explode('_',sfInflector::tableize($method));
  1115. $callable = array($this, array_shift($params));
  1116. array_unshift($arguments, implode('/', $params));
  1117. if(is_callable($callable))
  1118. {
  1119. return call_user_func_array($callable, $arguments);
  1120. }
  1121. else throw new sfException(sprintf('method "%s" does not exists in "%s" class', $callable[1], get_class($this)));
  1122. }
  1123. protected function appendToUrl($url, $params)
  1124. {
  1125. if(strpos($url, '?') !== false)
  1126. {
  1127. $url .= '&'.$params;
  1128. }
  1129. else
  1130. {
  1131. $url .= '?'.$params;
  1132. }
  1133. return $url;
  1134. }
  1135. protected function formatResult($response)
  1136. {
  1137. if($this->getOutputFormat() == 'json')
  1138. {
  1139. $response = json_decode($response);
  1140. }
  1141. return $response;
  1142. }
  1143. protected function formatUrl($action, $aliases = null)
  1144. {
  1145. if(is_null($this->getToken()))
  1146. {
  1147. throw new sfException(sprintf('there is no available token to make an api call in "%s" oauth', $this->getName()));
  1148. }
  1149. $base_url = $this->getNamespace($this->getCurrentNamespace());
  1150. $url = $base_url.'/'.$action;
  1151. if(is_string($aliases))
  1152. {
  1153. $url .= '/'.$aliases;
  1154. }
  1155. elseif(is_array($aliases))
  1156. {
  1157. $aliases = array_merge($this->getAliases(), $aliases);
  1158. }
  1159. if(!is_array($aliases))
  1160. {
  1161. $aliases = $this->getAliases();
  1162. }
  1163. return $this->applyUrlAliases($url, $aliases);
  1164. }
  1165. /**
  1166. *
  1167. * @param string $action
  1168. * @param array $url_params
  1169. * @param array $params
  1170. * @param string $method
  1171. *
  1172. * make api call
  1173. *
  1174. * @author Maxime Picaud
  1175. * @since 21 août 2010
  1176. */
  1177. abstract public function get($action, $aliases = null, $parameters = array());
  1178. abstract public function post($action, $aliases = null, $parameters = array());
  1179. abstract public function put($action, $aliases = null, $parameters = array());
  1180. abstract public function delete($action, $aliases = null, $parameters = array());
  1181. abstract protected function prepareCall($action, $aliases = null, $params = array(), $method = 'GET');
  1182. /**
  1183. *
  1184. * @param mixed $result
  1185. * @param string $path
  1186. * @param mixed $default
  1187. *
  1188. * Allow to retrieve result from a path
  1189. *
  1190. * @author Maxime Picaud
  1191. * @since 20 sept. 2010
  1192. */
  1193. public function fromPath($result, $path, $default = null)
  1194. {
  1195. $fields = explode('.', $path);
  1196. foreach($fields as $field)
  1197. {
  1198. if(is_object($result) && isset($result->$field))
  1199. {
  1200. $result = $result->$field;
  1201. }
  1202. elseif(is_array($result))
  1203. {
  1204. if(is_numeric($field))
  1205. {
  1206. $field = intval($field);
  1207. }
  1208. if(isset($result[$field]))
  1209. {
  1210. $result = $result[$field];
  1211. }
  1212. else
  1213. {
  1214. $result = $default;
  1215. break;
  1216. }
  1217. }
  1218. else
  1219. {
  1220. $result = $default;
  1221. break;
  1222. }
  1223. }
  1224. return $result;
  1225. }
  1226. }