source: trunk/include/smarty/libs/plugins/function.fetch.php @ 23384

Last change on this file since 23384 was 23384, checked in by rvelices, 11 years ago

smarty 3 - first pass for tests

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