PageRenderTime 50ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/src/lib/FACTFinder/Http/DataProvider.php

https://github.com/Flagbit/Magento-FACTFinder
PHP | 323 lines | 172 code | 40 blank | 111 comment | 28 complexity | e0eb9dfa37502f71d6c76acf28d1a8c7 MD5 | raw file
  1. <?php
  2. /**
  3. * FACT-Finder PHP Framework
  4. *
  5. * @category Library
  6. * @package FACTFinder\Http
  7. * @copyright Copyright (c) 2012 Omikron Data Quality GmbH (www.omikron.net)
  8. */
  9. /**
  10. * this data provider loads the data via http
  11. *
  12. * @author Rudolf Batt <rb@omikron.net>
  13. * @version $Id: DataProvider.php 25893 2010-06-29 08:19:43Z rb $
  14. * @package FACTFinder\Http
  15. */
  16. class FACTFinder_Http_DataProvider extends FACTFinder_Abstract_DataProvider
  17. {
  18. /**
  19. * @var FACTFinder_CurlInterface
  20. */
  21. protected $curl;
  22. protected $data;
  23. /**
  24. * @var FACTFinder_Http_UrlBuilder
  25. */
  26. protected $urlBuilder;
  27. protected $previousUrl = '';
  28. protected $httpHeader = array();
  29. protected $curlOptions = array(
  30. CURLOPT_RETURNTRANSFER => true,
  31. CURLOPT_SSL_VERIFYPEER => false,
  32. CURLOPT_SSL_VERIFYHOST => false
  33. );
  34. protected $lastHttpCode = null;
  35. protected $lastCurlErrno = null;
  36. protected $lastCurlError = null;
  37. function __construct(array $params = null, FACTFinder_Abstract_Configuration $config = null, FACTFinder_Abstract_Logger $log = null, FACTFinder_CurlInterface $curl = null) {
  38. if($curl === null)
  39. {
  40. $curl = FF::getInstance('curl');
  41. }
  42. $this->curl = $curl;
  43. $this->urlBuilder = FF::getInstance('http/urlBuilder', $params, $config, $log);
  44. parent::__construct($params, $config, $log);
  45. $this->setCurlOptions(array(
  46. CURLOPT_CONNECTTIMEOUT => $this->getConfig()->getDefaultConnectTimeout(),
  47. CURLOPT_TIMEOUT => $this->getConfig()->getDefaultTimeout()
  48. ));
  49. }
  50. /**
  51. * sets factfinder params object
  52. *
  53. * @param array params
  54. * @return void
  55. **/
  56. public function setParams(array $params)
  57. {
  58. $this->urlBuilder->setParams($params);
  59. }
  60. /**
  61. * set single param
  62. *
  63. * @param string name
  64. * @param string value
  65. * @return void
  66. **/
  67. public function setParam($name, $value)
  68. {
  69. $this->urlBuilder->setParam($name, $value);
  70. }
  71. /**
  72. * unset single param
  73. *
  74. * @param string name
  75. * @return void
  76. **/
  77. public function unsetParam($name)
  78. {
  79. $this->urlBuilder->unsetParam($name);
  80. }
  81. /**
  82. * set single param with multiple values
  83. *
  84. * @param string name
  85. * @param array of strings values
  86. * @return void
  87. **/
  88. public function setArrayParam($name, $values)
  89. {
  90. $this->urlBuilder->setArrayParam($name, $values);
  91. }
  92. /**
  93. * this implementation of the data provider uses the type as request path in addition to the request context path.
  94. * please ensure that this is the full action name, i.e. "Search.ff"
  95. *
  96. * @param string type
  97. */
  98. public function setType($type)
  99. {
  100. $this->urlBuilder->setAction($type);
  101. }
  102. protected function getType()
  103. {
  104. return $this->urlBuilder->getAction();
  105. }
  106. /**
  107. * @return array
  108. **/
  109. public function getParams()
  110. {
  111. return $this->urlBuilder->getParams();
  112. }
  113. /**
  114. * set a option for a cURL request like described at {@link http://php.net/manual/en/function.curl-setopt.php}.
  115. * The second parameter can be set to false, so the option will not be overwritten if it already exists
  116. *
  117. * @link http://php.net/manual/en/function.curl-setopt.php
  118. * @param the option key (should be a cURL constant)
  119. * @param the option value
  120. * @param boolean whether to overwrite existing options or not. optional, default = true
  121. * @return void
  122. */
  123. public function setCurlOption($option, $value, $overwriteExisting = true) {
  124. if ($overwriteExisting || !isset($this->curlOptions[$option])) {
  125. $this->curlOptions[$option] = $value;
  126. }
  127. }
  128. /**
  129. * Set multiple options for a cURL request like described at {@link http://php.net/manual/en/function.curl-setopt.php}
  130. *
  131. * @link http://php.net/manual/en/function.curl-setopt.php
  132. * @param array of options
  133. * @return void
  134. */
  135. public function setCurlOptions(array $options) {
  136. foreach($options AS $option => $value) {
  137. $this->setCurlOption($option, $value);
  138. }
  139. }
  140. /**
  141. * add an array of HTTP header fields in the format array('Content-type: text/plain', 'Content-length: 100')
  142. *
  143. * @param array $httpHeader
  144. * @return void
  145. */
  146. public function addHttpHeaderFields(array $httpHeader) {
  147. $this->httpHeader = array_merge($this->httpHeader, $httpHeader);
  148. }
  149. /**
  150. * this implementation returns the data as string, no matter what content type set at the http response
  151. *
  152. * @return string data
  153. */
  154. public function getData()
  155. {
  156. if ($this->hasUrlChanged()) {
  157. $this->data = $this->loadResponse();
  158. }
  159. return $this->data;
  160. }
  161. /**
  162. * sets the URL that was used for the most recent request
  163. **/
  164. public function setPreviousUrl($url)
  165. {
  166. $this->previousUrl = $url;
  167. }
  168. /**
  169. * checks whether the URL (and thus the parameters) have changed since last loading the data
  170. **/
  171. public function hasUrlChanged()
  172. {
  173. return $this->urlBuilder->getNonAuthenticationUrl() != $this->previousUrl;
  174. }
  175. /**
  176. * this function sends the request to the server and loads the response data
  177. *
  178. * @throws Exception on connection error
  179. * @return response data
  180. **/
  181. protected function loadResponse()
  182. {
  183. try
  184. {
  185. $this->prepareRequest();
  186. }
  187. catch(NoRequestTypeException $e)
  188. {
  189. return "";
  190. }
  191. $cResource = $this->curl->curl_init();
  192. if (sizeof($this->curlOptions) > 0) {
  193. $this->curl->curl_setopt_array($cResource, $this->curlOptions);
  194. }
  195. $response = $this->curl->curl_exec($cResource);
  196. $this->lastHttpCode = $this->curl->curl_getinfo($cResource, CURLINFO_HTTP_CODE);
  197. $this->lastCurlErrno = $this->curl->curl_errno($cResource);
  198. $this->lastCurlError = $this->curl->curl_error($cResource);
  199. $this->curl->curl_close($cResource);
  200. if (intval($this->lastHttpCode) >= 400) {
  201. $this->log->error("Connection failed. HTTP code: $this->lastHttpCode");
  202. } else if ($this->lastHttpCode == 0) {
  203. $this->log->error("Connection refused. $this->lastCurlError");
  204. } else if (floor(intval($this->lastHttpCode) / 100) == 2) { // all successful status codes (2**)
  205. $this->log->info("Received response!");
  206. }
  207. return $response;
  208. }
  209. /**
  210. * Sets up curl all necessary cURL options (including URL!)
  211. *
  212. * @throws Exception
  213. */
  214. public function prepareRequest()
  215. {
  216. if ($this->getType() === null) {
  217. $this->log->debug("Request type missing.");
  218. throw new NoRequestTypeException('Request type was not set! Cannot send request without knowing the type.');
  219. }
  220. $config = $this->getConfig();
  221. if ($config->getLanguage() != '') {
  222. $this->addHttpHeaderFields(array('Accept-Language: ' . $config->getLanguage()));
  223. }
  224. $url = $this->getAuthenticationUrl();
  225. if ($this->getConfig()->isDebugEnabled()) {
  226. $url .= '&verbose=true';
  227. if (isset($_SERVER['HTTP_REFERER'])) $this->setCurlOption(CURLOPT_REFERER, $_SERVER['HTTP_REFERER'], false);
  228. }
  229. if (!empty($this->httpHeader)) {
  230. $this->setCurlOption(CURLOPT_HTTPHEADER, $this->httpHeader);
  231. }
  232. $this->setCurlOption(CURLOPT_URL, $url);
  233. $this->setPreviousUrl($this->urlBuilder->getNonAuthenticationUrl());
  234. $this->log->info("Trying to send request to " . $url . "...");
  235. }
  236. /**
  237. * this function returns the request url with the correct authentication method (set by the configuration).
  238. *
  239. * @return string url
  240. */
  241. public function getAuthenticationUrl() {
  242. $config = $this->getConfig();
  243. if ($config->isHttpAuthenticationType()) {
  244. $url = $this->urlBuilder->getHttpAuthenticationUrl();
  245. } else if ($config->isSimpleAuthenticationType()) {
  246. $url = $this->urlBuilder->getSimpleAuthenticationUrl();
  247. } else if ($config->isAdvancedAuthenticationType()) {
  248. $url = $this->urlBuilder->getAdvancedAuthenticationUrl();
  249. } else {
  250. $url = $this->urlBuilder->getNonAuthenticationUrl();
  251. }
  252. return $url;
  253. }
  254. public function getNonAuthenticationUrl()
  255. {
  256. return $this->urlBuilder->getNonAuthenticationUrl();
  257. }
  258. public function getLastHttpCode()
  259. {
  260. if($this->lastHttpCode === null)
  261. throw new Exception("Cannot return last HTTP code. No request has been sent.");
  262. return $this->lastHttpCode;
  263. }
  264. public function getLastCurlError()
  265. {
  266. if($this->lastCurlError === null)
  267. throw new Exception("Cannot return last curl error. No request has been sent.");
  268. return $this->lastCurlError;
  269. }
  270. public function getLastCurlErrno()
  271. {
  272. if($this->lastCurlErrno === null)
  273. throw new Exception("Cannot return last curl errno. No request has been sent.");
  274. return $this->lastCurlErrno;
  275. }
  276. }
  277. /**
  278. * @internal
  279. * Exception type needed for data provider
  280. *
  281. * @package FACTFinder\Http
  282. */
  283. class NoRequestTypeException extends Exception {}