mstilkerich / carddavclient

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

long time for request #4

Closed sadden3194 closed 3 years ago

sadden3194 commented 3 years ago

Hi again šŸ‘

my code works and I am happy. But the request time is very long:

My code:

<?php

echo "Start :".date("d.m.Y - H:i:s");

require 'inc/config.php'; // Credentials 
require 'vendor/autoload.php';

use MStilkerich\CardDavClient\{Account, AddressbookCollection, Config};
use Psr\Log\{AbstractLogger, NullLogger, LogLevel};
use Sabre\VObject\Component\VCard;

class StdoutLogger extends AbstractLogger {
    public function log($level, $message, array $context = array()) {
        if ($level !== LogLevel::DEBUG) {
            $ctx = empty($context) ? "" : json_encode($context);
            echo ">>> ".$message . $ctx . "<br />";
        }
    }
}

    $log = new StdoutLogger();
    Config::init($log);

    $account = new Account(URL, USERNAME, PASSWORD);
    $abook = new AddressbookCollection(URL, $account);
    $contacts = $abook->getChildren();

    foreach ($contacts as $contact) {
      $vcard = $abook->getCard($contact->getUri());

        if (isset($vcard["vcard"]->EMAIL)) {

            foreach($vcard["vcard"]->EMAIL as $email) {

                if ($email == "mail@domain.de") {

                    exit();

                }

            }

        }

    }
    echo "<br />";
    echo "END: ".date("d.m.Y - H:i:s");
?>

Output:

START: 15.01.2021 - 12:04:46 END: 15.01.2021 - 12:05:18

This are 30 seconds. Can you explain me why? :(

mstilkerich commented 3 years ago

Well, you download the entire addressbook each time, and that using the most inefficient method of one request per card. So if you have a lot of cards / huge cards (photos) or a slow connection to the server, it may take a while.

The library currently mostly targets the use case of synchronizing an addressbook with a local cache of the VCards. The incremental synchronization normally is very fast. For your use case, addressbook-query would be best, but it is not yet supported (#2).

So:

sadden3194 commented 3 years ago

I would like to wait for #2 ;) How long it will take? :)

mstilkerich commented 3 years ago

It will take a while until this is properly implemented and tested. There is a quick proof of concept available on the issue2_addressbook_query that you can try. It appears to work for your use case, but I really haven't tested it very much.

$contacts = $abook->query(
     ['EMAIL' => '%foo%'], // this is the filter conditions, see QueryConditions.php for documentation
     [ 'FN', 'EMAIL' ]   // this is the list of properties asked for - omit if you want the full vcards
);                                                        

foreach ($contacts as $card) {                                                                                  
    $card = $card["vcard"];                                                                                  
    // whatever you want to do with it
}

Consider this an early proof of concept, which will have bugs and may be subject to change until the released version.

To have composer fetch the branch, change the dependency in composer.json to:

"mstilkerich/carddavclient": "dev-issue2_addressbook_query"

And then run

composer update
sadden3194 commented 3 years ago

Okay, I will wait for the final solution :)