Skip to content

Commit

Permalink
Doc for public API
Browse files Browse the repository at this point in the history
  • Loading branch information
mstilkerich committed Mar 5, 2021
1 parent c919085 commit bbc91d3
Show file tree
Hide file tree
Showing 33 changed files with 320 additions and 124 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -4,3 +4,5 @@

- New API AddressbookCollection::query() for server-side addressbook search
- Generated API documentation for the latest release is now published to [github pages](https://mstilkerich.github.io/carddavclient/)

<!-- vim: set ts=4 sw=4 expandtab fenc=utf8 ff=unix tw=120: -->
2 changes: 1 addition & 1 deletion Makefile
Expand Up @@ -41,7 +41,7 @@ tests-interop: tests/interop/phpunit.xml

doc:
rm -rf $(DOCDIR)
phpDocumentor.phar -d src/ -t $(DOCDIR) --title="CardDAV Client Library" --setting=graphs.enabled=true
phpDocumentor.phar -d src/ -t $(DOCDIR) --title="CardDAV Client Library" --setting=graphs.enabled=true --validate
[ -d ../carddavclient-pages ] && rsync -r --delete --exclude .git doc/api/ ../carddavclient-pages

# For github CI system - if AccountData.php is not available, create from AccountData.php.dist
Expand Down
2 changes: 2 additions & 0 deletions NOTES.md
Expand Up @@ -24,3 +24,5 @@ issues have so far been encountered:
a bad request result should occur for any other value. [Issue](https://issuetracker.google.com/issues/160190530)
- Google reports cards as deleted that have not been deleted between the last sync and the current one,
but probably before that. [Issue](https://issuetracker.google.com/issues/160192237)

<!-- vim: set ts=4 sw=4 expandtab fenc=utf8 ff=unix tw=120: -->
6 changes: 5 additions & 1 deletion README.md
Expand Up @@ -101,5 +101,9 @@ also uses this library for the interaction with the CardDAV server.
An overview of the API is available [here](doc/README.md).

The API documentation for the latest released version can be found [here](https://mstilkerich.github.io/carddavclient/).
The public API of the library can be found via the `Public` package in the navigation sidebar.

Documentation for the API can be generated from the source code using [phpDocumentor](https://www.phpdoc.org/) by running `make doc`.
Documentation for the API can be generated from the source code using [phpDocumentor](https://www.phpdoc.org/) by
running `make doc`.

<!-- vim: set ts=4 sw=4 expandtab fenc=utf8 ff=unix tw=120: -->
2 changes: 2 additions & 0 deletions doc/README.md
Expand Up @@ -5,3 +5,5 @@ The following diagram shows the classes of the library and shows the public (blu
![Class diagram](Classes.svg)

This library uses [semantic versioning](https://semver.org), for which the above identifies the public API.


30 changes: 15 additions & 15 deletions doc/SPNEGO.md
Expand Up @@ -43,29 +43,29 @@ in Apache (it requires the Apache mod\_auth\_gssapi):
AuthType GSSAPI
AuthName "GSSAPI Logon"
# The server needs access to its kerberos key in the keytab
# It should contain a service principal like HTTP/baikal.domain.com@REALM
# The server needs access to its kerberos key in the keytab
# It should contain a service principal like HTTP/baikal.domain.com@REALM
GssapiCredStore keytab:/etc/apache2/apache.keytab
# The following enables server-side support for credential delegation (not that it needs to
# be enabled on the client-side as well, if desired. You need to specify a directory that the
# webserver can write to
# GSSAPI delegation enables the server to acquire tickets for additional backend services. For
# a CardDAV server, you will not normally need this. For a different service like roundcube
# webmail, this would enable the webmail client for example to authenticate on the user's behalf
# with backend IMAP, SMTP or CardDAV servers.
# be enabled on the client-side as well, if desired. You need to specify a directory that the
# webserver can write to
# GSSAPI delegation enables the server to acquire tickets for additional backend services. For
# a CardDAV server, you will not normally need this. For a different service like roundcube
# webmail, this would enable the webmail client for example to authenticate on the user's behalf
# with backend IMAP, SMTP or CardDAV servers.
# GssapiDelegCcacheDir /var/run/apache2/krbclientcache
# maps the kerberos principal to a local username based on the settings in /etc/krb5.conf
# e. g. username@REALM -> username
GssapiLocalName On
# Restrict the mechanisms offered by SPNEGO to Kerberos 5
# Restrict the mechanisms offered by SPNEGO to Kerberos 5
GssapiAllowedMech krb5
# Optional: The following allows to fallback to Basic authentication if no ticket is available.
# In this case, the username and kerberos password are required and the webserver would use them
# to acquire a ticket-granting ticket for the user from the KDC itself.
# Optional: The following allows to fallback to Basic authentication if no ticket is available.
# In this case, the username and kerberos password are required and the webserver would use them
# to acquire a ticket-granting ticket for the user from the KDC itself.
#GssapiBasicAuth On
#GssapiBasicAuthMech krb5
Expand All @@ -78,4 +78,4 @@ in Apache (it requires the Apache mod\_auth\_gssapi):
</VirtualHost>
```


<!-- vim: set ts=4 sw=4 expandtab fenc=utf8 ff=unix tw=120: -->
17 changes: 11 additions & 6 deletions src/Account.php
Expand Up @@ -29,10 +29,11 @@

/**
* Represents an account on a CardDAV Server.
*
* @package Public\Entities
*/
class Account implements \JsonSerializable
{
/********* PROPERTIES *********/
/** @var string */
private $username;

Expand All @@ -53,6 +54,7 @@ class Account implements \JsonSerializable

/**
* Construct a new Account object.
*
* @param string $discoveryUri
* The URI to use for service discovery. This can be a partial URI, in the simplest case just a domain name. Note
* that if no protocol is given, https will be used. Unencrypted HTTP will only be done if explicitly given (e.g.
Expand All @@ -63,10 +65,11 @@ class Account implements \JsonSerializable
* The password to use for authentication. If no password is needed (e.g. GSSAPI/Kerberos), this may be an empty
* string.
* @param string $baseUrl
* The full URL of the CardDAV service. This URL is used as base URL for the underlying {@see CardDavClient} that
* can be retrieved using {@see Account::getClient()}. When relative URIs are passed to the client, they will be
* relative to this base URL. If this account is used for discovery with the {@see Services\Discovery} service,
* this parameter can be omitted.
* The URL of the CardDAV server without the path part (e.g. https://carddav.example.com:443). This URL is used as
* base URL for the underlying {@see CardDavClient} that can be retrieved using {@see Account::getClient()}. When
* relative URIs are passed to the client, they will be relative to this base URL. If this account is used for
* discovery with the {@see Services\Discovery} service, this parameter can be omitted.
* @api
*/
public function __construct(string $discoveryUri, string $username, string $password, string $baseUrl = null)
{
Expand All @@ -84,6 +87,7 @@ public function __construct(string $discoveryUri, string $username, string $pass
* @param array<string,?string> $props An associative array containing the Account attributes.
* Keys: discoveryUri, username, password, baseUrl with the meaning from {@see Account::__construct()}
* @see Account::jsonSerialize()
* @api
*/
public static function constructFromArray(array $props): Account
{
Expand All @@ -95,7 +99,6 @@ public static function constructFromArray(array $props): Account
}

/** @var array{discoveryUri: string, username: string, password: string} & array<string,string> $props */

return new Account($props["discoveryUri"], $props["username"], $props["password"], $props["baseUrl"] ?? null);
}

Expand Down Expand Up @@ -133,6 +136,7 @@ public function getClient(?string $baseUrl = null): CardDavClient

/**
* Returns the discovery URI for this Account.
* @api
*/
public function getDiscoveryUri(): string
{
Expand All @@ -149,6 +153,7 @@ public function setUrl(string $url): void

/**
* Returns the base URL of the CardDAV service.
* @api
*/
public function getUrl(): string
{
Expand Down
62 changes: 48 additions & 14 deletions src/AddressbookCollection.php
Expand Up @@ -41,6 +41,8 @@
* message: string,
* node: \Sabre\VObject\Component | \Sabre\VObject\Property
* }
*
* @package Public\Entities
*/
class AddressbookCollection extends WebDavCollection
{
Expand All @@ -65,11 +67,12 @@ class AddressbookCollection extends WebDavCollection
* component of the URL is returned. This is suggested by RFC6352 to compose the addressbook name.
*
* @return string Name of the addressbook
* @api
*/
public function getName(): string
{
$props = $this->getProperties();
return $props[XmlEN::DISPNAME] ?? basename($this->uri);
return $props[XmlEN::DISPNAME] ?? $this->getBasename();
}

/**
Expand All @@ -89,6 +92,8 @@ public function __toString(): string
*
* Note that the result of this function is meant for display, not parsing. Thus the content and formatting of the
* text may change without considering backwards compatibility.
*
* @api
*/
public function getDetails(): string
{
Expand Down Expand Up @@ -137,11 +142,23 @@ public function getDetails(): string
return $desc;
}

/**
* Queries whether the server supports the addressbook-multiget REPORT on this addressbook collection.
*
* @return bool True if addressbook-multiget is supported for this collection.
* @api
*/
public function supportsMultiGet(): bool
{
return $this->supportsReport(XmlEN::REPORT_MULTIGET);
}

/**
* Retrieves the getctag property for this addressbook collection (if supported by the server).
*
* @return string The getctag property, or null if not provided by the server.
* @api
*/
public function getCTag(): ?string
{
$props = $this->getProperties();
Expand All @@ -158,6 +175,7 @@ public function getCTag(): ?string
* - etag(string): Entity tag of the returned card
* - vcf(string): VCard as string
* - vcard(VCard): VCard as Sabre/VObject VCard
* @api
*/
public function getCard(string $uri): array
{
Expand All @@ -175,6 +193,7 @@ public function getCard(string $uri): array
* Deletes a VCard from the addressbook.
*
* @param string $uri The URI of the VCard to be deleted.
* @api
*/
public function deleteCard(string $uri): void
{
Expand All @@ -186,14 +205,15 @@ public function deleteCard(string $uri): void
* Creates a new VCard in the addressbook.
*
* If the given VCard lacks the mandatory UID property, one will be generated. If the server provides an add-member
* URI, the new card will be POSTed to that URI. Otherwise, the function attempts to store the card do a URI whose
* URI, the new card will be POSTed to that URI. Otherwise, the function attempts to store the card to a URI whose
* last path component (filename) is derived from the UID of the VCard.
*
* @param VCard $vcard The VCard to be stored.
* @return array{uri: string, etag: string}
* Associative array with keys
* @psalm-return array{uri: string, etag: string}
* @return array<string,string> Associative array with keys
* - uri (string): URI of the new resource if the request was successful
* - etag (string): Entity tag of the created resource if returned by server, otherwise empty string.
* @api
*/
public function createCard(VCard $vcard): array
{
Expand Down Expand Up @@ -247,6 +267,7 @@ public function createCard(VCard $vcard): array
* @return ?string Returns the ETag of the updated card if provided by the server, null otherwise. If null is
* returned, it must be assumed that the server stored the card with modifications and the card
* should be read back from the server (this is a good idea anyway).
* @api
*/
public function updateCard(string $uri, VCard $vcard, string $etag): ?string
{
Expand All @@ -262,16 +283,24 @@ public function updateCard(string $uri, VCard $vcard, string $etag): ?string
/**
* Issues an addressbook-query report.
*
* @param SimpleConditions|ComplexConditions $conditions The query filter conditions, see Filter class for format.
* @param list<string> $requestedVCardProps A list of the requested VCard properties. If empty array, the full
* VCards are requested from the server.
* @param bool $matchAll Whether all or any of the conditions needs to match.
* @param int $limit Tell the server to return at most $limit results. 0 means no limit.
*
* @return array<string, array{vcard: VCard, etag: string}>
* @psalm-param SimpleConditions|ComplexConditions $conditions
* @param array $conditions
* The query filter conditions, see {@see Filter::__construct()} for format.
* @psalm-param list<string> $requestedVCardProps
* @param string[] $requestedVCardProps
* A list of the requested VCard properties. If empty array, the full VCards are requested from the server.
* @param bool $matchAll
* Whether all or any of the conditions needs to match.
* @param int $limit
* Tell the server to return at most $limit results. 0 means no limit.
*
* @psalm-return array<string, array{vcard: VCard, etag: string}>
* @return array<string, array> Returns an array of matched VCards:
* - The keys of the array are the URIs of the vcards
* - The values are associative arrays with keys etag (type: string) and vcard (type: VCard)
* @see Filter
* @since v1.1.0
* @api
*/
public function query(
array $conditions,
Expand Down Expand Up @@ -323,6 +352,9 @@ public function query(

/**
* This function replaces some well-known XML namespaces with a long name with shorter names for printing.
*
* @param string $s The fully-qualified XML element name (e.g. {urn:ietf:params:xml:ns:carddav}prop)
* @return string The short name (e.g. {CARDDAV}prop)
*/
protected function shortenXmlNamespacesForPrinting(string $s): string
{
Expand All @@ -337,6 +369,7 @@ protected function shortenXmlNamespacesForPrinting(string $s): string
* Validates a VCard before sending it to a CardDAV server.
*
* @param VCard $vcard The VCard to be validated.
* @throws \InvalidArgumentException if the validation fails.
*/
protected function validateCard(VCard $vcard): void
{
Expand Down Expand Up @@ -368,10 +401,11 @@ protected function validateCard(VCard $vcard): void
/**
* Provides the list of property names that should be requested upon call of refreshProperties().
*
* @return list<string> A list of property names including namespace prefix (e. g. '{DAV:}resourcetype').
* @psalm-return list<string>
* @return array<int,string> A list of property names including namespace prefix (e. g. '{DAV:}resourcetype').
*
* @see parent::getProperties()
* @see parent::refreshProperties()
* @see WebDavResource::getProperties()
* @see WebDavResource::refreshProperties()
*/
protected function getNeededCollectionPropertyNames(): array
{
Expand Down
23 changes: 13 additions & 10 deletions src/CardDavClient.php
Expand Up @@ -21,10 +21,6 @@
* along with PHP-CardDavClient. If not, see <https://www.gnu.org/licenses/>.
*/

/**
* Class CardDavClient
*/

declare(strict_types=1);

namespace MStilkerich\CardDavClient;
Expand All @@ -37,15 +33,20 @@
use MStilkerich\CardDavClient\XmlElements\Deserializers;
use MStilkerich\CardDavClient\Exception\XmlParseException;

/*
Other needed features:
- Setting extra headers (Depth, Content-Type, charset, If-Match, If-None-Match)
- Debug output HTTP traffic to logfile
*/

/**
* Implements the operations of the CardDAV protocol.
*
* This class implements the lower level interactions with the CardDAV server that are utilized by the higher-level
* operations offered by the public entities ({@see AddressbookCollection} etc.) and services ({@see Services\Sync},
* {@see Services\Discovery}.
*
* An application interacting with the carddavclient library should not interact with this class directly, and it is
* considered an internal part of the library whose interfaces may change without being considered a change of the
* library's API.
*
* @psalm-import-type RequestOptions from HttpClientAdapter
* @psalm-import-type PropTypes from Prop
* @package Internal\Communication
*/
class CardDavClient
{
Expand All @@ -71,6 +72,8 @@ public function __construct(string $base_uri, string $username, string $password
}

/**
* Requests a sync-collection REPORT from the CardDAV server.
*
* Note: Google's server does not accept an empty syncToken, though explicitly allowed for initial sync by RFC6578.
* It will respond with 400 Bad Request and error message "Request contains an invalid argument."
*
Expand Down
11 changes: 5 additions & 6 deletions src/Config.php
Expand Up @@ -21,16 +21,17 @@
* along with PHP-CardDavClient. If not, see <https://www.gnu.org/licenses/>.
*/

/**
* Class Config
*/

declare(strict_types=1);

namespace MStilkerich\CardDavClient;

use Psr\Log\{LoggerInterface, NullLogger};

/**
* Central configuration of the carddavclient library.
*
* @package Public\Infrastructure
*/
class Config
{
/** @var LoggerInterface */
Expand All @@ -44,8 +45,6 @@ public static function init(LoggerInterface $logger = null, LoggerInterface $htt
self::$logger = $logger ?? new NullLogger();
self::$httplogger = $httplogger ?? new NullLogger();
}

// TODO whether to allow repairing errors in VCards
}

// vim: ts=4:sw=4:expandtab:fenc=utf8:ff=unix:tw=120

0 comments on commit bbc91d3

Please sign in to comment.