<commit_before><?php

/**
 * Carddav modules
 * @package modules
 * @subpackage carddav_contacts
 */

if (!defined('DEBUG_MODE')) { die(); }

/**
 * @subpackage carddav_contacts/lib
 */
class Hm_Carddav {

    public $addresses = array();
    private $src;
    private $url;
    private $user;
    private $pass;
    private $principal_url;
    private $address_url;
    private $principal_path = '//a:response/a:propstat/a:prop/a:current-user-principal/a:href';
    private $addressbook_path = '//a:response/a:propstat/a:prop/CR:addressbook-home-set/a:href';
    private $addr_list_path = '//a:response/a:href';
    private $addr_detail_path = '//a:response/a:propstat/a:prop/CR:address-data';

    public function __construct($src, $url, $user, $pass) {
        $this->user = $user;
        $this->src = $src;
        $this->pass = $<PASSWORD>;
        $this->url = $url;
        if ($this->discover()) {
            $this->get_vcards();
        }
    }

    private function get_vcards() {
        $res = array();
        $parser = new Hm_VCard();
        $count = 0;
        foreach ($this->xml_find($this->list_addressbooks(), $this->addr_list_path, true) as $url) {
            $url = $this->url_concat($url);
            if ($url == $this->address_url) {
                continue;
            }
            $count++;
            Hm_Debug::add(sprintf('CARDDAV: Trying contacts url %s', $url));
            foreach ($this->xml_find($this->report($url), $this->addr_detail_path, true) as $addr) {
                $parser->import($addr);
                foreach ($this->convert_to_contact($parser->parsed_data()) as $contact) {
                    $res[] = $contact;
                }
            }
        }
        Hm_Debug::add(sprintf('CARDDAV: %s contact urls found', $count));
        $this->addresses = $res;
    }

    private function convert_to_contact($data) {
        $res = array();
        if (!array_key_exists('email', $data) || count($data['email']) == 0) {
            return $res;
        }

        $dn = '';
        $phone = '';
        $dn = array_key_exists('n', $data) ? sprintf('%s %s', $data['n']['firstname'], $data['n']['lastname']) : '';
        $phone = array_key_exists('tel', $data) && count($data['tel']) > 0 ? $data['tel'][0]['value']: '';
        $all_flds = $this->parse_extr_flds($data);

        foreach ($data['email'] as $email) {
            $res[] = array(
                'source' => $this->src,
                'display_name' => $dn,
                'phone_number' => $phone,
                'email_address' => $email['value'],
                'all_fields' => $all_flds
            );
        }
        return $res;
    }

    private function parse_extr_flds($data) {
        $all_flds = array();
        foreach ($data as $name => $vals) {
            if (in_array($name, array('n', 'tel', 'email'))) {
                continue;
            }
            if (is_array($vals) && array_key_exists('formatted', $vals)) {
                $all_flds[$vals['formatted']['name']] = $vals['formatted']['value'];
            }
            if (is_string($vals)) {
                $all_flds[$name] = $vals;
            }
        }
        return $all_flds;
    }

    private function discover() {
        $path = $this->xml_find($this->principal_discover(), $this->principal_path);
        if ($path === false) {
            Hm_Debug::add('CARDDAV: No principal path discovered');
            return false;
        }
        Hm_Debug::add(sprintf('CARDDAV: Found %s principal path', $path));
        $this->principal_url = $this->url_concat($path);
        $address_path = $this->xml_find($this->addressbook_discover(), $this->addressbook_path);
        if ($address_path === false) {
            Hm_Debug::add('CARDDAV: No address path discovered');
            return false;
        }
        Hm_Debug::add(sprintf('CARDDAV: Found %s address path', $address_path));
        $this->address_url = $this->url_concat($address_path);
        return true;
    }

    private function parse_xml($xml) {
        try {
            $data = new SimpleXMLElement($xml);
            return $data;
        }
        catch (Exception $oops) {
            Hm_Msgs::add('ERRUnable to access CardDav server');
            Hm_Debug::add(sprintf('CARDDAV: Could not parse XML: %s', $xml));
        }
        return false;
    }

    private function xml_find($xml, $path, $multi=false) {
        $data = $this->parse_xml($xml);
        if (!$data) {
            return false;
        }
        foreach ($data->getDocNamespaces() as $pre => $ns) {
            if (!$pre) {
                $pre = 'a';
            }
            $data->registerXPathNamespace($pre, $ns);
        }
        $res = array();
        foreach ($data->xpath($path) as $node) {
            if (!$multi) {
                return (string) $node;
            }
            $res[] = (string) $node;
        }
        if ($multi) {
            if (count($res) == 0) {
                Hm_Debug::add(sprintf('CARDDAV: find for %s failed in xml: %s', $path, $xml));
            }
            return $res;
        }
        Hm_Debug::add(sprintf('CARDDAV: find for %s failed in xml: %s', $path, $xml));
        return false;
    }<commit_msg>begone fould namespaces! testing a fix for issue #120<commit_after><?php

/**
 * Carddav modules
 * @package modules
 * @subpackage carddav_contacts
 */

if (!defined('DEBUG_MODE')) { die(); }

/**
 * @subpackage carddav_contacts/lib
 */
class Hm_Carddav {

    public $addresses = array();
    private $src;
    private $url;
    private $user;
    private $pass;
    private $principal_url;
    private $address_url;
    private $principal_path = '//response/propstat/prop/current-user-principal/href';
    private $addressbook_path = '//response/propstat/prop/addressbook-home-set/href';
    private $addr_list_path = '//response/href';
    private $addr_detail_path = '//response/propstat/prop/address-data';

    public function __construct($src, $url, $user, $pass) {
        $this->user = $user;
        $this->src = $src;
        $this->pass = $pass;
        $this->url = $url;
        if ($this->discover()) {
            $this->get_vcards();
        }
    }

    private function get_vcards() {
        $res = array();
        $parser = new Hm_VCard();
        $count = 0;
        foreach ($this->xml_find($this->list_addressbooks(), $this->addr_list_path, true) as $url) {
            $url = $this->url_concat($url);
            if ($url == $this->address_url) {
                continue;
            }
            $count++;
            Hm_Debug::add(sprintf('CARDDAV: Trying contacts url %s', $url));
            foreach ($this->xml_find($this->report($url), $this->addr_detail_path, true) as $addr) {
                $parser->import($addr);
                foreach ($this->convert_to_contact($parser->parsed_data()) as $contact) {
                    $res[] = $contact;
                }
            }
        }
        Hm_Debug::add(sprintf('CARDDAV: %s contact urls found', $count));
        $this->addresses = $res;
    }

    private function convert_to_contact($data) {
        $res = array();
        if (!array_key_exists('email', $data) || count($data['email']) == 0) {
            return $res;
        }

        $dn = '';
        $phone = '';
        $dn = array_key_exists('n', $data) ? sprintf('%s %s', $data['n']['firstname'], $data['n']['lastname']) : '';
        $phone = array_key_exists('tel', $data) && count($data['tel']) > 0 ? $data['tel'][0]['value']: '';
        $all_flds = $this->parse_extr_flds($data);

        foreach ($data['email'] as $email) {
            $res[] = array(
                'source' => $this->src,
                'display_name' => $dn,
                'phone_number' => $phone,
                'email_address' => $email['value'],
                'all_fields' => $all_flds
            );
        }
        return $res;
    }

    private function parse_extr_flds($data) {
        $all_flds = array();
        foreach ($data as $name => $vals) {
            if (in_array($name, array('n', 'tel', 'email'))) {
                continue;
            }
            if (is_array($vals) && array_key_exists('formatted', $vals)) {
                $all_flds[$vals['formatted']['name']] = $vals['formatted']['value'];
            }
            if (is_string($vals)) {
                $all_flds[$name] = $vals;
            }
        }
        return $all_flds;
    }

    private function discover() {
        $path = $this->xml_find($this->principal_discover(), $this->principal_path);
        if ($path === false) {
            Hm_Debug::add('CARDDAV: No principal path discovered');
            return false;
        }
        Hm_Debug::add(sprintf('CARDDAV: Found %s principal path', $path));
        $this->principal_url = $this->url_concat($path);
        $address_path = $this->xml_find($this->addressbook_discover(), $this->addressbook_path);
        if ($address_path === false) {
            Hm_Debug::add('CARDDAV: No address path discovered');
            return false;
        }
        Hm_Debug::add(sprintf('CARDDAV: Found %s address path', $address_path));
        $this->address_url = $this->url_concat($address_path);
        return true;
    }

    private function parse_xml($xml) {
        $xml = preg_replace("/<[a-zA-Z]+:/Um", "<", $xml);
        $xml = preg_replace("/<\/[a-zA-Z]+:/Um", "</", $xml);
        $xml = str_replace('xmlns=', 'ns=', $xml);
        try {
            $data = new SimpleXMLElement($xml);
            return $data;
        }
        catch (Exception $oops) {
            Hm_Msgs::add('ERRUnable to access CardDav server');
            Hm_Debug::add(sprintf('CARDDAV: Could not parse XML: %s', $xml));
        }
        return false;
    }

    private function xml_find($xml, $path, $multi=false) {
        $data = $this->parse_xml($xml);
        if (!$data) {
            return false;
        }
        $res = array();
        foreach ($data->xpath($path) as $node) {
            if (!$multi) {
                return (string) $node;
            }
            $res[] = (string) $node;
        }
        if ($multi) {
            if (count($res) == 0) {
                Hm_Debug::add(sprintf('CARDDAV: find for %s failed in xml: %s', $path, $xml));
            }
            return $res;
        }
        Hm_Debug::add(sprintf('CARDDAV: find for %s failed in xml: %s', $path, $xml));
        return false;
    }
{'fraction_non_alphanumeric': 0.17117117117117117, 'fraction_numerical': 0.0012459267778416716, 'mean_word_length': 1.9916857798165137, 'pattern_counts': {'":': 0, '<': 10, '<?xml version=': 0, '>': 85, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 39}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3210661', 'n_tokens_mistral': 3338, 'n_tokens_neox': 3279, 'n_words': 649}