vobject
vobject copied to clipboard
Updating a telefone number with specific type
Hi everybody,
I have a vcard with: TEL;TYPE=work:+49 123 TEL;TYPE=home:+49 234 TEL;TYPE=cell:+49 345
I know that I can delete the object with: unset($vcard->TEL);
I know that I can walk through the elements with: foreach($vcard->TEL as $tel) echo $tel['TYPE'] .": ". $tel;
But how can I update for example only the telefonenumber with type="home". I checked the functions in the Component.php but I can not figure out how it works...
Is it necessary to save all elements, unset the complete TEL Object and then to recreate it with the other objects? Is there a simpler way?
Can anybody help me? Best regards Christoph
Hi again, I made some progress, but I am still not happy with it. So please give me feedback if my code could be simplified.
Here is my vcard:
BEGIN:VCARD VERSION:3.0 PRODID:-//Inverse inc.//SOGo Connector 1.0//EN UID:C790FF67-B850-0001-36F9-11D11E30E490.vcf N:adfadf;ABCDE;;; FN:ABCDE adfadf ORG:Company XYZ;Abteilung TEL;TYPE=work:123 TEL;TYPE=home:234 TEL;TYPE=cell:34 END:VCARD
Now I want to update only the TEL;TYPE=home Number. As Evert Pot writes in the docs it is never a good idea to delete entries and to recreate because it could delete customer data. So how can I update this single value?
First I thought it would be simple as: $vcard->{'TEL;TYPE=home'} but unfortunately that is not working.
Adding like $vcard->add('TEL', '234234234', ['TYPE' => 'home']) is also not working because it adds another entry without deleting the old one.
Now I use the following code:
<?php
// check if there is a TEL-entry. If not, just add it.
if ( !isset($vcard->TEL ) ){
$vcard->add('TEL', '234234234', ['type' => 'home']);
}
else{
// load old values
foreach($vcard->TEL as $tel)
$tmp['tel'][(string)$tel['TYPE']] = $tel;
// write my values
$tmp['tel']['work'] = "234234234";
// delete all TEL-entries
unset($vcard->TEL);
// write new tel-entries
foreach($tmp['tel'] as $key => $value)
$vcard->add('TEL', $value, ['type' => $key]);
}
is there no simpler way? If I even think further to vcard->ADR it gets even more complecated because I have multiple parts as value... Is there no simpler way? Best regards Christoph
Hi Christoph,
Here's a simple way using loops:
foreach($vcard->TEL as $tel) {
if (!$tel['TYPE']->has('home')) {
continue;
}
$tel->setValue('234234234');
}
This ensures this works correctly if home
is uppercase (HOME
) but also if there's more than one TYPE
on a single property. Note that if there's more than 1 phone number that has TYPE=HOME
, all of them will be updated.
This can be simplified further using:
$vcard->getByType('TEL','HOME')->setValue('234234234');
Note that getByType
will only return 1 item. If there's more than one phone numbers with TYPE=HOME
, only the first will be returned.
Here's a simple way using loops:
I guess the IF is missing negation.
Fixed!