Passed
Branch develop (4336b1)
by
unknown
85:39
created

vCard::buildVCardString()   C

Complexity

Conditions 11
Paths 260

Size

Total Lines 73
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 11
eloc 40
nc 260
nop 3
dl 0
loc 73
rs 5.7333
c 0
b 0
f 0

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
use Splash\Tests\WsObjects\O00ObjectBaseTest;
0 ignored issues
show
Bug introduced by
The type Splash\Tests\WsObjects\O00ObjectBaseTest was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
3
use JMS\Serializer\Exception\ObjectConstructionException;
0 ignored issues
show
Bug introduced by
The type JMS\Serializer\Exception...ctConstructionException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
4
5
/* Copyright (C)           Kai Blankenhorn      <[email protected]>
6
 * Copyright (C) 2005-2017 Laurent Destailleur  <[email protected]>
7
 * Copyright (C) 2020		Tobias Sekan		<[email protected]>
8
 *
9
 * This program is free software; you can redistribute it and/or modify
10
 * it under the terms of the GNU General Public License as published by
11
 * the Free Software Foundation; either version 3 of the License, or
12
 * (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, see <https://www.gnu.org/licenses/>.
21
 */
22
23
/**
24
 *	\file       htdocs/core/class/vcard.class.php
25
 *	\brief      Class to manage vCard files
26
 */
27
28
29
/**
30
 * Encode a string for vCard
31
 *
32
 * @param	string	$string		String to encode
33
 * @return	string				String encoded
34
 */
35
function encode($string)
36
{
37
	return str_replace(";", "\;", (dol_quoted_printable_encode(utf8_decode($string))));
38
}
39
40
41
/**
42
 * Taken from php documentation comments
43
 * No more used
44
 *
45
 * @param	string	$input		String
46
 * @param	int		$line_max	Max length of lines
47
 * @return	string				Encoded string
48
 */
49
function dol_quoted_printable_encode($input, $line_max = 76)
50
{
51
	$hex = array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F');
52
	$lines = preg_split("/(\?:\r\n|\r|\n)/", $input);
53
	$eol = "\r\n";
54
	$linebreak = "=0D=0A";
55
	$escape = "=";
56
	$output = "";
57
58
	$num = count($lines);
59
	for ($j = 0; $j < $num; $j++) {
60
		$line = $lines[$j];
61
		$linlen = strlen($line);
62
		$newline = "";
63
		for ($i = 0; $i < $linlen; $i++) {
64
			$c = substr($line, $i, 1);
65
			$dec = ord($c);
66
			if (($dec == 32) && ($i == ($linlen - 1))) { // convert space at eol only
67
				$c = "=20";
68
			} elseif (($dec == 61) || ($dec < 32) || ($dec > 126)) { // always encode "\t", which is *not* required
69
				$h2 = floor($dec / 16);
70
				$h1 = floor($dec % 16);
71
				$c = $escape.$hex["$h2"].$hex["$h1"];
72
			}
73
			if ((strlen($newline) + strlen($c)) >= $line_max) { // CRLF is not counted
74
				$output .= $newline.$escape.$eol; // soft line break; " =\r\n" is okay
75
				$newline = "    ";
76
			}
77
			$newline .= $c;
78
		} // end of for
79
		$output .= $newline;
80
		if ($j < count($lines) - 1) {
81
			$output .= $linebreak;
82
		}
83
	}
84
	return trim($output);
85
}
86
87
88
/**
89
 *	Class to buld vCard files
90
 */
91
class vCard
92
{
93
	/**
94
	 * @var array array of properties
95
	 */
96
	public $properties;
97
98
	/**
99
	 * @var string filename
100
	 */
101
	public $filename;
102
103
	/**
104
	 * @var string encoding
105
	 */
106
	public $encoding = "ISO-8859-1;ENCODING=QUOTED-PRINTABLE";
107
108
109
	/**
110
	 *  mise en forme du numero de telephone
111
	 *
112
	 *  @param	int		$number		numero de telephone
113
	 *  @param	string	$type		Type
114
	 *  @return	void
115
	 */
116
	public function setPhoneNumber($number, $type = "")
117
	{
118
		// 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"
119
		$key = "TEL";
120
		if ($type != "") {
121
			$key .= ";".$type;
122
		}
123
		$key .= ";CHARSET=".$this->encoding;
124
		$this->properties[$key] = encode($number);
125
	}
126
127
	/**
128
	 *	mise en forme de la photo
129
	 *  warning NON TESTE !
130
	 *
131
	 *  @param  string  $type			Type
132
	 *  @param  string  $photo			Photo
133
	 *  @return	void
134
	 */
135
	public function setPhoto($type, $photo)
136
	{
137
		// $type = "GIF" | "JPEG"
138
		$this->properties["PHOTO;TYPE=$type;ENCODING=BASE64"] = base64_encode($photo);
139
	}
140
141
	/**
142
	 *	mise en forme du nom formate
143
	 *
144
	 *	@param	string	$name			Name
145
	 *	@return	void
146
	 */
147
	public function setFormattedName($name)
148
	{
149
		$this->properties["FN;CHARSET=".$this->encoding] = encode($name);
150
	}
151
152
	/**
153
	 *	mise en forme du nom complet
154
	 *
155
	 *	@param	string	$family			Family name
156
	 *	@param	string	$first			First name
157
	 *	@param	string	$additional		Additional (e.g. second name, nick name)
158
	 *	@param	string	$prefix			Prefix (e.g. "Mr.", "Ms.", "Prof.")
159
	 *	@param	string	$suffix			Suffix (e.g. "sen." for senior, "jun." for junior)
160
	 *	@return	void
161
	 */
162
	public function setName($family = "", $first = "", $additional = "", $prefix = "", $suffix = "")
163
	{
164
		$this->properties["N;CHARSET=".$this->encoding] = encode($family).";".encode($first).";".encode($additional).";".encode($prefix).";".encode($suffix);
165
		$this->filename = "$first%20$family.vcf";
166
		if (empty($this->properties["FN"])) {
167
			$this->setFormattedName(trim("$prefix $first $additional $family $suffix"));
168
		}
169
	}
170
171
	/**
172
	 *	mise en forme de l'anniversaire
173
	 *
174
	 *	@param	integer	  $date		Date
175
	 *	@return	void
176
	 */
177
	public function setBirthday($date)
178
	{
179
		// $date format is YYYY-MM-DD - RFC 2425 and RFC 2426
180
		$this->properties["BDAY"] = dol_print_date($date, 'dayrfc');
181
	}
182
183
	/**
184
	 *	mise en forme de l'adresse
185
	 *
186
	 *	@param	string	$postoffice		Postoffice
187
	 *	@param	string	$extended		Extended
188
	 *	@param	string	$street			Street
189
	 *	@param	string	$city			City
190
	 *	@param	string	$region			Region
191
	 *	@param	string	$zip			Zip
192
	 *	@param	string	$country		Country
193
	 *	@param	string	$type			Type
194
	 *	@return	void
195
	 */
196
	public function setAddress($postoffice = "", $extended = "", $street = "", $city = "", $region = "", $zip = "", $country = "", $type = "HOME;POSTAL")
197
	{
198
		// $type may be DOM | INTL | POSTAL | PARCEL | HOME | WORK or any combination of these: e.g. "WORK;PARCEL;POSTAL"
199
		$key = "ADR";
200
		if ($type != "") {
201
			$key .= ";".$type;
202
		}
203
		$key .= ";CHARSET=".$this->encoding;
204
		$this->properties[$key] = ";".encode($extended).";".encode($street).";".encode($city).";".encode($region).";".encode($zip).";".encode($country);
205
206
		//if ($this->properties["LABEL;".$type.";CHARSET=".$this->encoding] == '') {
207
			//$this->setLabel($postoffice, $extended, $street, $city, $region, $zip, $country, $type);
208
		//}
209
	}
210
211
	/**
212
	 *  mise en forme du label
213
	 *
214
	 *  @param	string	$postoffice		Postoffice
215
	 *  @param	string	$extended		Extended
216
	 *  @param	string	$street			Street
217
	 *  @param	string	$city			City
218
	 *  @param	string	$region			Region
219
	 *  @param	string	$zip			Zip
220
	 *  @param	string	$country		Country
221
	 *  @param	string	$type			Type
222
	 *  @return	void
223
	 */
224
	public function setLabel($postoffice = "", $extended = "", $street = "", $city = "", $region = "", $zip = "", $country = "", $type = "HOME;POSTAL")
225
	{
226
		$label = "";
227
		if ($postoffice != "") {
228
			$label .= "$postoffice\r\n";
229
		}
230
		if ($extended != "") {
231
			$label .= "$extended\r\n";
232
		}
233
		if ($street != "") {
234
			$label .= "$street\r\n";
235
		}
236
		if ($zip != "") {
237
			$label .= "$zip ";
238
		}
239
		if ($city != "") {
240
			$label .= "$city\r\n";
241
		}
242
		if ($region != "") {
243
			$label .= "$region\r\n";
244
		}
245
		if ($country != "") {
246
			$country .= "$country\r\n";
247
		}
248
249
		$this->properties["LABEL;$type;CHARSET=".$this->encoding] = encode($label);
250
	}
251
252
	/**
253
	 *	Add a e-mail address to this vCard
254
	 *
255
	 *	@param	string	$address		E-mail address
256
	 *	@param	string	$type			(optional) The type of the e-mail (typical "PREF;INTERNET" or "INTERNET")
257
	 *	@return	void
258
	 */
259
	public function setEmail($address, $type = "TYPE=INTERNET;PREF")
260
	{
261
		$key = "EMAIL";
262
		if ($type != "") {
263
			$key .= ";".$type;
264
		}
265
		$this->properties[$key] = $address;
266
	}
267
268
	/**
269
	 *	mise en forme de la note
270
	 *
271
	 *	@param	string	$note		Note
272
	 *	@return	void
273
	 */
274
	public function setNote($note)
275
	{
276
		$this->properties["NOTE;CHARSET=".$this->encoding] = encode($note);
277
	}
278
279
	/**
280
	 * 	mise en forme de la fonction
281
	 *
282
	 *	@param	string	$title		Title
283
	 *	@return	void
284
	 */
285
	public function setTitle($title)
286
	{
287
		$this->properties["TITLE;CHARSET=".$this->encoding] = encode($title);
288
	}
289
290
291
	/**
292
	 *  mise en forme de la societe
293
	 *
294
	 *  @param	string	$org		Org
295
	 *  @return	void
296
	 */
297
	public function setOrg($org)
298
	{
299
		$this->properties["ORG;CHARSET=".$this->encoding] = encode($org);
300
	}
301
302
303
	/**
304
	 * 	mise en forme du logiciel generateur
305
	 *
306
	 *  @param	string	$prodid		Prodid
307
	 *	@return	void
308
	 */
309
	public function setProdId($prodid)
310
	{
311
		$this->properties["PRODID;CHARSET=".$this->encoding] = encode($prodid);
312
	}
313
314
315
	/**
316
	 * 	mise en forme du logiciel generateur
317
	 *
318
	 *  @param	string	$uid	Uid
319
	 *	@return	void
320
	 */
321
	public function setUID($uid)
322
	{
323
		$this->properties["UID;CHARSET=".$this->encoding] = encode($uid);
324
	}
325
326
327
	/**
328
	 *  mise en forme de l'url
329
	 *
330
	 *	@param	string	$url		URL
331
	 *  @param	string	$type		Type
332
	 *	@return	void
333
	 */
334
	public function setURL($url, $type = "")
335
	{
336
		// $type may be WORK | HOME
337
		$key = "URL";
338
		if ($type != "") {
339
			$key .= ";$type";
340
		}
341
		$this->properties[$key] = $url;
342
	}
343
344
	/**
345
	 *  permet d'obtenir une vcard
346
	 *
347
	 *  @return	string
348
	 */
349
	public function getVCard()
350
	{
351
		$text = "BEGIN:VCARD\r\n";
352
		$text .= "VERSION:3.0\r\n";
353
		//$text.= "VERSION:2.1\r\n";
354
		foreach ($this->properties as $key => $value) {
355
			$text .= "$key:$value\r\n";
356
		}
357
		$text .= "REV:".date("Y-m-d")."T".date("H:i:s")."Z\r\n";
358
		$text .= "MAILER: Dolibarr\r\n";
359
		$text .= "END:VCARD\r\n";
360
		return $text;
361
	}
362
363
	/**
364
	 *  permet d'obtenir le nom de fichier
365
	 *
366
	 *  @return	string		Filename
367
	 */
368
	public function getFileName()
369
	{
370
		return $this->filename;
371
	}
372
373
	/**
374
	 * Return a VCARD string
375
	 *
376
	 * @param	Object		$object		Object
377
	 * @param	Societe		$company	Company
378
	 * @param	Translate	$langs		Lang object
379
	 * @return	string					String
380
	 */
381
	public function buildVCardString($object, $company, $langs)
382
	{
383
		$this->setProdId('Dolibarr '.DOL_VERSION);
384
385
		$this->setUid('DOLIBARR-USERID-'.$object->id);
386
		$this->setName($object->lastname, $object->firstname, "", $object->civility_code, "");
387
		$this->setFormattedName($object->getFullName($langs, 1));
388
389
		$this->setPhoneNumber($object->office_phone, "TYPE=WORK;VOICE");
390
		$this->setPhoneNumber($object->personal_mobile, "TYPE=HOME;VOICE");
391
		$this->setPhoneNumber($object->user_mobile, "TYPE=CELL;VOICE");
392
		$this->setPhoneNumber($object->office_fax, "TYPE=WORK;FAX");
393
394
		$country = $object->country_code ? $object->country : '';
395
396
		$this->setAddress("", "", $object->address, $object->town, $object->state, $object->zip, $country, "TYPE=WORK;POSTAL");
397
		$this->setLabel("", "", $object->address, $object->town, $object->state, $object->zip, $country, "TYPE=WORK");
398
399
		$this->setEmail($object->email, "TYPE=WORK");
400
		$this->setNote($object->note_public);
401
		$this->setTitle($object->job);
402
403
		if ($company->id > 0) {
404
			$this->setURL($company->url, "TYPE=WORK");
405
			if (!$object->office_phone) {
406
				$this->setPhoneNumber($company->phone, "TYPE=WORK;VOICE");
407
			}
408
			if (!$object->office_fax) {
409
				$this->setPhoneNumber($company->fax, "TYPE=WORK;FAX");
410
			}
411
			if (!$object->zip) {
412
				$this->setAddress("", "", $company->address, $company->town, $company->state, $company->zip, $company->country, "TYPE=WORK;POSTAL");
413
			}
414
415
			// when company e-mail is empty, use only user e-mail
416
			if (empty(trim($company->email))) {
417
				// was set before, don't set twice
418
			} elseif (empty(trim($object->email))) {
419
				// when user e-mail is empty, use only company e-mail
420
				$this->setEmail($company->email, "TYPE=WORK");
421
			} else {
422
				$tmpuser2 = explode("@", trim($object->email));
423
				$tmpcompany = explode("@", trim($company->email));
424
425
				if (strtolower(end($tmpuser2)) == strtolower(end($tmpcompany))) {
426
					// when e-mail domain of user and company are the same, use user e-mail at first (and company e-mail at second)
427
					$this->setEmail($object->email, "TYPE=WORK");
428
429
					// support by Microsoft Outlook (2019 and possible earlier)
430
					$this->setEmail($company->email, 'INTERNET');
431
				} else {
432
					// when e-mail of user and company complete different use company e-mail at first (and user e-mail at second)
433
					$this->setEmail($company->email, "TYPE=WORK");
434
435
					// support by Microsoft Outlook (2019 and possible earlier)
436
					$this->setEmail($object->email, 'INTERNET');
437
				}
438
			}
439
440
			// Si user lie a un tiers non de type "particulier"
441
			if ($company->typent_code != 'TE_PRIVATE') {
442
				$this->setOrg($company->name);
443
			}
444
		}
445
446
		// Personal informations
447
		$this->setPhoneNumber($object->personal_mobile, "TYPE=HOME;VOICE");
448
		if ($object->birth) {
449
			$this->setBirthday($object->birth);
450
		}
451
452
		// Return VCard string
453
		return $this->getVCard();
454
	}
455
456
457
	/* Example from Microsoft Outlook 2019
458
459
	BEGIN:VCARD
460
	VERSION:2.1
461
462
	N;LANGUAGE=de:surename;forename;secondname;Sir;jun.
463
	FN:Sir surename secondname forename jun.
464
	ORG:Companyname
465
	TITLE:position
466
	TEL;WORK;VOICE:work-phone-number
467
	TEL;HOME;VOICE:private-phone-number
468
	TEL;CELL;VOICE:mobile-phone-number
469
	TEL;WORK;FAX:fax-phone-number
470
	ADR;WORK;PREF:;;street and number;town;region;012345;Deutschland
471
	LABEL;WORK;PREF;ENCODING=QUOTED-PRINTABLE:street and number=0D=0A=
472
	=0D=0A=
473
	012345  town  region
474
	X-MS-OL-DEFAULT-POSTAL-ADDRESS:2
475
	URL;WORK:www.mywebpage.de
476
	EMAIL;PREF;INTERNET:[email protected]
477
	EMAIL;INTERNET:[email protected]
478
	EMAIL;INTERNET:[email protected]
479
	X-MS-IMADDRESS:[email protected]
480
	REV:20200424T104242Z
481
482
	END:VCARD
483
	*/
484
}
485