/** * Create a contact group with the given name * * @param string The group name * @return mixed False on error, array with record props in success */ public function create_group($name) { $cuid = $this->find_free_uid(); $uri = "{$cuid}.vcf"; $save_data = array('name' => $name, 'kind' => 'group', 'cuid' => $cuid); $vcf = $this->create_vcard_from_save_data($save_data); if (!$vcf) { return false; } $vcfstr = $vcf->serialize(); if (!($etag = $this->put_record_to_carddav($uri, $vcfstr))) { return false; } $url = carddav_common::concaturl($this->config['url'], $uri); $url = preg_replace(';https?://[^/]+;', '', $url); if (!($dbid = $this->dbstore_group($etag, $url, $vcfstr, $save_data))) { return false; } return array('id' => $dbid, 'name' => $name); }
private function retrieve_addressbooks($path, $cdfopen_cfg, $recurse = false) { $baseurl = $cdfopen_cfg['url']; $url = carddav_common::concaturl($baseurl, $path); $depth = $recurse ? 1 : 0; self::$helper->debug("SEARCHING {$url} (Depth: " . $depth . ")"); // check if the given URL points to an addressbook $opts = array('method' => "PROPFIND", 'header' => array("Depth: " . $depth, 'Content-Type: application/xml; charset="utf-8"'), 'content' => <<<EOF <?xml version="1.0" encoding="utf-8"?> <D:propfind xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:carddav"><D:prop> \t<D:current-user-principal/> <D:resourcetype /> <D:displayname /> \t<C:addressbook-home-set/> </D:prop></D:propfind> EOF ); $reply = self::$helper->cdfopen($url, $opts, $cdfopen_cfg); $xml = self::$helper->checkAndParseXML($reply); if ($xml === false) { return false; } $aBooks = array(); // Check if we found addressbooks at the URL $xpresult = $xml->xpath('//RCMCD:response[descendant::RCMCD:resourcetype/RCMCC:addressbook]'); foreach ($xpresult as $ab) { self::$helper->registerNamespaces($ab); $aBook = array(); list($aBook['href']) = $ab->xpath('child::RCMCD:href'); list($aBook['name']) = $ab->xpath('descendant::RCMCD:displayname'); $aBook['href'] = (string) $aBook['href']; $aBook['name'] = (string) $aBook['name']; if (strlen($aBook['href']) > 0) { $aBook['href'] = carddav_common::concaturl($baseurl, $aBook['href']); self::$helper->debug("found abook: " . $aBook['name'] . " at " . $aBook['href']); $aBooks[] = $aBook; } } // found -> done if (count($aBooks) > 0) { return $aBooks; } if ($recurse === false) { // Check some additional URLs: $additional_urls = array(); // (1) original URL $additional_urls[] = $url; // (2) see if the server told us the addressbook home location $abookhome = $xml->xpath('//RCMCC:addressbook-home-set/RCMCD:href'); if (count($abookhome) != 0) { self::$helper->debug("addressbook home: " . $abookhome[0]); $additional_urls[] = $abookhome[0]; } // (3) see if we got a principal URL $princurl = $xml->xpath('//RCMCD:current-user-principal/RCMCD:href'); if (count($princurl) != 0) { self::$helper->debug("principal URL: " . $princurl[0]); $additional_urls[] = $princurl[0]; } foreach ($additional_urls as $other_url) { self::$helper->debug("Searching additional URL: {$other_url}"); if (strlen($other_url) <= 0) { continue; } // if the server returned a full URL, adjust the base url if (preg_match(';^[^/]+://[^/]+;', $other_url, $match)) { $cdfopen_cfg['url'] = $match[0]; } else { // restore original baseurl, may have changed in prev URL check $cdfopen_cfg['url'] = $baseurl; } $aBooks = $this->retrieve_addressbooks($other_url, $cdfopen_cfg, $other_url != $princurl[0]); // found -> done if (!($aBooks === false) && count($aBooks) > 0) { return $aBooks; } } } // (4) there is no more we can do -> fail self::$helper->debug("no principal URL found"); return false; }