PageRenderTime 27ms CodeModel.GetById 39ms RepoModel.GetById 0ms app.codeStats 0ms

/sites/all/modules/contrib/civicrm/vendor/electrolinux/phpquery/phpQuery/phpQuery/plugins/WebBrowser.php

https://gitlab.com/virtualrealms/d7civicrm
PHP | 436 lines | 302 code | 6 blank | 128 comment | 73 complexity | 33f86b5b6023de92d8f23c6923a2f5ac MD5 | raw file
  1. <?php
  2. /**
  3. * WebBrowser plugin.
  4. *
  5. */
  6. class phpQueryObjectPlugin_WebBrowser {
  7. /**
  8. * Limit binded methods to specified ones.
  9. *
  10. * @var array
  11. */
  12. public static $phpQueryMethods = null;
  13. /**
  14. * Enter description here...
  15. *
  16. * @param phpQueryObject $self
  17. * @todo support 'reset' event
  18. */
  19. public static function WebBrowser($self, $callback = null, $location = null) {
  20. $self = $self->_clone()->toRoot();
  21. $location = $location
  22. ? $location
  23. // TODO use document.location
  24. : $self->document->xhr->getUri(true);
  25. // FIXME tmp
  26. $self->document->WebBrowserCallback = $callback;
  27. if (! $location)
  28. throw new Exception('Location needed to activate WebBrowser plugin !');
  29. else {
  30. $self->bind('click', array($location, $callback), array('phpQueryPlugin_WebBrowser', 'hadleClick'));
  31. $self->bind('submit', array($location, $callback), array('phpQueryPlugin_WebBrowser', 'handleSubmit'));
  32. }
  33. }
  34. public static function browser($self, $callback = null, $location = null) {
  35. return $self->WebBrowser($callback, $location);
  36. }
  37. public static function downloadTo($self, $dir = null, $filename = null) {
  38. $url = null;
  39. if ($self->is('a[href]'))
  40. $url = $self->attr('href');
  41. else if ($self->find('a')->length)
  42. $url = $self->find('a')->attr('href');
  43. if ($url) {
  44. $url = resolve_url($self->document->location, $url);
  45. if (! $dir)
  46. $dir = getcwd();
  47. // TODO resolv name from response headers
  48. if (! $filename) {
  49. $matches = null;
  50. preg_match('@/([^/]+)$@', $url, $matches);
  51. $filename = $matches[1];
  52. }
  53. //print $url;
  54. $path = rtrim($dir, '/').'/'.$filename;
  55. phpQuery::debug("Requesting download of $url\n");
  56. // TODO use AJAX instead of file_get_contents
  57. file_put_contents($path, file_get_contents($url));
  58. }
  59. return $self;
  60. }
  61. /**
  62. * Method changing browser location.
  63. * Fires callback registered with WebBrowser(), if any.
  64. * @param $self
  65. * @param $url
  66. * @return unknown_type
  67. */
  68. public static function location($self, $url = null) {
  69. // TODO if ! $url return actual location ???
  70. $xhr = isset($self->document->xhr)
  71. ? $self->document->xhr
  72. : null;
  73. $xhr = phpQuery::ajax(array(
  74. 'url' => $url,
  75. ), $xhr);
  76. $return = false;
  77. if ($xhr->getLastResponse()->isSuccessful()) {
  78. $return = phpQueryPlugin_WebBrowser::browserReceive($xhr);
  79. if (isset($self->document->WebBrowserCallback))
  80. phpQuery::callbackRun(
  81. $self->document->WebBrowserCallback,
  82. array($return)
  83. );
  84. }
  85. return $return;
  86. }
  87. public static function download($self, $url = null) {
  88. $xhr = isset($self->document->xhr)
  89. ? $self->document->xhr
  90. : null;
  91. $xhr = phpQuery::ajax(array(
  92. 'url' => $url,
  93. ), $xhr);
  94. $return = false;
  95. if ($xhr->getLastResponse()->isSuccessful()) {
  96. $return = phpQueryPlugin_WebBrowser::browserDownload($xhr);
  97. if (isset($self->document->WebBrowserCallback))
  98. phpQuery::callbackRun(
  99. $self->document->WebBrowserCallback,
  100. array($return)
  101. );
  102. }
  103. return $return;
  104. }
  105. }
  106. class phpQueryPlugin_WebBrowser {
  107. /**
  108. *
  109. * @param $url
  110. * @param $callback
  111. * @param $param1
  112. * @param $param2
  113. * @param $param3
  114. * @return Zend_Http_Client
  115. */
  116. public static function browserGet($url, $callback,
  117. $param1 = null, $param2 = null, $param3 = null) {
  118. phpQuery::debug("[WebBrowser] GET: $url");
  119. self::authorizeHost($url);
  120. $xhr = phpQuery::ajax(array(
  121. 'type' => 'GET',
  122. 'url' => $url,
  123. 'dataType' => 'html',
  124. ));
  125. $paramStructure = null;
  126. if (func_num_args() > 2) {
  127. $paramStructure = func_get_args();
  128. $paramStructure = array_slice($paramStructure, 2);
  129. }
  130. if ($xhr->getLastResponse()->isSuccessful()) {
  131. phpQuery::callbackRun($callback,
  132. array(self::browserReceive($xhr)->WebBrowser()),
  133. $paramStructure
  134. );
  135. // phpQuery::callbackRun($callback, array(
  136. // self::browserReceive($xhr)//->WebBrowser($callback)
  137. // ));
  138. return $xhr;
  139. } else {
  140. throw new Exception("[WebBrowser] GET request failed; url: $url");
  141. return false;
  142. }
  143. }
  144. /**
  145. *
  146. * @param $url
  147. * @param $data
  148. * @param $callback
  149. * @param $param1
  150. * @param $param2
  151. * @param $param3
  152. * @return Zend_Http_Client
  153. */
  154. public static function browserPost($url, $data, $callback,
  155. $param1 = null, $param2 = null, $param3 = null) {
  156. self::authorizeHost($url);
  157. $xhr = phpQuery::ajax(array(
  158. 'type' => 'POST',
  159. 'url' => $url,
  160. 'dataType' => 'html',
  161. 'data' => $data,
  162. ));
  163. $paramStructure = null;
  164. if (func_num_args() > 3) {
  165. $paramStructure = func_get_args();
  166. $paramStructure = array_slice($paramStructure, 3);
  167. }
  168. if ($xhr->getLastResponse()->isSuccessful()) {
  169. phpQuery::callbackRun($callback,
  170. array(self::browserReceive($xhr)->WebBrowser()),
  171. $paramStructure
  172. );
  173. // phpQuery::callbackRun($callback, array(
  174. // self::browserReceive($xhr)//->WebBrowser($callback)
  175. // ));
  176. return $xhr;
  177. } else
  178. return false;
  179. }
  180. /**
  181. *
  182. * @param $ajaxSettings
  183. * @param $callback
  184. * @param $param1
  185. * @param $param2
  186. * @param $param3
  187. * @return Zend_Http_Client
  188. */
  189. public static function browser($ajaxSettings, $callback,
  190. $param1 = null, $param2 = null, $param3 = null) {
  191. self::authorizeHost($ajaxSettings['url']);
  192. $xhr = phpQuery::ajax(
  193. self::ajaxSettingsPrepare($ajaxSettings)
  194. );
  195. $paramStructure = null;
  196. if (func_num_args() > 2) {
  197. $paramStructure = func_get_args();
  198. $paramStructure = array_slice($paramStructure, 2);
  199. }
  200. if ($xhr->getLastResponse()->isSuccessful()) {
  201. phpQuery::callbackRun($callback,
  202. array(self::browserReceive($xhr)->WebBrowser()),
  203. $paramStructure
  204. );
  205. // phpQuery::callbackRun($callback, array(
  206. // self::browserReceive($xhr)//->WebBrowser($callback)
  207. // ));
  208. return $xhr;
  209. } else
  210. return false;
  211. }
  212. protected static function authorizeHost($url) {
  213. $host = parse_url($url, PHP_URL_HOST);
  214. if ($host)
  215. phpQuery::ajaxAllowHost($host);
  216. }
  217. protected static function ajaxSettingsPrepare($settings) {
  218. unset($settings['success']);
  219. unset($settings['error']);
  220. return $settings;
  221. }
  222. /**
  223. * @param Zend_Http_Client $xhr
  224. */
  225. public static function browserReceive($xhr) {
  226. phpQuery::debug("[WebBrowser] Received from ".$xhr->getUri(true));
  227. // TODO handle meta redirects
  228. $body = $xhr->getLastResponse()->getBody();
  229. // XXX error ???
  230. if (strpos($body, '<!doctype html>') !== false) {
  231. $body = '<html>'
  232. .str_replace('<!doctype html>', '', $body)
  233. .'</html>';
  234. }
  235. $pq = phpQuery::newDocument($body);
  236. $pq->document->xhr = $xhr;
  237. $pq->document->location = $xhr->getUri(true);
  238. $refresh = $pq->find('meta[http-equiv=refresh]')
  239. ->add('meta[http-equiv=Refresh]');
  240. if ($refresh->size()) {
  241. // print htmlspecialchars(var_export($xhr->getCookieJar()->getAllCookies(), true));
  242. // print htmlspecialchars(var_export($xhr->getLastResponse()->getHeader('Set-Cookie'), true));
  243. phpQuery::debug("Meta redirect... '{$refresh->attr('content')}'\n");
  244. // there is a refresh, so get the new url
  245. $content = $refresh->attr('content');
  246. $urlRefresh = substr($content, strpos($content, '=')+1);
  247. $urlRefresh = trim($urlRefresh, '\'"');
  248. // XXX not secure ?!
  249. phpQuery::ajaxAllowURL($urlRefresh);
  250. // $urlRefresh = urldecode($urlRefresh);
  251. // make ajax call, passing last $xhr object to preserve important stuff
  252. $xhr = phpQuery::ajax(array(
  253. 'type' => 'GET',
  254. 'url' => $urlRefresh,
  255. 'dataType' => 'html',
  256. ), $xhr);
  257. if ($xhr->getLastResponse()->isSuccessful()) {
  258. // if all is ok, repeat this method...
  259. return call_user_func_array(
  260. array('phpQueryPlugin_WebBrowser', 'browserReceive'), array($xhr)
  261. );
  262. }
  263. } else
  264. return $pq;
  265. }
  266. /**
  267. * @param Zend_Http_Client $xhr
  268. */
  269. public static function browserDownload($xhr) {
  270. phpQuery::debug("[WebBrowser] Received from ".$xhr->getUri(true));
  271. // TODO handle meta redirects
  272. $body = $xhr->getLastResponse()->getBody();
  273. return $body;
  274. }
  275. /**
  276. *
  277. * @param $e
  278. * @param $callback
  279. * @return unknown_type
  280. */
  281. public static function hadleClick($e, $callback = null) {
  282. $node = phpQuery::pq($e->target);
  283. $type = null;
  284. if ($node->is('a[href]')) {
  285. // TODO document.location
  286. $xhr = isset($node->document->xhr)
  287. ? $node->document->xhr
  288. : null;
  289. $xhr = phpQuery::ajax(array(
  290. 'url' => resolve_url($e->data[0], $node->attr('href')),
  291. 'referer' => $node->document->location,
  292. ), $xhr);
  293. if ((! $callback || !($callback instanceof Callback)) && $e->data[1])
  294. $callback = $e->data[1];
  295. if ($xhr->getLastResponse()->isSuccessful() && $callback)
  296. phpQuery::callbackRun($callback, array(
  297. self::browserReceive($xhr)
  298. ));
  299. } else if ($node->is(':submit') && $node->parents('form')->size())
  300. $node->parents('form')->trigger('submit', array($e));
  301. }
  302. /**
  303. * Enter description here...
  304. *
  305. * @param unknown_type $e
  306. * @TODO trigger submit for form after form's submit button has a click event
  307. */
  308. public static function handleSubmit($e, $callback = null) {
  309. $node = phpQuery::pq($e->target);
  310. if (!$node->is('form') || !$node->is('[action]'))
  311. return;
  312. // TODO document.location
  313. $xhr = isset($node->document->xhr)
  314. ? $node->document->xhr
  315. : null;
  316. $submit = pq($e->relatedTarget)->is(':submit')
  317. ? $e->relatedTarget
  318. // will this work ?
  319. // : $node->find(':submit:first')->get(0);
  320. : $node->find('*:submit:first')->get(0);
  321. $data = array();
  322. foreach($node->serializeArray($submit) as $r)
  323. // XXXt.c maybe $node->not(':submit')->add($sumit) would be better ?
  324. // foreach($node->serializeArray($submit) as $r)
  325. $data[ $r['name'] ] = $r['value'];
  326. $options = array(
  327. 'type' => $node->attr('method')
  328. ? $node->attr('method')
  329. : 'GET',
  330. 'url' => resolve_url($e->data[0], $node->attr('action')),
  331. 'data' => $data,
  332. 'referer' => $node->document->location,
  333. // 'success' => $e->data[1],
  334. );
  335. if ($node->attr('enctype'))
  336. $options['contentType'] = $node->attr('enctype');
  337. $xhr = phpQuery::ajax($options, $xhr);
  338. if ((! $callback || !($callback instanceof Callback)) && $e->data[1])
  339. $callback = $e->data[1];
  340. if ($xhr->getLastResponse()->isSuccessful() && $callback)
  341. phpQuery::callbackRun($callback, array(
  342. self::browserReceive($xhr)
  343. ));
  344. }
  345. }
  346. /**
  347. *
  348. * @param unknown_type $parsed
  349. * @return unknown
  350. * @link http://www.php.net/manual/en/function.parse-url.php
  351. * @author stevenlewis at hotmail dot com
  352. */
  353. function glue_url($parsed)
  354. {
  355. if (! is_array($parsed)) return false;
  356. $uri = isset($parsed['scheme']) ? $parsed['scheme'].':'.((strtolower($parsed['scheme']) == 'mailto') ? '':'//'): '';
  357. $uri .= isset($parsed['user']) ? $parsed['user'].($parsed['pass']? ':'.$parsed['pass']:'').'@':'';
  358. $uri .= isset($parsed['host']) ? $parsed['host'] : '';
  359. $uri .= isset($parsed['port']) ? ':'.$parsed['port'] : '';
  360. if(isset($parsed['path']))
  361. {
  362. $uri .= (substr($parsed['path'],0,1) == '/')?$parsed['path']:'/'.$parsed['path'];
  363. }
  364. $uri .= isset($parsed['query']) ? '?'.$parsed['query'] : '';
  365. $uri .= isset($parsed['fragment']) ? '#'.$parsed['fragment'] : '';
  366. return $uri;
  367. }
  368. /**
  369. * Enter description here...
  370. *
  371. * @param unknown_type $base
  372. * @param unknown_type $url
  373. * @return unknown
  374. * @author adrian-php at sixfingeredman dot net
  375. */
  376. function resolve_url($base, $url) {
  377. if (!strlen($base)) return $url;
  378. // Step 2
  379. if (!strlen($url)) return $base;
  380. // Step 3
  381. if (preg_match('!^[a-z]+:!i', $url)) return $url;
  382. $base = parse_url($base);
  383. if ($url{0} == "#") {
  384. // Step 2 (fragment)
  385. $base['fragment'] = substr($url, 1);
  386. return unparse_url($base);
  387. }
  388. unset($base['fragment']);
  389. unset($base['query']);
  390. if (substr($url, 0, 2) == "//") {
  391. // Step 4
  392. return unparse_url(array(
  393. 'scheme'=>$base['scheme'],
  394. 'path'=>substr($url,2),
  395. ));
  396. } else if ($url{0} == "/") {
  397. // Step 5
  398. $base['path'] = $url;
  399. } else {
  400. // Step 6
  401. $path = explode('/', $base['path']);
  402. $url_path = explode('/', $url);
  403. // Step 6a: drop file from base
  404. array_pop($path);
  405. // Step 6b, 6c, 6e: append url while removing "." and ".." from
  406. // the directory portion
  407. $end = array_pop($url_path);
  408. foreach ($url_path as $segment) {
  409. if ($segment == '.') {
  410. // skip
  411. } else if ($segment == '..' && $path && $path[sizeof($path)-1] != '..') {
  412. array_pop($path);
  413. } else {
  414. $path[] = $segment;
  415. }
  416. }
  417. // Step 6d, 6f: remove "." and ".." from file portion
  418. if ($end == '.') {
  419. $path[] = '';
  420. } else if ($end == '..' && $path && $path[sizeof($path)-1] != '..') {
  421. $path[sizeof($path)-1] = '';
  422. } else {
  423. $path[] = $end;
  424. }
  425. // Step 6h
  426. $base['path'] = join('/', $path);
  427. }
  428. // Step 7
  429. return glue_url($base);
  430. }