#!/usr/bin/env php
<?php
/**
 * This script migrates Nag's share data from the datatree Horde_Share
 * driver to the new SQL Horde_Share driver. You should run the 2.1_to_2.2.sql
 * upgrade script before executing this script.
 *
 * $Horde: nag/scripts/upgrades/convert_datatree_shares_to_sql.php,v 1.1.2.3 2008/05/23 02:28:40 chuck Exp $
 */

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

/* Set up the CLI environment */
require_once HORDE_BASE . '/lib/core.php';
require_once 'Horde/CLI.php';
if (!Horde_CLI::runningFromCli()) {
    exit("Must be run from the command line\n");
}
$cli = &Horde_CLI::singleton();
$cli->init();

/* Grab what we need to steal the DB config */
require_once HORDE_BASE . '/config/conf.php';
require_once 'MDB2.php';

$config = $GLOBALS['conf']['sql'];
unset($config['charset']);
$db = MDB2::factory($config);

$delete_dt_data = false;
$answer = $cli->prompt('Do you want to keep your old datatree data or delete it?', array('Keep', 'Delete'));
if ($answer == 1) {
    $delete_dt_data = true;
}
$answer = $cli->prompt(sprintf("Data will be copied into the new tables, and %s be deleted from the datatree.\n Is this what you want?", $delete_dt_data ? 'WILL' : 'WILL NOT'), array('y' => 'Yes', 'n' => 'No'));
if ($answer != 'y') {
    exit;
}

/* Get the share entries */
$sql = 'SELECT datatree_id, datatree_name FROM horde_datatree WHERE '
    . 'group_uid = \'horde.shares.nag\'';
$shares_result = $db->query($sql);
if (is_a($shares_result, 'PEAR_Error')) {
    die($shares_result->toString());
}

while ($row = $shares_result->fetchRow(MDB2_FETCHMODE_ASSOC)) {
    $share_id = $row['datatree_id'];
    $share_name = $row['datatree_name'];

    /* Build an array to hold the new row data */
    $data = array('share_id' => $db->nextId('nag_shares'),
                  'share_name' => $share_name);

    $sql = 'SELECT attribute_name, attribute_key, attribute_value FROM horde_datatree_attributes WHERE datatree_id = ?';
    $query = $db->prepare($sql);
    $query_result = $query->execute($share_id);
    $rows = $query_result->fetchAll(MDB2_FETCHMODE_ASSOC);
    $users = array();
    $groups = array();

    foreach ($rows as $row) {
        if ($row['attribute_name'] == 'perm_groups') {
            /* Group table entry */
            $groups[] = array('share_id' => $data['share_id'],
                              'group_uid' => $row['attribute_key'],
                              'perm' => $row['attribute_value']);
        } elseif ($row['attribute_name'] == 'perm_users') {
            /* User table entry */
            $users[] = array('share_id' => $data['share_id'],
                             'user_uid' => $row['attribute_key'],
                             'perm' => $row['attribute_value']);
        } else {
            /* Everything else goes in the main share table */
            switch ($row['attribute_name']) {
            case 'perm_creator':
            case 'perm_default':
            case 'perm_guest':
                $data[$row['attribute_name']] = $row['attribute_value'];
                break;

            case 'owner':
                $data['share_owner'] = $row['attribute_value'];
                break;

            case 'name':
                // Note the key to the $data array is not related to
                // the attribute_name field in the dt_attributes table.
                $data['attribute_name'] = $row['attribute_value'];
                break;

            case 'desc':
                $data['attribute_desc'] = $row['attribute_value'];
                break;
            }
        }
    }

    /* Set flags */
    $data['share_flags'] = 0;
    if (count($users)) {
        $data['share_flags'] |= 1;
    }
    if (count($groups)) {
        $data['share_flags'] |= 2;
    }

    /* Insert the new data */
    $cli->message('Migrating share data for share_id: ' . $share_id, 'cli.message');
    $result = insertData('nag_shares', $data);
    if (is_a($result, 'PEAR_Error')) {
        $cli->message($result->getMessage(), 'cli.error');
    }
    if (count($groups)) {
        foreach ($groups as $group) {
            $result = insertData('nag_shares_groups', $group);
            if (is_a($result, 'PEAR_Error')) {
                $cli->message($result->getMessage(), 'cli.error');
            }
        }
    }
    if (count($users)) {
        foreach ($users as $user) {
            $result = insertData('nag_shares_users', $user);
            if (is_a($result, 'PEAR_Error')) {
                $cli->message($result->getMessage(), 'cli.error');
            }
        }
    }

    /* Delete the datatree data, but ONLY if it was requested */
    if ($delete_dt_data) {
        $cli->message('DELETING datatree data for share_id: ' . $share_id, 'cli.message');
        $delete = $db->prepare('DELETE FROM horde_datatree_attributes WHERE datatree_id = ?', null, MDB2_PREPARE_MANIP);
        $delete->execute(array($share_id));
        $delete->free();

        $delete = $db->prepare('DELETE FROM horde_datatree WHERE datatree_id = ?', null, MDB2_PREPARE_MANIP);
        $delete->execute(array($share_id));
        $delete->free();
    }

    /* Cleanup */
    $query_result->free();
    unset($row, $rows, $data, $groups, $users);
}

/**
 * Helper function
 */
function insertData($table, $data)
{
    $fields = array_keys($data);
    $values = array_values($data);

    $insert = $GLOBALS['db']->prepare('INSERT INTO ' . $table . ' (' . implode(', ', $fields) . ') VALUES (' . str_repeat('?, ', count($values) - 1) . '?)',
                                      null, MDB2_PREPARE_MANIP);
    $insert_result = $insert->execute($values);
    $insert->free();
    return $insert_result;
}
