Completed
Push — master ( b62e39...9cdd75 )
by Richard
11:38
created

function.fetch.php ➔ smarty_function_fetch()   F

Complexity

Conditions 55
Paths > 20000

Size

Total Lines 195
Code Lines 141

Duplication

Lines 47
Ratio 24.1 %
Metric Value
cc 55
eloc 141
nc 32957
nop 2
dl 47
loc 195
rs 2

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Smarty plugin
4
 * @package Smarty
5
 * @subpackage plugins
6
 */
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
 * @link http://smarty.php.net/manual/en/language.function.fetch.php {fetch}
16
 *       (Smarty online manual)
17
 * @author Monte Ohrt <monte at ohrt dot com>
18
 * @param array
19
 * @param Smarty
20
 * @return string|null if the assign parameter is passed, Smarty assigns the
21
 *                     result to a template variable
22
 */
23
function smarty_function_fetch($params, &$smarty)
24
{
25
    if (empty($params['file'])) {
26
        $smarty->_trigger_fatal_error("[plugin] parameter 'file' cannot be empty");
27
        return;
28
    }
29
30
    $content = '';
31
    if ($smarty->security && !preg_match('!^(http|ftp)://!i', $params['file'])) {
32
        $_params = array('resource_type' => 'file', 'resource_name' => $params['file']);
33
        require_once(SMARTY_CORE_DIR . 'core.is_secure.php');
34
        if(!smarty_core_is_secure($_params, $smarty)) {
35
            $smarty->_trigger_fatal_error('[plugin] (secure mode) fetch \'' . $params['file'] . '\' is not allowed');
36
            return;
37
        }
38
        
39
        // fetch the file
40 View Code Duplication
        if($fp = @fopen($params['file'],'r')) {
41
            while(!feof($fp)) {
42
                $content .= fgets ($fp,4096);
43
            }
44
            fclose($fp);
45
        } else {
46
            $smarty->_trigger_fatal_error('[plugin] fetch cannot read file \'' . $params['file'] . '\'');
47
            return;
48
        }
49
    } else {
50
        // not a local file
51
        if(preg_match('!^http://!i',$params['file'])) {
52
            // http fetch
53
            if($uri_parts = parse_url($params['file'])) {
54
                // set defaults
55
                $host = $server_name = $uri_parts['host'];
56
                $timeout = 30;
57
                $accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*";
58
                $agent = "Smarty Template Engine ".$smarty->_version;
59
                $referer = "";
60
                $uri = !empty($uri_parts['path']) ? $uri_parts['path'] : '/';
61
                $uri .= !empty($uri_parts['query']) ? '?' . $uri_parts['query'] : '';
62
                $_is_proxy = false;
63
                if(empty($uri_parts['port'])) {
64
                    $port = 80;
65
                } else {
66
                    $port = $uri_parts['port'];
67
                }
68
                if(!empty($uri_parts['user'])) {
69
                    $user = $uri_parts['user'];
70
                }
71
                if(!empty($uri_parts['pass'])) {
72
                    $pass = $uri_parts['pass'];
73
                }
74
                // loop through parameters, setup headers
75
                foreach($params as $param_key => $param_value) {
76
                    switch($param_key) {
77
                        case "file":
78
                        case "assign":
79
                        case "assign_headers":
80
                            break;
81
                        case "user":
82
                            if(!empty($param_value)) {
83
                                $user = $param_value;
84
                            }
85
                            break;
86
                        case "pass":
87
                            if(!empty($param_value)) {
88
                                $pass = $param_value;
89
                            }
90
                            break;
91
                        case "accept":
92
                            if(!empty($param_value)) {
93
                                $accept = $param_value;
94
                            }
95
                            break;
96 View Code Duplication
                        case "header":
97
                            if(!empty($param_value)) {
98
                                if(!preg_match('![\w\d-]+: .+!',$param_value)) {
99
                                    $smarty->_trigger_fatal_error("[plugin] invalid header format '".$param_value."'");
100
                                    return;
101
                                } else {
102
                                    $extra_headers[] = $param_value;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$extra_headers was never initialized. Although not strictly required by PHP, it is generally a good practice to add $extra_headers = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
103
                                }
104
                            }
105
                            break;
106
                        case "proxy_host":
107
                            if(!empty($param_value)) {
108
                                $proxy_host = $param_value;
109
                            }
110
                            break;
111 View Code Duplication
                        case "proxy_port":
112
                            if(!preg_match('!\D!', $param_value)) {
113
                                $proxy_port = (int) $param_value;
114
                            } else {
115
                                $smarty->_trigger_fatal_error("[plugin] invalid value for attribute '".$param_key."'");
116
                                return;
117
                            }
118
                            break;
119
                        case "agent":
120
                            if(!empty($param_value)) {
121
                                $agent = $param_value;
122
                            }
123
                            break;
124
                        case "referer":
125
                            if(!empty($param_value)) {
126
                                $referer = $param_value;
127
                            }
128
                            break;
129 View Code Duplication
                        case "timeout":
130
                            if(!preg_match('!\D!', $param_value)) {
131
                                $timeout = (int) $param_value;
132
                            } else {
133
                                $smarty->_trigger_fatal_error("[plugin] invalid value for attribute '".$param_key."'");
134
                                return;
135
                            }
136
                            break;
137
                        default:
138
                            $smarty->_trigger_fatal_error("[plugin] unrecognized attribute '".$param_key."'");
139
                            return;
140
                    }
141
                }
142
                if(!empty($proxy_host) && !empty($proxy_port)) {
143
                    $_is_proxy = true;
144
                    $fp = fsockopen($proxy_host,$proxy_port,$errno,$errstr,$timeout);
145
                } else {
146
                    $fp = fsockopen($server_name,$port,$errno,$errstr,$timeout);
147
                }
148
149
                if(!$fp) {
150
                    $smarty->_trigger_fatal_error("[plugin] unable to fetch: $errstr ($errno)");
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
179
                    fputs($fp, "\r\n");
180
                    while(!feof($fp)) {
181
                        $content .= fgets($fp,4096);
182
                    }
183
                    fclose($fp);
184
                    $csplit = preg_split("!\r\n\r\n!",$content,2);
185
186
                    $content = $csplit[1];
187
188
                    if(!empty($params['assign_headers'])) {
189
                        $smarty->assign($params['assign_headers'],preg_split("!\r\n!",$csplit[0]));
190
                    }
191
                }
192
            } else {
193
                $smarty->_trigger_fatal_error("[plugin] unable to parse URL, check syntax");
194
                return;
195
            }
196 View Code Duplication
        } else {
197
            // ftp fetch
198
            if($fp = @fopen($params['file'],'r')) {
199
                while(!feof($fp)) {
200
                    $content .= fgets ($fp,4096);
201
                }
202
                fclose($fp);
203
            } else {
204
                $smarty->_trigger_fatal_error('[plugin] fetch cannot read file \'' . $params['file'] .'\'');
205
                return;
206
            }
207
        }
208
209
    }
210
211
212
    if (!empty($params['assign'])) {
213
        $smarty->assign($params['assign'],$content);
214
    } else {
215
        return $content;
216
    }
217
}
218
219
/* vim: set expandtab: */
220
221
?>
0 ignored issues
show
Best Practice introduced by
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...
222