Completed
Push — master ( d1322e...dc7924 )
by Michael
02:10
created

vcard.php ➔ vcard_quoted_printable_encode()   D

Complexity

Conditions 10
Paths 15

Size

Total Lines 38
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 29
nc 15
nop 2
dl 0
loc 38
rs 4.8196
c 0
b 0
f 0

How to fix   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
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 32 and the first side effect is on line 331.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
/***************************************************************************
3
 *
4
 * PHP vCard class v2.0
5
 * (c) Kai Blankenhorn
6
 * www.bitfolge.de/en
7
 * [email protected]
8
 *
9
 * This program is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU General Public License
11
 * as published by the Free Software Foundation; either version 2
12
 * of the License, or (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program; if not, write to the Free Software
21
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
 ***************************************************************************/
23
24
/***************************************************************************
25
 *
26
 * Modified for WF-Links by McDonald - March 2008
27
 **************************************************************************
28
 * @param $string
29
 * @return mixed
30
 */
31
32
function vcard_encode($string)
33
{
34
    return vcard_escape(vcard_quoted_printable_encode($string));
35
}
36
37
/**
38
 * @param $string
39
 *
40
 * @return mixed
41
 */
42
function vcard_escape($string)
43
{
44
    return str_replace(';', "\;", $string);
45
}
46
47
/**
48
 * @param $email
49
 *
50
 * @return mixed
51
 */
52 View Code Duplication
function vcardemailcnvrt($email)
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
53
{
54
    $search = [
55
        "/\ AT /",
56
        "/\ DOT /",
57
    ];
58
59
    $replace = [
60
        '@',
61
        '.',
62
    ];
63
64
    $text = preg_replace($search, $replace, $email);
65
66
    return $text;
67
}
68
69
// taken from PHP documentation comments
70
/**
71
 * @param     $input
72
 * @param int $line_max
73
 *
74
 * @return string
75
 */
76
function vcard_quoted_printable_encode($input, $line_max = 76)
77
{
78
    $hex       = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'];
79
    $lines     = preg_split("/(?:\r\n|\r|\n)/", $input);
80
    $eol       = "\r\n";
81
    $linebreak = '=0D=0A';
82
    $escape    = '=';
83
    $output    = '';
84
85
    for ($j = 0, $jMax = count($lines); $j < $jMax; ++$j) {
86
        $line    = $lines[$j];
87
        $linlen  = strlen($line);
88
        $newline = '';
89
        for ($i = 0; $i < $linlen; ++$i) {
90
            $c   = substr($line, $i, 1);
91
            $dec = ord($c);
92
            if (($dec == 32) && ($i == ($linlen - 1))) { // convert space at eol only
93
                $c = '=20';
94
            } elseif (($dec == 61) || ($dec < 32)
95
                      || ($dec > 126)) { // always vcard_encode "\t", which is *not* required
96
                $h2 = floor($dec / 16);
97
                $h1 = floor($dec % 16);
98
                $c  = $escape . $hex["$h2"] . $hex["$h1"];
99
            }
100
            if ((strlen($newline) + strlen($c)) >= $line_max) { // CRLF is not counted
101
                $output  .= $newline . $escape . $eol; // soft line break; " =\r\n" is okay
102
                $newline = '    ';
103
            }
104
            $newline .= $c;
105
        } // end of for
106
        $output .= $newline;
107
        if ($j < count($lines) - 1) {
108
            $output .= $linebreak;
109
        }
110
    }
111
112
    return trim($output);
113
}
114
115
/**
116
 * Class VCard
117
 */
118
class VCard
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
119
{
120
    public $properties;
121
    public $filename;
122
123
    /**
124
     * @param        $number
125
     * @param string $type
126
     */
127
    public function setPhoneNumber($number, $type = '')
128
    {
129
        // type may be PREF | WORK | HOME | VOICE | FAX | MSG | CELL | PAGER | BBS | CAR | MODEM | ISDN | VIDEO or any senseful combination, e.g. "PREF;WORK;VOICE"
130
        $key = 'TEL';
131
        if ($type !== '') {
132
            $key .= ';' . $type;
133
        }
134
        $key                    .= ';ENCODING=QUOTED-PRINTABLE';
135
        $this->properties[$key] = vcard_quoted_printable_encode($number);
136
    }
137
138
    // UNTESTED !!!
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
139
140
    /**
141
     * @param $type
142
     * @param $photo
143
     */
144
    public function setPhoto($type, $photo)
145
    { // $type = "GIF" | "JPEG"
0 ignored issues
show
Unused Code Comprehensibility introduced by
40% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
146
        $this->properties["PHOTO;TYPE=$type;ENCODING=BASE64"] = base64_vcard_encode($photo);
147
    }
148
149
    /**
150
     * @param $name
151
     */
152
    public function setFormattedName($name)
153
    {
154
        $this->properties['FN'] = vcard_quoted_printable_encode($name);
155
    }
156
157
    /**
158
     * @param string $family
159
     * @param string $first
160
     * @param string $additional
161
     * @param string $prefix
162
     * @param string $suffix
163
     */
164
    public function setName($family = '', $first = '', $additional = '', $prefix = '', $suffix = '')
165
    {
166
        $this->properties['N'] = "$family;$first;$additional;$prefix;$suffix";
167
        //  $this -> filename = "$first%20$family.vcf";
0 ignored issues
show
Unused Code Comprehensibility introduced by
37% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
168
        if ($this->properties['FN'] === '') {
169
            $this->setFormattedName(trim("$prefix $first $additional $family $suffix"));
170
        }
171
    }
172
173
    /**
174
     * @param $date
175
     */
176
    public function setBirthday($date)
177
    { // $date format is YYYY-MM-DD
178
        $this->properties['BDAY'] = $date;
179
    }
180
181
    /**
182
     * @param string $postoffice
183
     * @param string $extended
184
     * @param string $street
185
     * @param string $city
186
     * @param string $region
187
     * @param string $zip
188
     * @param string $country
189
     * @param string $type
190
     */
191
    public function setAddress(
192
        $postoffice = '',
193
        $extended = '',
194
        $street = '',
195
        $city = '',
196
        $region = '',
197
        $zip = '',
198
        $country = '',
199
        $type = '')
200
    {
201
        // $type may be DOM | INTL | POSTAL | PARCEL | HOME | WORK or any combination of these: e.g. "WORK;PARCEL;POSTAL"
202
        $key = 'ADR';
203
        if ($type !== '') {
204
            $key .= ";$type";
205
        }
206
        $key                    .= ';ENCODING=QUOTED-PRINTABLE';
207
        $this->properties[$key] = vcard_encode($postoffice) . ';' . vcard_encode($extended) . ';' . vcard_encode($street) . ';' . vcard_encode($city) . ';' . vcard_encode($region) . ';' . vcard_encode($zip) . ';' . vcard_encode($country);
208
209
        if ($this->properties["LABEL;$type;ENCODING=QUOTED-PRINTABLE"] === '') {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
210
            //$this->setLabel($postoffice, $extended, $street, $city, $region, $zip, $country, $type);
0 ignored issues
show
Unused Code Comprehensibility introduced by
72% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
211
        }
212
    }
213
214
    /**
215
     * @param string $postoffice
216
     * @param string $extended
217
     * @param string $street
218
     * @param string $city
219
     * @param string $region
220
     * @param string $zip
221
     * @param string $country
222
     * @param string $type
223
     */
224
    public function setLabel(
225
        $postoffice = '',
226
        $extended = '',
227
        $street = '',
228
        $city = '',
229
        $region = '',
230
        $zip = '',
231
        $country = '',
232
        $type = 'HOME;POSTAL')
233
    {
234
        $label = '';
235
        if ($postoffice !== '') {
236
            $label .= "$postoffice\r\n";
237
        }
238
        if ($extended !== '') {
239
            $label .= "$extended\r\n";
240
        }
241
        if ($street !== '') {
242
            $label .= "$street\r\n";
243
        }
244
        if ($zip !== '') {
245
            $label .= "$zip ";
246
        }
247
        if ($city !== '') {
248
            $label .= "$city\r\n";
249
        }
250
        if ($region !== '') {
251
            $label .= "$region\r\n";
252
        }
253
        if ($country !== '') {
254
            $country .= "$country\r\n";
255
        }
256
257
        $this->properties["LABEL;$type;ENCODING=QUOTED-PRINTABLE"] = vcard_quoted_printable_encode($label);
258
    }
259
260
    /**
261
     * @param $address
262
     */
263
    public function setEmail($address)
264
    {
265
        $this->properties['EMAIL;INTERNET'] = $address;
266
    }
267
268
    /**
269
     * @param $note
270
     */
271
    public function setNote($note)
272
    {
273
        $this->properties['NOTE;ENCODING=QUOTED-PRINTABLE'] = vcard_quoted_printable_encode($note);
274
    }
275
276
    /**
277
     * @param        $url
278
     * @param string $type
279
     */
280
    public function setURL($url, $type = '')
281
    {
282
        // $type may be WORK | HOME
283
        $key = 'URL';
284
        if ($type !== '') {
285
            $key .= ";$type";
286
        }
287
        $this->properties[$key] = $url;
288
    }
289
290
    /**
291
     * @param $comp
292
     */
293
    public function setCOMP($comp)
294
    {
295
        $this->filename          = "$comp.vcf";
296
        $this->properties['ORG'] = $comp;
297
    }
298
299
    /**
300
     * @return string
301
     */
302
    public function getVCard()
303
    {
304
        $text = "BEGIN:VCARD\r\n";
305
        $text .= "VERSION:2.1\r\n";
306
        foreach ($this->properties as $key => $value) {
307
            $text .= "$key:$value\r\n";
308
        }
309
        $text .= 'REV:' . date('Y-m-d') . 'T' . date('H:i:s') . "Z\r\n";
310
        $text .= "MAILER:PHP vCard class by Kai Blankenhorn\r\n";
311
        $text .= "END:VCARD\r\n";
312
313
        return $text;
314
    }
315
316
    public function getFileName()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
317
    {
318
        return $this->filename;
319
    }
320
    // NOT TESTED -- McDONALD
321
322
    /**
323
     * @param $charset
324
     */
325
    public function setADR($charset)
326
    {
327
        $this->properties['ADR;CHARSET'] = $charset;
328
    }
329
}
330
331
require_once __DIR__ . '/header.php';
332
333
$lid = WflinksUtility::cleanRequestVars($_REQUEST, 'lid', 0);
334
$lid = (int)$lid;
335
336
global $xoopsDB;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
337
$result    = $xoopsDB->query('SELECT title, street1, street2, town, zip, state, country, url, tel, fax, voip, mobile, email, vat FROM ' . $xoopsDB->prefix('wflinks_links') . ' WHERE lid=' . $lid);
338
$vcard_arr = $xoopsDB->fetchArray($result);
339
340
$title   = $vcard_arr['title'];
341
$street1 = $vcard_arr['street1'];
342
$street2 = $vcard_arr['street2'];
343
$town    = $vcard_arr['town'];
344
$zip     = $vcard_arr['zip'];
345
$state   = $vcard_arr['state'];
346
$country = WflinksUtility::getCountryName($vcard_arr['country']);
347
$tel     = $vcard_arr['tel'];
348
$mobile  = $vcard_arr['mobile'];
349
$fax     = $vcard_arr['fax'];
350
$voip    = $vcard_arr['voip'];
351
$url     = $vcard_arr['url'];
352
$email   = $vcard_arr['email'];
353
$vat     = $vcard_arr['vat'];
354
$charset = _CHARSET;
355
356
$v = new VCard();
357
358
// Set Xoops Character set
359
$v->setADR($charset);
360
361
// Phone number(s)
362
$v->setPhoneNumber($tel, 'WORK;VOICE;PREF');
363
$v->setPhoneNumber($mobile, 'WORK;CELL');
364
$v->setPhoneNumber($fax, 'WORK;FAX');
365
$v->setPhoneNumber($voip, 'WORK;PCS');
366
367
// Name
368
$v->setName('', '', '', '');
369
370
// Birthday
0 ignored issues
show
Unused Code Comprehensibility introduced by
47% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
371
// $v -> setBirthday("1960-07-31");
372
373
// Address
374
$street = $street1;
375
if ($street2) {
376
    $street = $street1 . ', ' . $street2;
377
}
378
$v->setAddress('', '', $street, $town, $state, $zip, $country, 'WORK');
379
380
// Email
381
$emailaddr = vcardemailcnvrt($email);
382
$v->setEmail($emailaddr);
383
384
// Note
0 ignored issues
show
Unused Code Comprehensibility introduced by
47% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
385
// $v -> setNote("You can take some notes here.\r\nMultiple lines are supported via \\r\\n.");
386
if ($voip) {
387
    $v->setNote('VoIP: ' . $voip);
388
}
389
if ($vat) {
390
    $v->setNote(_MD_WFL_VAT . $vat);
391
}
392
393
// Website
394
$v->setURL($url, 'WORK');
395
396
// Company name
397
$v->setCOMP($title);
398
399
$output   = $v->getVCard();
400
$filename = $v->getFileName();
401
402
header("Content-Disposition: attachment; filename=$filename");
403
header('Content-Length: ' . strlen($output));
404
header('Connection: close');
405
header("Content-Type: text/x-vCard; name=$filename");
406
407
echo $output;
408