VCardContactWriter   A
last analyzed

Complexity

Total Complexity 28

Size/Duplication

Total Lines 247
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 28
eloc 99
c 1
b 0
f 0
dl 0
loc 247
rs 10

14 Methods

Rating   Name   Duplication   Size   Complexity  
A buildName() 0 15 1
A endBuffer() 0 4 1
A buildOrganization() 0 11 1
A buildMailaddresses() 0 9 2
A buildAddresses() 0 20 4
A startBuffer() 0 4 1
A buildPhoneNumbers() 0 13 3
A __construct() 0 3 1
A buildData() 0 17 1
A buildHomepages() 0 9 2
A __toString() 0 3 1
A buildPhoto() 0 17 4
A buildCategories() 0 11 2
A buildAdditionalData() 0 22 4
1
<?php
2
declare(strict_types=1);
3
4
namespace SKien\VCard;
5
6
/**
7
 * Helper class that builds the string buffer for one contact in the VCard format.
8
 *
9
 * @package VCard
10
 * @author Stefanius <[email protected]>
11
 * @copyright MIT License - see the LICENSE file for details
12
 * @internal
13
 */
14
class VCardContactWriter
15
{
16
    use VCardHelper;
17
18
    /** @var VCardContact the contact to write     */
19
    protected VCardContact $oContact;
20
    /** @var string internal buffer     */
21
    protected string $buffer = '';
22
23
    /**
24
     * Create a contact writer object.
25
     * @param VCardContact $oContact    the contact to build
26
     */
27
    function __construct(VCardContact $oContact)
28
    {
29
        $this->oContact = $oContact;
30
    }
31
32
    /**
33
     * Return internal string buffer.
34
     * @return string
35
     */
36
    public function __toString() : string
37
    {
38
        return $this->buildData();
39
    }
40
41
    /**
42
     * Build the contact as VCard compatible string.
43
     * @return string
44
     */
45
    public function buildData() : string
46
    {
47
        $this->startBuffer();
48
49
        $this->buffer .= $this->buildName();
50
        $this->buffer .= $this->buildOrganization();
51
        $this->buffer .= $this->buildAddresses();
52
        $this->buffer .= $this->buildPhoneNumbers();
53
        $this->buffer .= $this->buildMailaddresses();
54
        $this->buffer .= $this->buildHomepages();
55
        $this->buffer .= $this->buildAdditionalData();
56
        $this->buffer .= $this->buildCategories();
57
        $this->buffer .= $this->buildPhoto();
58
59
        $this->endBuffer();
60
61
        return $this->buffer;
62
    }
63
64
    /**
65
     * Create the start sequence.
66
     */
67
    protected function startBuffer() : void
68
    {
69
        $this->buffer = 'BEGIN:VCARD' . PHP_EOL;
70
        $this->buffer .= 'VERSION:3.0' . PHP_EOL;
71
    }
72
73
    /**
74
     * Create the end sequence.
75
     */
76
    protected function endBuffer() : void
77
    {
78
        // END
79
        $this->buffer .= 'END:VCARD' . PHP_EOL;
80
    }
81
82
    /**
83
     * Build all name relevant contact properties.
84
     * @return string
85
     */
86
    protected function buildName() : string
87
    {
88
        // name properties
89
        // family name; given name; additional name(s); honorific prefixes; honorific sufffixes
90
        $strName  = $this->maskString($this->oContact->getLastName()) . ';';
91
        $strName .= $this->maskString($this->oContact->getFirstName()) . ';';
92
        $strName .= ';';
93
        $strName .= $this->maskString($this->oContact->getPrefix()) . ';';
94
        $strName .= $this->maskString($this->oContact->getSuffix());
95
96
        $buffer = $this->buildProperty('N', $strName, false);
97
        $buffer .= $this->buildProperty('FN', $this->oContact->getName());
98
        $buffer .= $this->buildProperty('NICKNAME', $this->oContact->getNickName());
99
100
        return $buffer;
101
    }
102
103
    /**
104
     * Build all organization relevant contact properties.
105
     * @return string
106
     */
107
    protected function buildOrganization() : string
108
    {
109
        // organisation
110
        $strOrg  = $this->maskString($this->oContact->getOrganisation()) . ';';
111
        $strOrg .= $this->maskString($this->oContact->getSection());
112
113
        $buffer = $this->buildProperty('ORG', $strOrg, false);
114
        $buffer .= $this->buildProperty('TITLE', $this->oContact->getPosition());
115
        $buffer .= $this->buildProperty('ROLE', $this->oContact->getRole());
116
117
        return $buffer;
118
    }
119
120
    /**
121
     * Build all addresses.
122
     * @return string
123
     */
124
    protected function buildAddresses() : string
125
    {
126
        // addresses
127
        $buffer = '';
128
        $iCnt = $this->oContact->getAddressCount();
129
        $iPref = 0;
130
        for ($i = 0; $i < $iCnt; $i++) {
131
            $oAddress = $this->oContact->getAddress($i);
132
            if ($oAddress) {
133
                $buffer .= $oAddress->buildFullAddress();
134
                $buffer .= $oAddress->buildLabel();
135
                if ($oAddress->isPreferred()) {
136
                    $iPref = $i;
137
                }
138
            }
139
        }
140
        // set preferred address also as default postal address for MS
141
        $buffer .= $this->buildProperty('X-MS-OL-DEFAULT-POSTAL-ADDRESS', (string)($iPref + 1));
142
143
        return $buffer;
144
    }
145
146
    /**
147
     * Build all phone numbers.
148
     * @return string
149
     */
150
    protected function buildPhoneNumbers() : string
151
    {
152
        // phone numbers
153
        $buffer = '';
154
        $iCnt = $this->oContact->getPhoneCount();
155
        for ($i = 0; $i < $iCnt; $i++) {
156
            $aPhone = $this->oContact->getPhone($i);
157
            if ($aPhone) {
158
                $strName = 'TEL;TYPE=' . $aPhone['strType'];
159
                $buffer .= $this->buildProperty($strName, $aPhone['strPhone']);
160
            }
161
        }
162
        return $buffer;
163
    }
164
165
    /**
166
     * Build all e-mail addresses.
167
     * @return string
168
     */
169
    protected function buildMailaddresses() : string
170
    {
171
        // mailaddresses
172
        $buffer = '';
173
        $iCnt = $this->oContact->getEMailCount();
174
        for ($i = 0; $i < $iCnt; $i++) {
175
            $buffer .= $this->buildProperty('EMAIL;TYPE=INTERNET', $this->oContact->getEMail($i));
176
        }
177
        return $buffer;
178
    }
179
180
    /**
181
     * Build all homepages.
182
     * @return string
183
     */
184
    protected function buildHomepages() : string
185
    {
186
        // homepages
187
        $buffer = '';
188
        $iCnt = $this->oContact->getHomepageCount();
189
        for ($i = 0; $i < $iCnt; $i++) {
190
            $buffer .= $this->buildProperty('URL;TYPE=WORK', $this->oContact->getHomepage($i));
191
        }
192
        return $buffer;
193
    }
194
195
    /**
196
     * Build all additional properties.
197
     * @return string
198
     */
199
    protected function buildAdditionalData() : string
200
    {
201
        // personal data
202
        $buffer = $this->buildProperty('BDAY', /** @scrutinizer ignore-type */ $this->oContact->getDateOfBirth()); // @phpstan-ignore-line
203
        $strGender = $this->oContact->getGender();
204
        if (strlen($strGender) > 0) {
205
            if ($strGender == 'M') {
206
                $buffer .= $this->buildProperty('X-WAB-GENDER', '1');
207
                $buffer .= $this->buildProperty('X-GENDER', 'Female');
208
            } else if ($strGender == 'F') {
209
                $buffer .= $this->buildProperty('X-WAB-GENDER', '2');
210
                $buffer .= $this->buildProperty('X-GENDER', 'Male');
211
            } else {
212
                $buffer .= $this->buildProperty('X-WAB-GENDER', '9');
213
                $buffer .= $this->buildProperty('X-GENDER', 'Unknown');
214
            }
215
            $buffer .= $this->buildProperty('GENDER', $strGender);
216
        }
217
        // annotation
218
        $buffer .= $this->buildProperty('NOTE', $this->oContact->getNote());
219
220
        return $buffer;
221
    }
222
223
    /**
224
     * Build all categories.
225
     * @return string
226
     */
227
    protected function buildCategories() : string
228
    {
229
        // categories
230
        $iCnt = $this->oContact->getCategoriesCount();
231
        $strSep = '';
232
        $strValue = '';
233
        for ($i = 0; $i < $iCnt; $i++) {
234
            $strValue .= $strSep . $this->maskString($this->oContact->getCategory($i));
235
            $strSep = ',';
236
        }
237
        return $this->buildProperty('CATEGORIES', $strValue, false);
238
    }
239
240
    /**
241
     * Build the photo.
242
     * @return string
243
     */
244
    protected function buildPhoto() : string
245
    {
246
        // photo
247
        $buffer = '';
248
        $blobPortrait = $this->oContact->getPortraitBlob();
249
        if (strlen($blobPortrait) > 0) {
250
            // extract image type from binary data
251
            $strType = '';
252
            $strImage = '';
253
            $this->parseImageData($blobPortrait, $strType, $strImage);
254
            if (strlen($strType) > 0 && strlen($strImage) > 0) {
255
                $strName = 'PHOTO;TYPE=' . $strType . ';ENCODING=B';
256
                $buffer .= $this->buildProperty($strName, $strImage, false);
257
                $buffer .= PHP_EOL; // even though in vcard 3.0 spec blank line after binary value no longer is requires, MS Outlook need it...
258
            }
259
        }
260
        return $buffer;
261
    }
262
}