#!/usr/local/bin/php
<?php
/**
 * This script imports SquirrelMail file-based preferences into Horde.
 * It was developed against SquirrelMail 1.4.0, so use at your own risk
 * against different versions.
 *
 * Input can be either a single squirrelmail .pref file, or a directory
 * containing multiple .pref files.
 *
 * $Horde: horde/scripts/import_squirrelmail_prefs.php,v 1.3.2.2 2008/01/02 11:32:33 jan Exp $
 *
 * Copyright 2007-2008 The Horde Project (http://www.horde.org/)
 *
 * See the enclosed file LICENSE for license information (ASL).  If you
 * did not receive this file, see http://www.horde.org/licenses/asl.php.
 *
 * @author Ben Chavet <ben@horde.org>
 */

@define('AUTH_HANDLER', true);
@define('HORDE_BASE', dirname(__FILE__) . '/..');

// Do CLI checks and environment setup first.
require_once HORDE_BASE . '/lib/core.php';
require_once 'Horde/CLI.php';

// Makre sure no one runs this from the web.
if (!Horde_CLI::runningFromCli()) {
    exit("Must be run from the command line\n");
}

// Load the CLI environment - make sure there's no time limit, init some
// variables, etc.
$cli = &Horde_CLI::singleton();
$cli->init();

// Read command line parameters.
if (count($argv) != 2) {
    $cli->message('Too many or too few parameters.', 'cli.error');
    $cli->writeln('Usage: import_squirrelmail_prefs.php path-to-squirrelmail-data');
    exit;
}
$data = $argv[1];

// Make sure we load Horde base to get the auth config
require_once HORDE_BASE . '/lib/base.php';

// Get list of SquirrelMail pref files
if (is_dir($data)) {
    $files = array();
    if ($handle = opendir($data)) {
        while (false !== ($file = readdir($handle))) {
            if (preg_match('/.pref$/', $file)) {
                $files[] = $data . '/' . $file;
            }
        }
        closedir($handle);
    } else {
        exit;
    }
} else {
    $files = array($data);
}

// Loop through SquirrelMail pref files
$auth = &Auth::singleton($conf['auth']['driver']);
foreach($files as $file) {
    if ($handle = fopen($file, 'r')) {

        // Set current user
        $user = substr(basename($file), 0, -5);
        $auth->setAuth($user, array());
        $cli->message('Importing ' . $user . '\'s preferences');

        // Reset user prefs
        unset($prefs);
        $prefs = &Prefs::factory($conf['prefs']['driver'], 'horde', $user, null, null, false);
        unset($prefs_cache);
        $prefs_cache = array();

        // Read pref file, one line at a time
        while (!feof($handle)) {
            $buffer = fgets($handle);
            if (!empty($buffer)) {

                /**
                 * BEGIN: Code from squirrelmail to parse pref (GPL)
                 */
                $pref = trim($buffer);
                $equalsAt = strpos($pref, '=');
                if ($equalsAt > 0) {
                    $key = substr($pref, 0, $equalsAt);
                    $value = substr($pref, $equalsAt + 1);
                    /* this is to 'rescue' old-style highlighting rules. */
                    if (substr($key, 0, 9) == 'highlight') {
                        $key = 'highlight' . $highlight_num;
                        $highlight_num ++;
                    }

                    if ($value != '') {
                        $prefs_cache[$key] = $value;
                    }
                }
                /**
                 * END: Code from squirrelmail to parse pref (GPL)
                 */

            }
        }

        fclose($handle);

        // Load default SquirrelMail signature
        $prefs_cache['signature'] = getSignature(substr($file, 0, -5));

        // Loop through the SquirrelMail prefs and translate them to Horde prefs
        foreach ($prefs_cache as $key => $val) {
            $horde_pref = convert($key, $val);

            if ($horde_pref) {
                foreach ($horde_pref as $pref) {
                    // Load prefs scope
                    $prefs->retrieve($pref['scope']);
                    
                    // Set pref value
                    $prefs->setValue($pref['name'], $pref['value']);
                }
            }

        }

        // Import identities
        if (isset($prefs_cache['identities']) && $prefs_cache['identities'] > 1) {
            require_once 'Horde/Identity.php';
            $identity = &Identity::singleton(array('imp', 'imp'), $user);
            for ($i = 1; $i < $prefs_cache['identities']; $i++) { // Intentionally off-by-one
                $new_identity = array('id' => 'Identity #' . ($i + 1),
                                      'fullname' => $prefs_cache['full_name' . $i],
                                      'replyto_addr' => $prefs_cache['reply_to' . $i],
                                      'from_addr' => $prefs_cache['email_address' . $i],
                                      'signature' => getSignature(substr($file, 0, -5), $i));
                if (isset($prefs_cache['prefix_sig'])) {
                    $new_identity['sig_dashes'] = $prefs_cache['prefix_sig'];
                }
                if (isset($prefs_cache['sig_first'])) {
                    $new_identity['sig_first'] = $prefs_cache['sig_first'];
                }
                if (isset($prefs_cache['sent_folder'])) {
                    if ($prefs_cache['sent_folder'] == '[ ' . _("Do not use Sent") . ' ]') {
                        $new_identity['save_sent_mail'] = 0;
                    } else {
                        $new_identity['save_sent_mail'] = 1;
                    }
                }
                $identity->add($new_identity);
            }
            $identity->save();
        }

        // Store prefs
        $prefs->store();

    }
}

/**
 * Returns the horde pref value(s) that correspond with the given squirrelmail
 * pref.
 *
 * @return array of pref arrays ('name', 'scope', 'value').
 *         false if there is no horde pref equivalent, or the horde default
 *           should be used.
 */
function convert($sm_pref_name, $sm_pref_value)
{

    switch ($sm_pref_name) {

    case 'compose_new_win':
        return array(array('name' => 'compose_popup', 'scope' => 'imp', 'value' => $sm_pref_value));
        break;

    case 'draft_folder':
        if ($sm_pref_value != '[ ' . _("Do not use Drafts") . ' ]') {
            return array(array('name' => 'drafts_folder', 'scope' => 'imp', 'value' => $sm_pref_value));
        }
        break;

    case 'email_address':
        return array(array('name' => 'from_addr', 'scope' => 'horde', 'value' => $sm_pref_value));
        break;

    case 'full_name':
        return array(array('name' => 'fullname', 'scope' => 'horde', 'value' => $sm_pref_value));
        break;

    case 'hour_format':
        return array(array('name' => 'twentyFour', 'scope' => 'horde', 'value' => ($sm_pref_value == 1)));
        break;
                     
    case 'internal_date_sort':
        if ($sm_pref_value == 1) {
            return array(array('name' => 'sortby', 'scope' => 'imp', 'value' => '1'));
        }
        break;

    case 'language':
        return array(array('name' => 'language', 'scope' => 'horde', 'value' => $sm_pref_value));
        break;

    case 'left_refresh':
        return array(array('name' => 'menu_refresh_time', 'scope' => 'horde', 'value' => $sm_pref_value));
        break;

    case 'left_size':
        return array(array('name' => 'sidebar_width', 'scope' => 'horde', 'value' => $sm_pref_value));
        break;

    case 'mdn_user_support':
        $value = 'ask';
        if ($sm_pref_value == 0) {
            $value = 'never';
        }
        return array(array('name' => 'disposition_request_read',
                           'scope' => 'imp',
                           'value' => $value));
        break;

    case 'prefix_sig':
        return array(array('name' => 'sig_dashes', 'scope' => 'imp', 'value' => $sm_pref_value));
        break;

    case 'reply_citation_style':
        switch ($sm_pref_value) {
        case 'none':
            return array(array('name' => 'attrib_text', 'scope' => 'imp', 'value' => ''));
            break;
        case 'author_said':
            return array(array('name' => 'attrib_text', 'scope' => 'imp', 'value' => '%p wrote'));
            break;
        case 'date_time_author':
            return array(array('name' => 'attrib_text', 'scope' => 'imp', 'value' => 'On %c, %p wrote'));
            break;
        }
        break;

    case 'reply_to':
        return array(array('name' => 'replyto_addr', 'scope' => 'imp', 'value' => $sm_pref_value));
        break;

    case 'sent_folder':
        if ($sm_pref_value == '[ ' . _("Do not use Sent") . ' ]') {
            return array(array('name' => 'save_sent_mail', 'scope' => 'imp', 'value' => '0'));
        }
        return array(array('name' => 'save_sent_mail', 'scope' => 'imp', 'value' => '1'),
                     array('name' => 'sent_mail_folder', 'scope' => 'imp', 'value' => $sm_pref_value));
        break;

    case 'show_num':
        return array(array('name' => 'max_msgs', 'scope' => 'imp', 'value' => $sm_pref_value));
        break;

    case 'show_xmailer_default':
        if ($sm_pref_value == 1) {
            $GLOBALS['prefs']->retrieve('imp');
            $value = "X-Mailer\n" . $GLOBALS['prefs']->getValue('mail_hdr');
            return array(array('name' => 'mail_hdr', 'scope' => 'imp', 'value' => trim($value)));
        }
        break;

    case 'sig_first':
        return array(array('name' => 'sig_first', 'scope' => 'imp', 'value' => $sm_pref_value));
        break;

    case 'signature':
        return array(array('name' => 'signature', 'scope' => 'imp', 'value' => $sm_pref_value));
        break;

    case 'sort_by_ref':
        if ($sm_pref_value == 1) {
            return array(array('name' => 'sortby', 'scope' => 'imp', 'value' => '161'));
        }
        break;

    case 'timezone':
        return array(array('name' => 'timezone', 'scope' => 'horde', 'value' => $sm_pref_value));
        break;

    case 'trash_folder':
        if ($sm_pref_value == '[ ' . _("Do not use Trash") . ' ]') {
            return array(array('name' => 'use_trash', 'scope' => 'imp', 'value' => '0'));
        }
        return array(array('name' => 'use_trash', 'scope' => 'imp', 'value' => '1'),
                     array('name' => 'trash_folder', 'scope' => 'imp', 'value' => $sm_pref_value));
        break;

    case 'unseen_notify':
        if ($sm_pref_value == 2) {
            return array(array('name' => 'nav_poll_all', 'scope' => 'imp', 'value' => false));
        } else if ($sm_pref_value == 3) {
            return array(array('name' => 'nav_poll_all', 'scope' => 'imp', 'value' => true));
        }
        break;

    case 'use_signature':
        if ($sm_pref_value == 0) {
            return array(array('name' => 'signature', 'scope' => 'imp', 'value' => ''));
        }
        break;

    // The rest of the SquirrelMail options do not translate
    default:
        return false;
    }

    // Default to no conversion.
    return false;
}

function getSignature($basename, $number = 'g')
{
    $sigfile = $basename . '.si' . $number;
    $signature = '';
    if (file_exists($sigfile)) {
        if ($handle = @fopen($sigfile, 'r')) {
            while (!feof($handle)) {
                $signature .= fgets($handle, 1024);
            }
            fclose($handle);
        }
    }
    return $signature;
}
