mstilkerich / carddavclient

CardDAV client library for PHP ("PHP-CardDavClient")
MIT License
20 stars 4 forks source link

can't find a way to list all vcards within the addressbook #29

Open pasqual-artif opened 1 week ago

pasqual-artif commented 1 week ago

I would like to rtfm to loop through all vcards existing in the received addressbook. With var_dump($abook->query(['FN' => '/NAME/'])) I can print the specific card, but I want a loop through the elements... getChildren() doesn't help either

mstilkerich commented 1 week ago

getChildren gives you all members of an addressbookcollection. It could in theory include non vcard children, e.g. nested addressbookcollection, but this is rather uncommon. Why is it not working for you?

pasqual-artif commented 1 week ago

I get several things listed, including the used password for example, but not the vcards I created...

$abook = $abooks[0];
$synchandler = new EchoSyncHandler();
$syncmgr = new Sync();

$log->notice("Performing initial sync");
$lastSyncToken = $syncmgr->synchronize($abook, $synchandler, [ "FN" ], "");
$log->notice(">>> Initial Sync completed, new sync token is $lastSyncToken");

$log->notice("Performing followup sync");
$lastSyncToken = $syncmgr->synchronize($abook, $synchandler, [ "FN" ], $lastSyncToken);
$log->notice(">>> Re-Sync completed, new sync token is $lastSyncToken");

// var_dump($abook);
// die();
var_export($abook->query(['FN' => '/Pasqual/']));
// got result
var_export($abook->query(['FN' => '/.*/']));
// empty array
var_export($abook->getChildren());
// lot of information, but no vcards
mstilkerich commented 1 week ago

The sync stuff is just needed if you plan to perform synchronization. Of course it could also be used to get all the cards initially, but you have to implement a synchandler which makes it a bit overkill for the simple use case.

getChildren() gives you a webdavresource objects, not vcards. To get vcards from these, use the getCard API.

Something like this (typing this on a phone, so this may contain errors but I hope you get the idea):

$resources = $abook->getChildren();
foreach ($resources as $resource) {
   $cardinfo = $abook->getCard($resource->getUri());
   $vcard = $cardinfo[’vcard’];
}
pasqual-artif commented 1 week ago

Not quite... If I print the vcards in a loop, I can see the data, but I cant access them. For example with

// (...)
$resources = $abook->getChildren();
foreach ($resources as $resource) {
    $vcards = $cardinfo['vcard'];
    foreach ($vcards as $vcard) {
        var_dump($vcard->FN);
// prints the whole vcard again; same live var_dump(vcard)
        var_dump(vcard->getChildren());
// undefined method
        var_dump($vcard['children']);
// undefined array key
        die();
    }
 }

But the Sabre\VObject\Component\VCard object clearly shows:

object(Sabre\VObject\Component\VCard)#1557 (6) {
  ["parent"]=>
  NULL
  ["iterator":protected]=>
  NULL
  ["root":protected]=>
  *RECURSION*
  ["name"]=>
  string(5) "VCARD"
  ["children":protected]=>
  array(8) {
    ["VERSION"]=>
    array(1) {
      [0]=>
      object(Sabre\VObject\Property\FlatText)#1550 (12) {
        ["parent"]=>
        *RECURSION*
        ["iterator":protected]=>
        object(Sabre\VObject\ElementList)#1560 (1) {
          ["storage":"ArrayIterator":private]=>
          array(1) {
            [0]=>
            *RECURSION*
          }
        }
        ["root":protected]=>
        *RECURSION*
        ["name"]=>
        string(7) "VERSION"
        ["group"]=>
        NULL
        ["parameters"]=>
        array(0) {
        }
        ["value":protected]=>
        array(1) {
          [0]=>
          string(3) "3.0"
        }
        ["delimiter"]=>
        string(1) ","
        ["lineIndex"]=>
        NULL
        ["lineString"]=>
        NULL
        ["structuredValues":protected]=>
        array(6) {
          [0]=>
          string(1) "N"
          [1]=>
          string(3) "ADR"
          [2]=>
          string(3) "ORG"
          [3]=>
          string(6) "GENDER"
          [4]=>
          string(12) "CLIENTPIDMAP"
          [5]=>
          string(14) "REQUEST-STATUS"
        }
        ["minimumPropertyValues":protected]=>
        array(2) {
          ["N"]=>
          int(5)
          ["ADR"]=>
          int(7)
        }
      }
    }
    ["PRODID"]=>
    array(1) {
      [0]=>
      object(Sabre\VObject\Property\FlatText)#1547 (12) {
        ["parent"]=>
        *RECURSION*
        ["iterator":protected]=>
        NULL
        ["root":protected]=>
        *RECURSION*
        ["name"]=>
        string(6) "PRODID"
        ["group"]=>
        NULL
        ["parameters"]=>
        array(0) {
        }
        ["value":protected]=>
        array(1) {
          [0]=>
          string(33) "-//Sabre//Sabre VObject 4.5.4//EN"
        }
        ["delimiter"]=>
        string(1) ","
        ["lineIndex"]=>
        NULL
        ["lineString"]=>
        NULL
        ["structuredValues":protected]=>
        array(6) {
          [0]=>
          string(1) "N"
          [1]=>
          string(3) "ADR"
          [2]=>
          string(3) "ORG"
          [3]=>
          string(6) "GENDER"
          [4]=>
          string(12) "CLIENTPIDMAP"
          [5]=>
          string(14) "REQUEST-STATUS"
        }
        ["minimumPropertyValues":protected]=>
        array(2) {
          ["N"]=>
          int(5)
          ["ADR"]=>
          int(7)
        }
      }
    }
    ["UID"]=>
    array(1) {
      [0]=>
      object(Sabre\VObject\Property\FlatText)#1546 (12) {
        ["parent"]=>
        *RECURSION*
        ["iterator":protected]=>
        NULL
        ["root":protected]=>
        *RECURSION*
        ["name"]=>
        string(3) "UID"
        ["group"]=>
        NULL
        ["parameters"]=>
        array(0) {
        }
        ["value":protected]=>
        array(1) {
          [0]=>
          string(36) "SOME_ID"
        }
        ["delimiter"]=>
        string(1) ","
        ["lineIndex"]=>
        NULL
        ["lineString"]=>
        NULL
        ["structuredValues":protected]=>
        array(6) {
          [0]=>
          string(1) "N"
          [1]=>
          string(3) "ADR"
          [2]=>
          string(3) "ORG"
          [3]=>
          string(6) "GENDER"
          [4]=>
          string(12) "CLIENTPIDMAP"
          [5]=>
          string(14) "REQUEST-STATUS"
        }
        ["minimumPropertyValues":protected]=>
        array(2) {
          ["N"]=>
          int(5)
          ["ADR"]=>
          int(7)
        }
      }
    }
    ["FN"]=>
    array(1) {
      [0]=>
      object(Sabre\VObject\Property\FlatText)#1544 (12) {
        ["parent"]=>
        *RECURSION*
        ["iterator":protected]=>
        NULL
        ["root":protected]=>
        *RECURSION*
        ["name"]=>
        string(2) "FN"
        ["group"]=>
        NULL
        ["parameters"]=>
        array(0) {
        }
        ["value":protected]=>
        array(1) {
          [0]=>
          string(15) "Pasqual"
        }
        ["delimiter"]=>
        string(1) ","
        ["lineIndex"]=>
(...)
pasqual-artif commented 1 week ago

Im trying to read data from an Excel file and I want to prevent to create duplicate entries, for example if someone is editing the VCard serverside, or if the file is read twice.

So I want to compare the new data with the recieved elements and create or update a card based on the count of deviations.

mstilkerich commented 1 week ago

You have to loop over the array returned by getchildren. Please compare my loop to your loop.

pasqual-artif commented 1 week ago

I did... sry.. I missed the line... code is edited

mstilkerich commented 1 week ago

Not quite... If I print the vcards in a loop, I can see the data, but I cant access them. For example with

// (...)
$resources = $abook->getChildren();
foreach ($resources as $resource) {
    $vcards = $cardinfo['vcard'];
    foreach ($vcards as $vcard) {
        var_dump($vcard->FN);
// prints the whole vcard again; same live var_dump(vcard)
        var_dump(vcard->getChildren());
// undefined method
        var_dump($vcard['children']);
// undefined array key
        die();
    }
 }

But the Sabre\VObject\Component\VCard object clearly shows:

object(Sabre\VObject\Component\VCard)#1557 (6) {
  ["parent"]=>
  NULL
  ["iterator":protected]=>
  NULL
  ["root":protected]=>
  *RECURSION*
  ["name"]=>
  string(5) "VCARD"
  ["children":protected]=>
  array(8) {
    ["VERSION"]=>
    array(1) {
      [0]=>
      object(Sabre\VObject\Property\FlatText)#1550 (12) {
        ["parent"]=>
        *RECURSION*
        ["iterator":protected]=>
        object(Sabre\VObject\ElementList)#1560 (1) {
          ["storage":"ArrayIterator":private]=>
          array(1) {
            [0]=>
            *RECURSION*
          }
        }
        ["root":protected]=>
        *RECURSION*
        ["name"]=>
        string(7) "VERSION"
        ["group"]=>
        NULL
        ["parameters"]=>
        array(0) {
        }
        ["value":protected]=>
        array(1) {
          [0]=>
          string(3) "3.0"
        }
        ["delimiter"]=>
        string(1) ","
        ["lineIndex"]=>
        NULL
        ["lineString"]=>
        NULL
        ["structuredValues":protected]=>
        array(6) {
          [0]=>
          string(1) "N"
          [1]=>
          string(3) "ADR"
          [2]=>
          string(3) "ORG"
          [3]=>
          string(6) "GENDER"
          [4]=>
          string(12) "CLIENTPIDMAP"
          [5]=>
          string(14) "REQUEST-STATUS"
        }
        ["minimumPropertyValues":protected]=>
        array(2) {
          ["N"]=>
          int(5)
          ["ADR"]=>
          int(7)
        }
      }
    }
    ["PRODID"]=>
    array(1) {
      [0]=>
      object(Sabre\VObject\Property\FlatText)#1547 (12) {
        ["parent"]=>
        *RECURSION*
        ["iterator":protected]=>
        NULL
        ["root":protected]=>
        *RECURSION*
        ["name"]=>
        string(6) "PRODID"
        ["group"]=>
        NULL
        ["parameters"]=>
        array(0) {
        }
        ["value":protected]=>
        array(1) {
          [0]=>
          string(33) "-//Sabre//Sabre VObject 4.5.4//EN"
        }
        ["delimiter"]=>
        string(1) ","
        ["lineIndex"]=>
        NULL
        ["lineString"]=>
        NULL
        ["structuredValues":protected]=>
        array(6) {
          [0]=>
          string(1) "N"
          [1]=>
          string(3) "ADR"
          [2]=>
          string(3) "ORG"
          [3]=>
          string(6) "GENDER"
          [4]=>
          string(12) "CLIENTPIDMAP"
          [5]=>
          string(14) "REQUEST-STATUS"
        }
        ["minimumPropertyValues":protected]=>
        array(2) {
          ["N"]=>
          int(5)
          ["ADR"]=>
          int(7)
        }
      }
    }
    ["UID"]=>
    array(1) {
      [0]=>
      object(Sabre\VObject\Property\FlatText)#1546 (12) {
        ["parent"]=>
        *RECURSION*
        ["iterator":protected]=>
        NULL
        ["root":protected]=>
        *RECURSION*
        ["name"]=>
        string(3) "UID"
        ["group"]=>
        NULL
        ["parameters"]=>
        array(0) {
        }
        ["value":protected]=>
        array(1) {
          [0]=>
          string(36) "SOME_ID"
        }
        ["delimiter"]=>
        string(1) ","
        ["lineIndex"]=>
        NULL
        ["lineString"]=>
        NULL
        ["structuredValues":protected]=>
        array(6) {
          [0]=>
          string(1) "N"
          [1]=>
          string(3) "ADR"
          [2]=>
          string(3) "ORG"
          [3]=>
          string(6) "GENDER"
          [4]=>
          string(12) "CLIENTPIDMAP"
          [5]=>
          string(14) "REQUEST-STATUS"
        }
        ["minimumPropertyValues":protected]=>
        array(2) {
          ["N"]=>
          int(5)
          ["ADR"]=>
          int(7)
        }
      }
    }
    ["FN"]=>
    array(1) {
      [0]=>
      object(Sabre\VObject\Property\FlatText)#1544 (12) {
        ["parent"]=>
        *RECURSION*
        ["iterator":protected]=>
        NULL
        ["root":protected]=>
        *RECURSION*
        ["name"]=>
        string(2) "FN"
        ["group"]=>
        NULL
        ["parameters"]=>
        array(0) {
        }
        ["value":protected]=>
        array(1) {
          [0]=>
          string(15) "Pasqual"
        }
        ["delimiter"]=>
        string(1) ","
        ["lineIndex"]=>
(...)

$cardinfo['vcard']is a single vcard, why do you run a loop over it? I think this loop will iterate over the properties of the vcard, which I guess is not what you want.

You can access the properties you are interested in via index operator or dereference operator, e.g. $vcard = $cardinfo['vcard']; echo $vcard->FN;

See sabre vobject docs for ways of working with vcard objects.

https://sabre.io/vobject/vcard/