Completed
Push — vcard ( 1c7030 )
by mw
05:55 queued 30s
created

vCard::__construct()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 26
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 26
rs 8.8571
c 0
b 0
f 0
cc 1
eloc 22
nc 1
nop 3
1
<?php
2
3
namespace SRF\vCard;
4
5
use Title;
6
use Article;
7
8
/**
9
 * Represents a single entry in an vCard
10
 *
11
 * @see http://www.semantic-mediawiki.org/wiki/vCard
12
 *
13
 * @license GNU GPL v2+
14
 * @since 1.5
15
 *
16
 * @author Markus Krötzsch
17
 * @author Denny Vrandecic
18
 * @author Frank Dengler
19
 */
20
class vCard {
21
22
	/**
23
	 * @var string
24
	 */
25
	private $uri;
26
27
	/**
28
	 * @var string
29
	 */
30
	private $text;
31
32
	/**
33
	 * @var string
34
	 */
35
	private $vcard = [];
36
37
	/**
38
	 * @var boolean
39
	 */
40
	private $isPublic = true;
41
42
	/**
43
	 * @var integer
44
	 */
45
	private $timestamp;
46
47
	/**
48
	 * @since 3.0
49
	 *
50
	 * @param string $uri
51
	 * @param string $text
52
	 * @param array $vcard
53
	 */
54
	public function __construct( $uri, $text, array $vcard ) {
55
		$this->uri = $uri;
56
		$this->text = $text;
57
58
		$default = [
59
			'prefix' => '',
60
			'firstname' => '',
61
			'lastname' => '',
62
			'additionalname' => '',
63
			'suffix' => '',
64
			'fullname' => '',
65
			'tel' => [],
66
			'address' => [],
67
			'email' => [],
68
			'birthday' => '',
69
			'title' => '',
70
			'role' => '',
71
			'organization' => '',
72
			'department' => '',
73
			'category' => '',
74
			'url' => '',
75
			'note' => ''
76
		];
77
78
		$this->vcard = $vcard + $default;
0 ignored issues
show
Documentation Bug introduced by
It seems like $vcard + $default of type array is incompatible with the declared type string of property $vcard.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
79
	}
80
81
	/**
82
	 * @since 3.0
83
	 *
84
	 * @param boolean $isPublic
85
	 */
86
	public function isPublic( $isPublic ) {
87
		$this->isPublic = $isPublic;
88
	}
89
90
	/**
91
	 * @since 3.0
92
	 *
93
	 * @param integer $timestamp
94
	 */
95
	public function setTimestamp( $timestamp ) {
96
		$this->timestamp = $timestamp;
97
	}
98
99
	/**
100
	 * Creates the vCard output for a single item.
101
	 *
102
	 * @return string
103
	 */
104
	public function text() {
105
106
		$vcard = $this->prepareCard( $this->vcard );
107
108
		$text  = "BEGIN:VCARD\r\n";
109
		$text .= "VERSION:3.0\r\n";
110
111
		// N and FN are required properties in vCard 3.0, we need to write something there
112
		$text .= "N;CHARSET=UTF-8:" .
113
			$vcard['lastname'] . ';' .
114
			$vcard['firstname'] . ';' .
115
			$vcard['additionalname'] . ';' .
116
			$vcard['prefix'] . ';' .
117
			$vcard['suffix'] . "\r\n";
118
119
		$text .= "FN;CHARSET=UTF-8:" .
120
			$vcard['label'] . "\r\n";
121
122
		$text .= ( $this->isPublic ? 'CLASS:PUBLIC':'CLASS:CONFIDENTIAL' ) . "\r\n";
123
124
		if ( $vcard['birthday'] !== "" ) {
125
			$text .= "BDAY:" . $vcard['birthday'] ."\r\n";
126
		}
127
128
		if ( $vcard['title'] !== "" ) {
129
			$text .= "TITLE;CHARSET=UTF-8:" . $vcard['title'] ."\r\n";
130
		}
131
132
		if ( $vcard['role'] !== "" ) {
133
			$text .= "ROLE;CHARSET=UTF-8:" . $vcard['role'] ."\r\n";
134
		}
135
136
		if ( $vcard['organization'] !== "" ) {
137
			$text .= "ORG;CHARSET=UTF-8:" . $vcard['organization'] . ';' . $vcard['department'] ."\r\n";
138
		}
139
140
		if ( $vcard['category'] !== "" ) {
141
			$text .= "CATEGORIES;CHARSET=UTF-8:" . $vcard['category'] ."\r\n";
142
		}
143
144
		foreach ( $vcard['email'] as $e ) {
145
			$text .= $e->text();
146
		}
147
148
		foreach ( $vcard['address'] as $a ) {
149
			$text .= $a->text();
150
		}
151
152
		foreach ( $vcard['tel'] as $t ) {
153
			$text .= $t->text();
154
		}
155
156
		if ( $vcard['note'] !== "" ) {
157
			$text .= "NOTE;CHARSET=UTF-8:" . $vcard['note'] ."\r\n";
158
		}
159
160
		$text .= "SOURCE;CHARSET=UTF-8:$this->uri\r\n";
161
162
		// The identifier for the product that created the vCard object
163
		$text .= "PRODID:-////Semantic MediaWiki\r\n";
164
165
		// A timestamp for the last time the vCard was updated
166
		$text .= "REV:$this->timestamp\r\n";
167
168
		// A URL pointing to a website that represents the person in some way
169
		$text .= "URL:" . ( $vcard['url'] !== "" ? $vcard['url'] : $this->uri ) . "\r\n";
170
171
		// Specifies a value that represents a persistent, globally unique
172
		// identifier associated with the object.
173
		$text .= "UID:$this->uri\r\n";
174
		$text .= "END:VCARD\r\n";
175
176
		return $text;
177
	}
178
179
	public static function escape( $text ) {
180
		return str_replace( [ '\\', ',', ':', ';' ], [ '\\\\', '\,', '\:', '\;' ], $text );
181
	}
182
183
	private function prepareCard( $vcard ) {
184
185
		$vcard['label'] = '';
186
187
		$additionalname = $vcard['additionalname'];
188
189
		// Read fullname or guess it in a simple way from other names that are
190
		// given
191
		if ( $vcard['fullname'] != '' ) {
192
			$vcard['label'] = $vcard['fullname'];
193
		} elseif ( $vcard['firstname'] . $vcard['lastname'] != '' ) {
194
			$vcard['label'] = $vcard['firstname'] . ( ( ( $vcard['firstname'] != '' ) && ( $vcard['lastname'] != '' ) ) ? ' ':'' ) . $vcard['lastname'];
195
		} else {
196
			$vcard['label'] = $this->text;
197
		}
198
199
		$vcard['label'] = self::escape( $vcard['label'] );
200
201
		// read firstname and lastname, or guess it from other names that are given
202
		if ( $vcard['firstname'] . $vcard['lastname'] == '' ) { // guessing needed
203
			$nameparts = explode( ' ', $vcard['label'] );
204
			// Accepted forms for guessing:
205
			// "Lastname"
206
			// "Firstname Lastname"
207
			// "Firstname <Additionalnames> Lastname"
208
			$vcard['lastname'] = self::escape( array_pop( $nameparts ) );
209
210
			if ( count( $nameparts ) > 0 ) {
211
				$vcard['firstname'] = self::escape( array_shift( $nameparts ) );
212
			}
213
214
			foreach ( $nameparts as $name ) {
215
				$vcard['additionalname'] .= ( $vcard['additionalname'] != '' ? ',':'' ) . self::escape( $name );
216
			}
217
		} else {
218
			$vcard['firstname'] = self::escape( $vcard['firstname'] );
219
			$vcard['lastname'] = self::escape( $vcard['lastname'] );
220
		}
221
222
 		// no escape, can be a value list
223
		if ( $additionalname != '' ) {
224
			$vcard['additionalname'] = $additionalname;
225
		}
226
227
		$vcard['prefix'] = self::escape( $vcard['prefix'] );
228
		$vcard['suffix'] = self::escape( $vcard['suffix'] );
229
		$vcard['title'] = self::escape( $vcard['title'] );
230
		$vcard['role'] = self::escape( $vcard['role'] );
231
		$vcard['organization'] = self::escape( $vcard['organization'] );
232
		$vcard['department'] = self::escape( $vcard['department'] );
233
		$vcard['note'] = self::escape( $vcard['note'] );
234
235
		return $vcard;
236
	}
237
238
}
239