<?php
#
# Copyright 2003 James Seng. See LICENSE for the Software License.
#

$GLOBALS['conf_fcontacts'] = "contacts";

function contacts_element_start($parser,$name,$attribs) {
    if (!isset($GLOBALS['contacts_load'])) return 0;
    if ($name == "OUTLINE") {
        $id = $attribs['TEXT'];
        $userid = $attribs['USERID'];
        $passwd = $attribs['PASSWD'];
        $url = $attribs['URL'];
        $GLOBALS['contacts_load']->add_contact($id,$userid,$passwd,$url);
    }
}

function contacts_element_end($parser,$name) {
}


class func_contacts extends function_base {
    var $contacts = array();

    function func_contacts() {
        global $config;

        $this->load($GLOBALS['conf_fcontacts']);
        $GLOBALS['contacts'] =& $this;
    }

    function print_menu($type) {
        if ($type == 'short') {
            print "<a href=\"?q=show_contacts\">Contacts</a> | ";
            return;
        }

        if ($type == 'long') {
            print <<<_LONG_
<tr>
  <td align="right" width="25%" valign="top">
    <a href="?q=show_contacts">Edit Contacts</a></td>
  <td align="left" width="75%" valign="top">
    This is a "PonG client". You define your friends' "PonG 
    server" (URL & password if you have one) and the client will query 
    these servers to keep their contact information up to date. 
    </td>
  </tr>
_LONG_;
        }
    }

    function add_contact($id,$userid,$passwd,$url) {
        $this->contacts[$id] = array("url" => $url, 
                                     "userid" => $userid,
                                     "passwd" => $passwd);
    }

    function del_contact($id) {
        if (isset($this->contacts[$id])) {
            unset($this->contacts[$id]);

            // reorder the contacts after deleting
            $this->contacts = array_values($this->contacts);
        }
    }

    function load($file = "contacts") {
        $filename = $this->filename($file);

        $GLOBALS['contacts_load'] =& $this;

        if (!file_exists($filename))
            return 0;

        if (!($fh = fopen($filename,"r")))
            return $this->error("Unable to open $filename for reading.");

        $xml_parser = xml_parser_create();
        xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING,1);
        xml_set_element_handler($xml_parser, "contacts_element_start",
            "contacts_element_end");

        while ($data = fread($fh, 4096)) {
            if (!xml_parse($xml_parser,$data,feof($fh))) 
                return $this->error(sprintf(
                    "%s: XML parse error %s at line %d.",
                        $filename,
                        xml_error_string(xml_get_error_code($xml_parser)),
                        xml_get_current_line_number($xml_parser)));
        }

        xml_parser_free($xml_parser);

        unset($GLOBALS['contacts_load']);

        // re-order the contacts after loading
        $this->contacts = array_values($this->contacts);

        return 1;
    }

    function save($file = "contacts") {
        global $config;

        // re-order the contacts before saving
        $this->contacts = array_values($this->contacts);

        ignore_user_abort(true);
    
        if (!isset($config->conf['datecreated'])) {
            $config->set('datecreated',long_datetime());
        }
    
        $filename = $this->tempfile($file);
    
        if (!($fh = fopen($filename, 'w')))
            return $this->error("Unable to open $filename for writing.");
    
        if (flock($fh,LOCK_EX | LOCK_NB)) {
            fwrite($fh,$this->opml_header("Pong Contacts"));
            foreach ($this->contacts as $id => $contact) {
                $url = htmlspecialchars($contact['url']);
                $userid = htmlspecialchars($contact['userid']);
                $passwd = htmlspecialchars($contact['passwd']);
                $str = <<<_FRIEND_
    <outline text="$id" url="$url" userid="$userid" passwd="$passwd">

_FRIEND_;
                fwrite($fh,$str);
            }
            fwrite($fh,$this->opml_footer());
            flock($fh,LOCK_UN);
        }
        fclose($fh);
    
        copy($filename,$this->filename($file));
        unlink($filename);
    
        ignore_user_abort(false);
    
        return 1;
    }

    function show_form() {
        print <<<_FORM_HEAD_
<center>
<form method="POST" action="?q=update_contacts">
<table class="table" cellpadding="5" width="80%">
<tr>
  <td class="title" colspan="4" align="center">
    Contacts URL</td>
  </tr>
<tr class="menu">
  <td valign="middle" width="5%">
    </td>
  <td valign="middle" width="55%" align="left">
    PonG URL</td>
  <td valign="middle" width="20%" align="left">
    Userid</td>
  <td valign="middle" width="20%" align="left">
    Password</td>
  </tr>
_FORM_HEAD_;

        foreach ($this->contacts as $id => $contact) {
            $url = htmlspecialchars($contact['url']);
            $userid = htmlspecialchars($contact['userid']);
            $passwd = htmlspecialchars($contact['passwd']);

            print <<<_CONTACT_
<tr>
  <td valign="middle" width="5%">
    <input type="checkbox" name="_$id"></td>
  <td valign="middle" width="55%" align="left">
    <input class="text" name="url$id" value="$url"></td>
  <td valign="middle" width="20%" align="left">
    <input class="customize" name="userid$id" value="$userid" size="14"></td>
  <td valign="middle" width="20%" align="left">
    <input class="customize" name="passwd$id" value="$passwd" size="14"></td>
  </tr>
_CONTACT_;
        }

        print <<<_FORM_TAIL_
<tr>
  <td colspan="4" align="center">
    <input class="customize" name=_add size="40"> &nbsp;
    <input class=button type=submit name=submit value=add> &nbsp;
    <input class=button type=submit name=submit value=delete> &nbsp; 
    <input class=button type=submit name=submit value=save>
    </td>
  </tr>
<tr>
  <td class="help" colspan="4" align="left">
    To add an contact, enter the PonG URL and click "Add". To delete an
    contact, check on the boxes on the left and click "Delete". 
    <p>
    Userid and Password are optional. If you don't have it, you can only
    access public information on the contact.
    <p>
    Click on "Address Book" on the top menu to view the contacts.
    </td>
  </tr>
</table>
</form>
</center>

_FORM_TAIL_;
        return 1;
    }
}

function cmd_show_contacts() {
    global $contacts;

    $contacts->show_form();

    return;
}

function cmd_update_contacts() {
    global $contacts,$config;

    if ($_REQUEST['submit'] == 'delete') {
        foreach ($contacts->contacts as $id => $v) {
            if ($_REQUEST["_".$id] == "on") 
                $contacts->del_contact($id);
        }
        showmsg("ok","Successfully deleted checked contacts.");
        $contacts->save();
    } else if ($_REQUEST['submit'] == 'add') {
        $url = $_REQUEST['_add'];

        if (!preg_match("/^(http|https)/",$url)) {
            showmsg("error","URL must start with http or https.");
        } else {
            $id = count($contacts->contacts);
            $contacts->add_contact($id,$config->get('userid'),'',$url);
            $contacts->save();
        }
    } else if ($_REQUEST['submit'] == 'save') {
        foreach ($contacts->contacts as $id => $v) {
            $url = $_REQUEST["url".$id];
            $userid = $_REQUEST["userid".$id];
            $passwd = $_REQUEST["passwd".$id];
            $contacts->add_contact($id,$userid,$passwd,$url);
        }
        showmsg("ok","Contacts URL saved");
        $contacts->save();
    } else {
        showmsg("error","Unknown request ${_REQUEST['submit']}");
    }

    return $contacts->show_form();
}

?>
