<?php
/**
 * $Horde: turba/data.php,v 1.12.2.17 2003/02/23 15:51:32 chuck Exp $
 *
 * Copyright 2001-2003 Jan Schneider <jan@horde.org>
 *
 * See the enclosed file COPYING for license information (GPL).  If you
 * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
 */

define('TURBA_BASE', dirname(__FILE__));
require_once TURBA_BASE . '/lib/base.php';
require_once TURBA_BASE . '/lib/Source.php';
require_once HORDE_BASE . '/lib/Data.php';
require TURBA_BASE . '/config/attributes.php';

if (!$conf['menu']['import_export']) {
    header('Location: ' . Horde::applicationUrl('index.php', true));
    exit;
}

$error = false;
$actionID = Horde::getFormData('actionID');

if ($actionID == HORDE_IMPORT) {

    $importID = Horde::getFormData('importID');
    $dates = array();

    if ($importID == IMPORT_MAPPED) {

        include_once HORDE_BASE . '/lib/SessionCache.php';
        $cache = new SessionCache();
        $cacheID = Horde::getFormData('cacheID');

        if (!isset($cacheID) || !(list($importData, $dest) = $cache->getObject($cacheID))) {
            Horde::raiseMessage(_("The data got lost."), HORDE_ERROR);
            $error = true;
        } else {
            $import_type = Horde::getFormData('import_type');
            $dataKeys = Horde::getFormData('dataKeys', '');
            $appKeys = Horde::getFormData('appKeys', '');
            if (empty($dataKeys) || empty($appKeys)) {
                Horde::raiseMessage(_("You didn't map any fields from the imported file to the corresponding fields in Turba."), HORDE_ERROR);
                $error = true;
            } else {
                $dataKeys = explode("\t", $dataKeys);
                $appKeys = explode("\t", $appKeys);
                $map = array();
                foreach ($appKeys as $key => $app) {
                    $map[$app] = $dataKeys[$key];
                    if ($attributes[$app]['type'] == 'date' ||
                        $attributes[$app]['type'] == 'time' ||
                        $attributes[$app]['type'] == 'datetime') {
                        $dates[$dataKeys[$key]]['type'] = $attributes[$app]['type'];
                        for ($i = 0; $i < min(count($importData), 10); $i++) {
                            if ($importData[$i][$dataKeys[$key]] != '') {
                                $dates[$dataKeys[$key]]['values'][] = $importData[$i][$dataKeys[$key]];
                            }
                        }
                    }
                }

                if (count($dates) > 0) {
                    $cacheID = $cache->putObject(array($importData, $dest, $map));
                }
            }
        }

    } elseif ($importID == IMPORT_DATETIME) {

        include_once HORDE_BASE . '/lib/SessionCache.php';
        $cache = new SessionCache();
        $cacheID = Horde::getFormData('cacheID');

        if (!isset($cacheID) || !($tmp = $cache->getObject($cacheID))) {
            Horde::raiseMessage(_("The data got lost"), HORDE_ERROR);
            $error = true;
        } else {
            $importData = $tmp[0];
            $dest = $tmp[1];
            $map = $tmp[2];
            $delimiter = Horde::getFormData('delimiter');
            $format = Horde::getFormData('format');
        }

    }


    if ($importID == IMPORT_MAPPED || $importID == IMPORT_DATETIME) {

        if (!$error && count($dates) == 0) {

            $driver = &Turba_Source::singleton($dest, $cfgSources[$dest]);
            if (PEAR::isError($driver)) {
                Horde::raiseMessage(_("Failed to connect to the specified directory."), HORDE_ERROR);
                $error = true;
            } else {
                foreach ($importData as $row) {
                    $hash = array();
                    reset($cfgSources[$dest]['map']);
                    while (list($key, ) = each($cfgSources[$dest]['map'])) {
                        if (isset($map[$key]) && !empty($row[$map[$key]])) {
                            if ($attributes[$key]['type'] == 'date' ||
                                $attributes[$key]['type'] == 'time' ||
                                $attributes[$key]['type'] == 'datetime') {
                                $dt_arr = Data::mapDate($row[$map[$key]], $attributes[$key]['type'], $delimiter[$map[$key]], $format[$map[$key]]);
                            }
                            if ($attributes[$key]['type'] == 'date' &&
                                $dt_arr['mday'] != 0 &&
                                $dt_arr['month'] != 0 &&
                                $dt_arr['year'] != 0) {
                                $hash[$key] = mktime(0, 0, 0, $dt_arr['month'], $dt_arr['mday'], $dt_arr['year']);
                            } elseif ($attributes[$key]['type'] == 'time') {
                                $hash[$key] = mktime($dt_arr['hour'], $dt_arr['min'], $dt_arr['sec'], 0, 0, 0);
                            } elseif ($attributes[$key]['type'] == 'datetime') {
                                $hash[$key] = mktime($dt_arr['hour'], $dt_arr['min'], $dt_arr['sec'], $dt_arr['month'], $dt_arr['mday'], $dt_arr['year']);
                            } else {
                                $hash[$key] = $row[$map[$key]];
                            }
                        }
                    }
                    $hash['__owner'] = Auth::getAuth();
                    if (!$driver->addObject($hash)) {
                        $error = true;
                    }
                }
            }

            if ($error) {
                Horde::raiseMessage(_("There was an error importing the data."), HORDE_ERROR);
            } else {
                $import_type = Horde::getFormData('import_type');
                switch ($import_type) {
                case IMPORT_CSV:
                    $type = 'CSV';
                    break;
                case IMPORT_TSV:
                    $type = 'TSV';
                    break;
                case IMPORT_OUTLOOK:
                    $type = 'Outlook';
                    break;
                }
                Horde::raiseMessage(sprintf(_("%s file successfully imported"), $type), HORDE_SUCCESS);
            }

        }

    } else {

        if (!isset($_FILES['import_file']['size']) ||
            !isset($_FILES['import_file']['tmp_name'])) {
            Horde::raiseMessage(_("There was a problem with the file upload. The file may have been larger than the maximum allowed size."), HORDE_ERROR);
            $error = true;
        } elseif (!is_uploaded_file($_FILES['import_file']['tmp_name'])) {
            Horde::raiseMessage(_("Illegal or malformed form data."), HORDE_ERROR);
            $error = true;
        } elseif ($_FILES['import_file']['size'] > 0) {
            _fileCleanup($_FILES['import_file']['tmp_name']);

            $header = null;
            switch ($importID) {

            case IMPORT_OUTLOOK:
                $header = true;

            case IMPORT_CSV:
                $csv = new Data_csv();
                if (!isset($header)) {
                    $header = Horde::getFormData('header');
                }
                $importData = $csv->importFile($_FILES['import_file']['tmp_name'], $header, ',');

                if (!isset($importData) || !is_array($importData)) {
                    Horde::raiseMessage(_("There was an error importing the uploaded file"), HORDE_ERROR);
                    $error = true;
                } else {
                    $dest = Horde::getFormData('dest');
                    include_once HORDE_BASE . '/lib/SessionCache.php';
                    $cache = new SessionCache();
                    $cacheID = $cache->putObject(array($importData, $dest));
                    $actionUrl = Horde::applicationUrl('data.php');

                    $appFields = array();
                    reset($cfgSources[$dest]['map']);
                    while (list($key, ) = each($cfgSources[$dest]['map'])) {
                        if (substr($key, 0, 2) != '__') {
                            $appFields[$key] = $attributes[$key]['desc'];
                        }
                    }
                }

                break;

            case IMPORT_TSV:
                $tsv = new Data_tsv();
                if (!isset($header)) {
                    $header = Horde::getFormData('header');
                }
                $importData = $tsv->importFile($_FILES['import_file']['tmp_name'], $header, "\t");

                if (!isset($importData) || !is_array($importData)) {
                    Horde::raiseMessage(_("There was an error importing the uploaded file"), HORDE_ERROR);
                    $error = true;
                } else {
                    $dest = Horde::getFormData('dest');
                    include_once HORDE_BASE . '/lib/SessionCache.php';
                    $cache = new SessionCache();
                    $cacheID = $cache->putObject(array($importData, $dest));
                    $actionUrl = Horde::applicationUrl('data.php');

                    $appFields = array();
                    reset($cfgSources[$dest]['map']);
                    while (list($key, ) = each($cfgSources[$dest]['map'])) {
                        if (substr($key, 0, 2) != '__') {
                            $appFields[$key] = $attributes[$key]['desc'];
                        }
                    }
                }

                break;

            case IMPORT_VCARD:
                $vcf = new Data_rfc2425();
                $data = $vcf->importFile($_FILES['import_file']['tmp_name']);
                $dest = Horde::getFormData('dest');
                $driver = &Turba_Source::singleton($dest, $cfgSources[$dest]);
                if (PEAR::isError($driver)) {
                    Horde::raiseMessage(_("Failed to connect to the specified directory."), HORDE_ERROR);
                    $error = true;
                } else {
                    $dest = $cfgSources[$dest]['map'];
                    foreach ($data as $object) {
                        if (strtoupper($object['type']) == 'VCARD') {
                            $hash = array();
                            foreach ($object['params'] as $item) {

                                switch ($item['name']) {

                                case 'FN':
                                    $hash['name'] = $vcf->read($item);
                                    break;

                                case 'NICKNAME':
                                    $hash['alias'] = $vcf->read($item);
                                    break;

                                    // We use LABEL but should probably use ADR.
                                case 'LABEL':
                                    if (isset($item['params']['HOME'])) {
                                        $hash['homeAddress'] = $vcf->read($item);
                                    } elseif (isset($item['params']['WORK'])) {
                                        $hash['workAddress'] = $vcf->read($item);
                                    } else {
                                        $hash['workAddress'] = $vcf->read($item);
                                    }
                                    break;

                                case 'TEL':
                                    if (isset($item['params']['VOICE'])) {
                                        if (isset($item['params']['HOME'])) {
                                            $hash['homePhone'] = $vcf->read($item);
                                        } elseif (isset($item['params']['WORK'])) {
                                            $hash['workPhone'] = $vcf->read($item);
                                        } elseif (isset($item['params']['CELL'])) {
                                            $hash['cellPhone'] = $vcf->read($item);
                                        }
                                    } elseif (isset($item['params']['FAX'])) {
                                        $hash['fax'] = $vcf->read($item);
                                    }
                                    break;

                                case 'EMAIL':
                                    if (isset($item['params']['PREF']) || !isset($hash['email'])) {
                                        $hash['email'] = Turba::getBareEmail($vcf->read($item));
                                    }
                                    break;

                                case 'TITLE':
                                    $hash['title'] = $vcf->read($item);
                                    break;

                                case 'ORG':
                                    $units = array();
                                    for ($i = 0; $i < count($item['values']); $i++) {
                                        $units[] = $vcf->read($item, $i);
                                    }
                                    $hash['company'] = implode(', ', $units);
                                    break;

                                case 'NOTE':
                                    $hash['notes'] = $vcf->read($item);
                                    break;

                                }

                            }
                            $hash['__owner'] = Auth::getAuth();
                            if (!$driver->addObject($hash)) {
                                $error = true;
                            }
                        }
                    }
                }

                if ($error) {
                    Horde::raiseMessage(_("There was an error importing the data."), HORDE_ERROR);
                } else {
                    Horde::raiseMessage(sprintf(_("%s file successfully imported"), 'vCard'), HORDE_SUCCESS);
                }

                break;

            case IMPORT_MULBERRY:
                $mulberry = new Data_tsv();
                $importData = $mulberry->importFile($_FILES['import_file']['tmp_name']);
                $dest = Horde::getFormData('dest');
                $driver = &Turba_Source::singleton($dest, $cfgSources[$dest]);
                if (!isset($importData) || !is_array($importData)) {
                    Horde::raiseMessage(_("There was an error importing the uploaded file"), HORDE_ERROR);
                    $error = true;
                } elseif (PEAR::isError($driver)) {
                    Horde::raiseMessage(_("Failed to connect to the specified directory."), HORDE_ERROR);
                    $error = true;
                } else {
                    include_once HORDE_BASE . '/lib/SessionCache.php';
                    $cache = new SessionCache();
                    $cacheID = $cache->putObject(array($importData, $dest));
                    if (!isset($cacheID) || !(list($importData, $dest) = $cache->getObject($cacheID))) {
                        Horde::raiseMessage(_("The data got lost."), HORDE_ERROR);
                        $error = true;
                    } else {
                        $import_type = Horde::getFormData('import_type');
                        $appKeys = array('alias', 'name', 'email', 'company', 'workAddress', 'workPhone', 'homePhone', 'fax', 'notes');
                        $dataKeys = array(0, 1, 2, 3, 4, 5, 6, 7, 9);
                        $map = array();
                        foreach ($appKeys as $key => $app) {
                            $map[$app] = $dataKeys[$key];
                        }
                        foreach ($importData as $row) {
                            $hash = array();
                            reset($cfgSources[$dest]['map']);
                            if (preg_match("/^Grp:/", $row[0])) {
                                continue;
                            }
                            $row[1] = preg_replace('/^([^,"]+),\s*(.*)$/', '$2 $1', $row[1]);
                            while (list($key,) = each($cfgSources[$dest]['map'])) {
                                if (isset($map[$key]) && !empty($row[$map[$key]])) {
                                    $hash[$key] = stripslashes(preg_replace('/\\\\r/', "\n", $row[$map[$key]]));
                                }
                            }
                            $hash['__owner'] = Auth::getAuth();
                            if (!$driver->addObject($hash)) {
                                $error = true;
                            }
                        }
                    }
                }

                if ($error) {
                    Horde::raiseMessage(_("There was an error importing the data."), HORDE_ERROR);
                } else {
                    Horde::raiseMessage(_("Mulberry addressbook sucessfully imported"), HORDE_SUCCESS);
                }

            break;

            case IMPORT_PINE:
                $pine = new Data_tsv();
                $importData = $pine->importFile($_FILES['import_file']['tmp_name']);
                $dest = Horde::getFormData('dest');
                $driver = &Turba_Source::singleton($dest, $cfgSources[$dest]);
                if (!isset($importData) || !is_array($importData)) {
                    Horde::raiseMessage(_("There was an error importing the uploaded file"), HORDE_ERROR);
                    $error = true;
                } elseif (PEAR::isError($driver)) {
                    Horde::raiseMessage(_("Failed to connect to the specified directory."), HORDE_ERROR);
                    $error = true;
                } else {
                    include_once HORDE_BASE . '/lib/SessionCache.php';
                    $cache = new SessionCache();
                    $cacheID = $cache->putObject(array($importData, $dest));
                    if (!isset($cacheID) || !(list($importData, $dest) = $cache->getObject($cacheID))) {
                        Horde::raiseMessage(_("The data got lost."), HORDE_ERROR);
                        $error = true;
                    } else {
                        $import_type = Horde::getFormData('import_type');
                        $appKeys = array('alias', 'name', 'email', 'notes');
                        $dataKeys = array(0, 1, 2, 4);
                        $map = array();
                        foreach ($appKeys as $key => $app) {
                            $map[$app] = $dataKeys[$key];
                        }
                        foreach ($importData as $row) {
                            $hash = array();
                            reset($cfgSources[$dest]['map']);
                            if (count($row) < 3 || preg_match("/^#DELETED/", $row[0]) || preg_match("/[()]/", $row[2])) {
                                continue;
                            }
                            $row[1] = preg_replace('/^([^,"]+),\s*(.*)$/', '$2 $1', $row[1]);
                            while (list($key, ) = each($cfgSources[$dest]['map'])) {
                                if (isset($map[$key]) && !empty($row[$map[$key]])) {
                                    $hash[$key] = $row[$map[$key]];
                                }
                            }
                            $hash['__owner'] = Auth::getAuth();
                            if (!$driver->addObject($hash)) {
                                $error = true;
                            }
                        }
                    }
                }

                if ($error) {
                    Horde::raiseMessage(_("There was an error importing the data."), HORDE_ERROR);
                } else {
                    Horde::raiseMessage(_("Pine addressbook sucessfully imported"), HORDE_SUCCESS);
                }

            break;

            }

        } else {
            Horde::raiseMessage(_("The file contained no data."), HORDE_ERROR);
            $error = true;
        }
    }

} elseif ($actionID == HORDE_EXPORT) {
    $exportID = Horde::getFormData('exportID');

    switch ($exportID) {

    case EXPORT_CSV:
        $source = Horde::getFormData('source');
        if (!isset($source) && isset($cfgSources) && is_array($cfgSources) && count($cfgSources) > 0) {
            reset($cfgSources);
            $source = key($cfgSources);
        }

        $driver = &Turba_Source::singleton($source, $cfgSources[$source]);
        if (PEAR::isError($driver)) {
            Horde::raiseMessage(_("Failed to connect to the specified directory."), HORDE_ERROR);
            $error = true;
        } else {
            if (get_class($addresses = $driver->search(array())) != 'turba_list') {
                Horde::raiseMessage(sprintf(_("Failed to search the directory: %s"), $driver->error()), HORDE_ERROR);
                $error = true;
            } else {
                $data = array();
                while ($ob = $addresses->next()) {
                    $tmp = $ob->getAttributes();
                    $row = array();
                    foreach ($tmp as $key => $attribute) {
                        if (substr($key, 0, 2) != '__') {
                            $row[$key] = $attribute;
                        }
                    }
                    $data[] = $row;
                }

                $csv = new Data_csv();
                $csv->exportFile('turba.csv', $data, true);
                exit;
            }
        }
        break;


    case EXPORT_TSV:
        $source = Horde::getFormData('source');
        if (!isset($source) && isset($cfgSources) && is_array($cfgSources) && count($cfgSources) > 0) {
            reset($cfgSources);
            $source = key($cfgSources);
        }

        $driver = &Turba_Source::singleton($source, $cfgSources[$source]);
        if (PEAR::isError($driver)) {
            Horde::raiseMessage(_("Failed to connect to the specified directory."), HORDE_ERROR);
            $error = true;
        } else {
            if (get_class($addresses = $driver->search(array())) != 'turba_list') {
                Horde::raiseMessage(sprintf(_("Failed to search the directory: %s"), $driver->error()), HORDE_ERROR);
                $error = true;
            } else {
                $data = array();
                while ($ob = $addresses->next()) {
                    $tmp = $ob->getAttributes();
                    $row = array();
                    foreach ($tmp as $key => $attribute) {
                        if (substr($key, 0, 2) != '__') {
                            $row[$key] = $attribute;
                        }
                    }
                    $data[] = $row;
                }

                $tsv = new Data_tsv();
                $tsv->exportFile('turba.tsv', $data, true);
                exit;
            }
        }
        break;

    }
}

$title = _("Import/Export Addressbooks");
$js_onLoad = null;
require TURBA_TEMPLATES . '/common-header.inc';
require TURBA_BASE . '/menu.php';
require TURBA_BASE . '/status.php';

if (is_null($actionID) || $error) {
    /* Build the directory sources select widget. */
    $source_options = '';
    foreach ($cfgSources as $key => $entry) {
        if (!empty($entry['export'])) {
            $source_options .= "<option value=\"$key\">";
            $source_options .= $entry['title'] . "</option>\n";
        }
    }

    /* Build the directory destination select widget. */
    $dest_options = '';
    $hasWriteable = false;
    foreach ($cfgSources as $key => $entry) {
        if (empty($entry['readonly']) || (isset($entry['admin']) && in_array(Auth::getAuth(), $entry['admin']))) {
            $dest_options .= "<option value=\"$key\">";
            $dest_options .= $entry['title'] . "</option>\n";
            $hasWriteable = true;
        }
    }

    if ($hasWriteable) {
        include TURBA_TEMPLATES . '/data/import.inc';
    }
    include TURBA_TEMPLATES . '/data/export.inc';
} else {
    switch ($importID) {

    case IMPORT_OUTLOOK:
    case IMPORT_CSV:
    case IMPORT_TSV:
        include $registry->getParam('templates', 'horde') . '/data/csvmap.inc';
        break;

    case IMPORT_MAPPED:
        if (count($dates) > 0) {
            $actionUrl = Horde::applicationUrl('data.php');
            include $registry->getParam('templates', 'horde') . '/data/datemap.inc';
        }
        break;

    }
}

$registry->shutdown();
require TURBA_TEMPLATES . '/common-footer.inc';
