Completed
Push — master ( 1650a0...29e43d )
by mw
06:30
created

vCard   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 231
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 91.46%

Importance

Changes 0
Metric Value
wmc 28
lcom 1
cbo 0
dl 0
loc 231
ccs 75
cts 82
cp 0.9146
rs 10
c 0
b 0
f 0

7 Methods

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