選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

function.fetch.php 7.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. <?php
  2. /**
  3. * Smarty plugin
  4. *
  5. * @package Smarty
  6. * @subpackage PluginsFunction
  7. */
  8. /**
  9. * Smarty {fetch} plugin
  10. * Type: function<br>
  11. * Name: fetch<br>
  12. * Purpose: fetch file, web or ftp data and display results
  13. *
  14. * @link http://www.smarty.net/manual/en/language.function.fetch.php {fetch}
  15. * (Smarty online manual)
  16. * @author Monte Ohrt <monte at ohrt dot com>
  17. *
  18. * @param array $params parameters
  19. * @param Smarty_Internal_Template $template template object
  20. *
  21. * @throws SmartyException
  22. * @return string|null if the assign parameter is passed, Smarty assigns the result to a template variable
  23. */
  24. function smarty_function_fetch($params, $template)
  25. {
  26. if (empty($params['file'])) {
  27. trigger_error("[plugin] fetch parameter 'file' cannot be empty", E_USER_NOTICE);
  28. return;
  29. }
  30. // strip file protocol
  31. if (stripos($params['file'], 'file://') === 0) {
  32. $params['file'] = substr($params['file'], 7);
  33. }
  34. $protocol = strpos($params['file'], '://');
  35. if ($protocol !== false) {
  36. $protocol = strtolower(substr($params['file'], 0, $protocol));
  37. }
  38. if (isset($template->smarty->security_policy)) {
  39. if ($protocol) {
  40. // remote resource (or php stream, …)
  41. if (!$template->smarty->security_policy->isTrustedUri($params['file'])) {
  42. return;
  43. }
  44. } else {
  45. // local file
  46. if (!$template->smarty->security_policy->isTrustedResourceDir($params['file'])) {
  47. return;
  48. }
  49. }
  50. }
  51. $content = '';
  52. if ($protocol == 'http') {
  53. // http fetch
  54. if ($uri_parts = parse_url($params['file'])) {
  55. // set defaults
  56. $host = $server_name = $uri_parts['host'];
  57. $timeout = 30;
  58. $accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*";
  59. $agent = "Smarty Template Engine " . Smarty::SMARTY_VERSION;
  60. $referer = "";
  61. $uri = !empty($uri_parts['path']) ? $uri_parts['path'] : '/';
  62. $uri .= !empty($uri_parts['query']) ? '?' . $uri_parts['query'] : '';
  63. $_is_proxy = false;
  64. if (empty($uri_parts['port'])) {
  65. $port = 80;
  66. } else {
  67. $port = $uri_parts['port'];
  68. }
  69. if (!empty($uri_parts['user'])) {
  70. $user = $uri_parts['user'];
  71. }
  72. if (!empty($uri_parts['pass'])) {
  73. $pass = $uri_parts['pass'];
  74. }
  75. // loop through parameters, setup headers
  76. foreach ($params as $param_key => $param_value) {
  77. switch ($param_key) {
  78. case "file":
  79. case "assign":
  80. case "assign_headers":
  81. break;
  82. case "user":
  83. if (!empty($param_value)) {
  84. $user = $param_value;
  85. }
  86. break;
  87. case "pass":
  88. if (!empty($param_value)) {
  89. $pass = $param_value;
  90. }
  91. break;
  92. case "accept":
  93. if (!empty($param_value)) {
  94. $accept = $param_value;
  95. }
  96. break;
  97. case "header":
  98. if (!empty($param_value)) {
  99. if (!preg_match('![\w\d-]+: .+!', $param_value)) {
  100. trigger_error("[plugin] invalid header format '" . $param_value . "'", E_USER_NOTICE);
  101. return;
  102. } else {
  103. $extra_headers[] = $param_value;
  104. }
  105. }
  106. break;
  107. case "proxy_host":
  108. if (!empty($param_value)) {
  109. $proxy_host = $param_value;
  110. }
  111. break;
  112. case "proxy_port":
  113. if (!preg_match('!\D!', $param_value)) {
  114. $proxy_port = (int) $param_value;
  115. } else {
  116. trigger_error("[plugin] invalid value for attribute '" . $param_key . "'", E_USER_NOTICE);
  117. return;
  118. }
  119. break;
  120. case "agent":
  121. if (!empty($param_value)) {
  122. $agent = $param_value;
  123. }
  124. break;
  125. case "referer":
  126. if (!empty($param_value)) {
  127. $referer = $param_value;
  128. }
  129. break;
  130. case "timeout":
  131. if (!preg_match('!\D!', $param_value)) {
  132. $timeout = (int) $param_value;
  133. } else {
  134. trigger_error("[plugin] invalid value for attribute '" . $param_key . "'", E_USER_NOTICE);
  135. return;
  136. }
  137. break;
  138. default:
  139. trigger_error("[plugin] unrecognized attribute '" . $param_key . "'", E_USER_NOTICE);
  140. return;
  141. }
  142. }
  143. if (!empty($proxy_host) && !empty($proxy_port)) {
  144. $_is_proxy = true;
  145. $fp = fsockopen($proxy_host, $proxy_port, $errno, $errstr, $timeout);
  146. } else {
  147. $fp = fsockopen($server_name, $port, $errno, $errstr, $timeout);
  148. }
  149. if (!$fp) {
  150. trigger_error("[plugin] unable to fetch: $errstr ($errno)", E_USER_NOTICE);
  151. return;
  152. } else {
  153. if ($_is_proxy) {
  154. fputs($fp, 'GET ' . $params['file'] . " HTTP/1.0\r\n");
  155. } else {
  156. fputs($fp, "GET $uri HTTP/1.0\r\n");
  157. }
  158. if (!empty($host)) {
  159. fputs($fp, "Host: $host\r\n");
  160. }
  161. if (!empty($accept)) {
  162. fputs($fp, "Accept: $accept\r\n");
  163. }
  164. if (!empty($agent)) {
  165. fputs($fp, "User-Agent: $agent\r\n");
  166. }
  167. if (!empty($referer)) {
  168. fputs($fp, "Referer: $referer\r\n");
  169. }
  170. if (isset($extra_headers) && is_array($extra_headers)) {
  171. foreach ($extra_headers as $curr_header) {
  172. fputs($fp, $curr_header . "\r\n");
  173. }
  174. }
  175. if (!empty($user) && !empty($pass)) {
  176. fputs($fp, "Authorization: BASIC " . base64_encode("$user:$pass") . "\r\n");
  177. }
  178. fputs($fp, "\r\n");
  179. while (!feof($fp)) {
  180. $content .= fgets($fp, 4096);
  181. }
  182. fclose($fp);
  183. $csplit = preg_split("!\r\n\r\n!", $content, 2);
  184. $content = $csplit[1];
  185. if (!empty($params['assign_headers'])) {
  186. $template->assign($params['assign_headers'], preg_split("!\r\n!", $csplit[0]));
  187. }
  188. }
  189. } else {
  190. trigger_error("[plugin fetch] unable to parse URL, check syntax", E_USER_NOTICE);
  191. return;
  192. }
  193. } else {
  194. $content = @file_get_contents($params['file']);
  195. if ($content === false) {
  196. throw new SmartyException("{fetch} cannot read resource '" . $params['file'] . "'");
  197. }
  198. }
  199. if (!empty($params['assign'])) {
  200. $template->assign($params['assign'], $content);
  201. } else {
  202. return $content;
  203. }
  204. }