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

function.mailto.php ➔ smarty_function_mailto()   F

Complexity

Conditions 24
Paths 937

Size

Total Lines 112
Code Lines 73

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 24
eloc 73
nc 937
nop 2
dl 0
loc 112
rs 2.248

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 {mailto} function plugin
11
 *
12
 * Type:     function<br>
13
 * Name:     mailto<br>
14
 * Date:     May 21, 2002
15
 * Purpose:  automate mailto address link creation, and optionally
16
 *           encode them.<br>
17
 * Input:<br>
18
 *         - address = e-mail address
19
 *         - text = (optional) text to display, default is address
20
 *         - encode = (optional) can be one of:
21
 *                * none : no encoding (default)
22
 *                * javascript : encode with javascript
23
 *                * javascript_charcode : encode with javascript charcode
24
 *                * hex : encode with hexidecimal (no javascript)
25
 *         - cc = (optional) address(es) to carbon copy
26
 *         - bcc = (optional) address(es) to blind carbon copy
27
 *         - subject = (optional) e-mail subject
28
 *         - newsgroups = (optional) newsgroup(s) to post to
29
 *         - followupto = (optional) address(es) to follow up to
30
 *         - extra = (optional) extra tags for the href link
31
 *
32
 * Examples:
33
 * <pre>
34
 * {mailto address="[email protected]"}
35
 * {mailto address="[email protected]" encode="javascript"}
36
 * {mailto address="[email protected]" encode="hex"}
37
 * {mailto address="[email protected]" subject="Hello to you!"}
38
 * {mailto address="[email protected]" cc="[email protected],[email protected]"}
39
 * {mailto address="[email protected]" extra='class="mailto"'}
40
 * </pre>
41
 * @link http://smarty.php.net/manual/en/language.function.mailto.php {mailto}
42
 *          (Smarty online manual)
43
 * @version  1.2
44
 * @author   Monte Ohrt <monte at ohrt dot com>
45
 * @author   credits to Jason Sweat (added cc, bcc and subject functionality)
46
 * @param    array
47
 * @param    Smarty
48
 * @return   string
0 ignored issues
show
Documentation introduced by
Should the return type not be null|string?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
49
 */
50
function smarty_function_mailto($params, &$smarty)
51
{
52
    $extra = '';
53
54
    if (empty($params['address'])) {
55
        $smarty->trigger_error("mailto: missing 'address' parameter");
56
        return;
57
    } else {
58
        $address = $params['address'];
59
    }
60
61
    $text = $address;
62
63
    // netscape and mozilla do not decode %40 (@) in BCC field (bug?)
64
    // so, don't encode it.
65
    $search = array('%40', '%2C');
66
    $replace  = array('@', ',');
67
    $mail_parms = array();
68
    foreach ($params as $var=>$value) {
69
        switch ($var) {
70
            case 'cc':
71
            case 'bcc':
72
            case 'followupto':
73
                if (!empty($value))
74
                    $mail_parms[] = $var.'='.str_replace($search,$replace,rawurlencode($value));
75
                break;
76
                
77
            case 'subject':
78
            case 'newsgroups':
79
                $mail_parms[] = $var.'='.rawurlencode($value);
80
                break;
81
82
            case 'extra':
83
            case 'text':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
84
                $$var = $value;
85
86
            default:
87
        }
88
    }
89
90
    $mail_parm_vals = '';
91
    for ($i=0; $i<count($mail_parms); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
92
        $mail_parm_vals .= (0==$i) ? '?' : '&';
93
        $mail_parm_vals .= $mail_parms[$i];
94
    }
95
    $address .= $mail_parm_vals;
96
97
    $encode = (empty($params['encode'])) ? 'none' : $params['encode'];
98
    if (!in_array($encode,array('javascript','javascript_charcode','hex','none')) ) {
99
        $smarty->trigger_error("mailto: 'encode' parameter must be none, javascript or hex");
100
        return;
101
    }
102
103
    if ($encode == 'javascript' ) {
104
        $string = 'document.write(\'<a href="mailto:'.$address.'" '.$extra.'>'.$text.'</a>\');';
105
106
        $js_encode = '';
107
        for ($x=0; $x < strlen($string); $x++) {
108
            $js_encode .= '%' . bin2hex($string[$x]);
109
        }
110
111
        return '<script type="text/javascript">eval(unescape(\''.$js_encode.'\'))</script>';
112
113
    } elseif ($encode == 'javascript_charcode' ) {
114
        $string = '<a href="mailto:'.$address.'" '.$extra.'>'.$text.'</a>';
115
116
        for($x = 0, $y = strlen($string); $x < $y; $x++ ) {
117
            $ord[] = ord($string[$x]);   
0 ignored issues
show
Coding Style Comprehensibility introduced by
$ord was never initialized. Although not strictly required by PHP, it is generally a good practice to add $ord = 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...
118
        }
119
120
        $_ret = "<script type=\"text/javascript\" language=\"javascript\">\n";
121
        $_ret .= "<!--\n";
122
        $_ret .= "{document.write(String.fromCharCode(";
123
        $_ret .= implode(',',$ord);
0 ignored issues
show
Bug introduced by
The variable $ord does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
124
        $_ret .= "))";
125
        $_ret .= "}\n";
126
        $_ret .= "//-->\n";
127
        $_ret .= "</script>\n";
128
        
129
        return $_ret;
130
        
131
        
132
    } elseif ($encode == 'hex') {
133
134
        preg_match('!^(.*)(\?.*)$!',$address,$match);
135
        if(!empty($match[2])) {
136
            $smarty->trigger_error("mailto: hex encoding does not work with extra attributes. Try javascript.");
137
            return;
138
        }
139
        $address_encode = '';
140
        for ($x=0; $x < strlen($address); $x++) {
141
            if(preg_match('!\w!',$address[$x])) {
142
                $address_encode .= '%' . bin2hex($address[$x]);
143
            } else {
144
                $address_encode .= $address[$x];
145
            }
146
        }
147
        $text_encode = '';
148
        for ($x=0; $x < strlen($text); $x++) {
149
            $text_encode .= '&#x' . bin2hex($text[$x]).';';
150
        }
151
152
        $mailto = "&#109;&#97;&#105;&#108;&#116;&#111;&#58;";
153
        return '<a href="'.$mailto.$address_encode.'" '.$extra.'>'.$text_encode.'</a>';
154
155
    } else {
156
        // no encoding
157
        return '<a href="mailto:'.$address.'" '.$extra.'>'.$text.'</a>';
158
159
    }
160
161
}
162
163
/* vim: set expandtab: */
164
165
?>
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...
166