# ==================================================================
# Gossamer Links - enhanced directory management system
#
#	Website  : http://gossamer-threads.com/
#	Support  : http://gossamer-threads.com/scripts/support/
#	Revision : $Id: CGI.pm,v 1.17 2005/04/05 08:44:30 brewt Exp $
#
# Copyright (c) 2001 Gossamer Threads Inc.  All Rights Reserved.
# Redistribution in part or in whole strictly prohibited. Please
# see LICENSE file for full details.
# ==================================================================

package Links::Import::Interface::CGI;
# ==================================================================

use strict;
use Links qw/$IN $CFG/;

sub new {
    my $this = shift;
    my $class = ref($this) || $this;
    my $self = {};
    bless $self, $class;
    return $self;
}

sub isin {
    my $val = shift;
    for (@_) {
        return 1 if $val eq $_;
    }
    return undef;
}

sub html_escape {
    shift if ref $_[0];
    my $to_escape = shift;
    $to_escape = "" unless defined $to_escape;
    $to_escape =~ s/&/&amp;/g;
    $to_escape =~ s/ /&nbsp;/g;
    $to_escape =~ s/</&lt;/g;
    $to_escape =~ s/>/&gt;/g;
    $to_escape =~ s/"/&quot;/g;
    $to_escape;
}

sub make_opts {
    my $self = shift;
    return if ref $self->{cgi} eq 'HASH';
    $self->{cgi} = { };
    $self->{cgi}{help} = 1, return if $IN->param("help");
    return unless $IN->param("Interface_CGI");

    $self->{cgi}{transfer} = isin($IN->param("transfer"),qw/L1S2 L2S2 S1S2 BKS2 S2BK/)
                               ? $IN->param("transfer")
                               : "";

    for ($IN->param) { $self->{cgi}{$_} = $IN->param($_); }
}

sub get_options {
    my $self = shift;
    $self->make_opts;
    return wantarray ? (help => 1) : { help => 1 } if $self->{cgi}{'help'};
    $self->start_page(),exit unless $IN->param("Interface_CGI");
    if ($self->{cgi}{'errors_to_browser'}) {
        if ($self->{cgi}{error_file}) {
            my $fh = \do { local *FH; *FH };
            unless (open $fh, "> $self->{cgi}{error_file}") {
                _print_headers();
                print "<pre>Unable to open error file @{[html_pre_format(qq($self->{cgi}{error_file}: $!))]}</pre>";
                exit;
            }
            $self->{cgi}{error_file} = sub {
                for (@_) {
                    print html_pre_format("Import error: $_\n");
                    print $fh "Import error: $_\n";
                }
            }
        }
        else {
            $self->{cgi}{error_file} = sub {
                for (@_) {
                    print html_pre_format("Import error: $_\n");
                }
            }
        }
    }
    else {
        $self->{cgi}{error_file} = 'STDOUT';
    }
    return wantarray ? %{$self->{cgi}} : $self->{cgi};
}

sub usage ($$$) {
    my $self = shift;
    push @{$self->{usage_list}}, shift if @_;
# Don't care about the third argument; it is exclusively for Interface::Text
}

sub has_usage {
    my $self = shift;
    return ref $self->{usage_list} ? scalar @{$self->{usage_list}} : undef;
}

sub show_usage {
    my $self = shift;
    $self->start_page(1);
}

sub pre_import {
    require Links;
    _print_headers();
    print "<html>\n<head>\n<title>Import Results</title>\n</head>\n<body bgcolor=#FFFFFF>\n";
    print Links::header("Import/Export", "Please be patient, this can take a while...");
    print "<blockquote><pre>";
}

sub finished {
    print "</pre></blockquote>\n<b><font face='Tahoma,Arial,Helvetica' size=2>Data has been successfully import/exported!</font></b>\n</body>\n</html>";
    exit;
}

# Takes one optional argument which, if true, will make it print usage messages
sub start_page {
    my $self = shift;
    $self->make_opts unless ref $self->{cgi} eq 'HASH';
    _print_headers();
    $self->_start_page_top;
    if (shift and ref $self->{usage_list} and @{$self->{usage_list}}) {
        print "\n\n<ul>\n";
        for (@{$self->{usage_list}}) {
            print "  <li><font color=red><b>$_&nbsp;</b></font></li>\n";
        }
        print "</ul>\n\n";
    }
    $self->_start_page_bottom;
    exit;
}

sub _start_page_top {
    print <<'HTML';
<html>

<head>
<title>Gossamer Links Import</title>
</head>

<body bgcolor="#FFFFFF">
<table border="1" cellpadding="0" cellspacing="0"><tr><td>
	<table bgColor="#ffffff" border="0" cellPadding="3" cellSpacing="3" width="500" valign="top">
	  <tr>
		<td align="left" bgColor="navy"><b><font color="#ffffff" size="2" face="Tahoma,Arial,Helvetica">Gossamer Links Import/Backup/Restore</font></b></td>
	  </tr>
	  <tr>
		<td>
		  <p align="center"><b><font color="#000000" size="2" face="Tahoma,Arial,Helvetica">Gossamer Links Import/Backup/Restore</font></b></p>
		  <p><font size="2" face="Tahoma,Arial,Helvetica">This tool will allow you to easily migrate from a previous
		  version of Links, or backup and restore your data. For more information on the specific options, please
		  consult the <b><a href="nph-import.cgi?help=1&Interface_CGI=1">Help</a></b></font></td>
	  </tr>
	</table>
	</td></tr>
</table>

HTML
}

sub _start_page_bottom {
    my $self = shift;
    print qq[
  <form action="nph-import.cgi" method="POST">
  <input type=hidden name="Interface_CGI" value=1>
  <input type="hidden" name="destination" value="$CFG->{admin_root_path}/defs">
  <table border="1" cellspacing="0" cellpadding="0"><tr><td>
  <table border="0" cellspacing="0" cellpadding="3" width=500>
    <tr>
      <td colspan="2" bgcolor="#DDDDDD"><b><font face="Tahoma,Arial,Helvetica" size="2">Import Data from previous versions of Links</font></b></td>
    </tr>
    <tr>
      <td valign="top" align="left">
        <font face="Tahoma,Arial,Helvetica" size="2">
          Import From:&nbsp;&nbsp;
        </font>
      </td>
      <td valign="top" align="left"><font face="Tahoma,Arial,Helvetica" size="2">
        <select size="1" name="transfer" style="font-family: Tahoma, Arial, Helvetica; font-size: 10pt; color: #000000">
          <option ];
    print "selected " if $self->{cgi}{transfer} and $self->{cgi}{transfer} eq "S1S2";
    print qq[value="S1S2">Links SQL 1.x</option>
          <option ];
    print "selected " if $self->{cgi}{transfer} and $self->{cgi}{transfer} eq "L1S2";
    print qq[value="L1S2">Links 1.x</option>
          <option ];
    print "selected " if $self->{cgi}{transfer} and $self->{cgi}{transfer} eq "L2S2";
    print qq[value="L2S2">Links 2.x</option>
        </select></font>
      </td>
    </tr>
    <tr>
      <td valign="top" align="left">
        <font face="Tahoma,Arial,Helvetica" size="2">
          Location of def files:
        </font>
      </td>
      <td valign="top" align="left">
        <input type="text" name="source" size="40" ];
    print qq[value="].html_escape($self->{cgi}{source}).qq[" ] if $self->{cgi}{source} && ($self->{cgi}{transfer} =~ /^(?:L[12]|S1)S2$/);
    print qq[style="font-family: Tahoma, Arial, Helvetica; font-size: 10pt">
      </td>
    </tr>
    <tr>
      <td valign="top" align="left">
        <font face="Tahoma,Arial,Helvetica" size="2">
          Error File (optional):
        </font>
      </td>
      <td valign="top" align="left">
        <input type="text" name="error_file" size="40" ];
    print qq[value="].html_escape($self->{cgi}{error_file}).qq[" ] if $self->{cgi}{error_file} && ($self->{cgi}{transfer} =~ /^(?:L[12]|S1)S2$/);
    print qq[style="font-family: Tahoma, Arial, Helvetica; font-size: 10pt">
      </td>
    </tr>
  </table>
  <table border="0" cellspacing="0" width="100%">
    <tr>
	  <td valign="top" align="left" colspan="6">
        <font face="Tahoma,Arial,Helvetica" size="2">
		  <br><b>Options:</b>
		</font>
	   </td>
	</tr>
    <tr>
      <td valign="top" align="left">
        <font face="Tahoma,Arial,Helvetica" size="2">
          <input type="checkbox" name="show_mild_warnings" value=1];
    print " checked" if $self->{cgi}{show_mild_warnings};
    print qq[>
          Show Mild Warnings
        </font>
      </td>
      <td valign="top" align="left" colspan=2>
        <font face="Tahoma,Arial,Helvetica" size="2">
          <input type="checkbox" name="critical_warnings" value=1];
    print " checked" if $self->{cgi}{critical_warnings};
    print qq[>
          Critical Warnings
        </font>
      </td>
      <td valign="top" align="left">
        <font face="Tahoma,Arial,Helvetica" size="2">
          <input type="checkbox" name="data_integrity" value=1];
    print " checked" if $self->{cgi}{data_integrity};
    print qq[>
          Extra Data Integrity
        </font>
      </td>
    </tr>
    <tr>
      <td valign="top" align="left">
        <font face="Tahoma,Arial,Helvetica" size="2">
          <input type="checkbox" name="clear_tables" value=1];
    print " checked" if not keys %{$self->{cgi}} or $self->{cgi}{clear_tables} and ($self->{cgi}{transfer} =~ /^(?:L[12]|S1)S2$/);
    print qq[>
          Clear Tables
        </font>
      </td>
      <td valign="top" align="left" colspan=2>
        <font face="Tahoma,Arial,Helvetica" size="2">
          <input type="checkbox" name="errors_to_browser" value=1];
    print " checked" if ($self->{cgi}{errors_to_browser} or not keys %{$self->{cgi}});
    print qq[>
          Show Errors
        </font>
      </td>
      <td valign="top" align="left">
        <font face="Tahoma,Arial,Helvetica" size="2">
          <input type="checkbox" name="straight_import" value=1];
    print " checked" if $self->{cgi}{straight_import};
    print qq[>
          Straight Import
        </font>
      </td>
    </tr>
    <tr>
      <td valign=top align=left colspan=2>
        <font face="Tahoma,Arial,Helvetica" size=2>
          <input type="checkbox" name="create_columns" value=1];
    print " checked" if $self->{cgi}{create_columns} or not keys %{$self->{cgi}};
    print qq[>
          Recreate Non-standard Columns
        </font>
      </td>
      <td valign=top align=left colspan=2>
        <font face="Tahoma,Arial,Helvetica" size=2>
          <input type=checkbox name=create_missing_categories value=1];
    print " checked" if $self->{cgi}{create_missing_categories} or not keys %{$self->{cgi}};
    print qq[>
          Create Missing Categories
        </font>
      </td>
    </tr>
    <tr>
        <td colspan="8"><br><center><input type="submit" value="Import Data"></center><br></td>
    </tr>
  </table>
  </td></tr></table>
  </form>
  <br>

  <form action="nph-import.cgi" method="POST">
  <input type=hidden name="Interface_CGI" value=1>
  <input type="hidden" name="source" value="$CFG->{admin_root_path}/defs">
  <input type="hidden" name="transfer" value="S2BK">
  <input type="hidden" name="delimiter" value="|">
  <table border="1" cellspacing="0" cellpadding="0"><tr><td>
  <table border="0" cellspacing="0" cellpadding="3" width=500>
    <tr>
      <td colspan="2" bgcolor="#DDDDDD"><b><font face="Tahoma,Arial,Helvetica" size="2">Create backup file of all Gossamer Links data</font></b></td>
    </tr>
    <tr>
      <td valign="top" align="left">
        <font face="Tahoma,Arial,Helvetica" size="2">
          Location of Backup File:
        </font>
      </td>
      <td valign="top" align="left">
        <input type="text" name="destination" size="40" ];
    print qq[value="].html_escape($self->{cgi}{destination}).qq[" ] if $self->{cgi}{destination} && ($self->{cgi}{transfer} eq 'S2BK');
    print qq[style="font-family: Tahoma, Arial, Helvetica; font-size: 10pt">
      </td>
    </tr>
    <tr>
        <td colspan="2"><br><center><input type="submit" value="Backup Data"></center><br></td>
    </tr>
  </table>
  </td></tr></table>
  </form>
  <br>

  <form action="nph-import.cgi" method="POST">
  <input type=hidden name="Interface_CGI" value=1>
  <input type="hidden" name="destination" value="$CFG->{admin_root_path}/defs">
  <input type="hidden" name="transfer" value="BKS2">
  <input type="hidden" name="delimiter" value="|">
  <input type="hidden" name="clear_tables" value="1">
  <table border="1" cellspacing="0" cellpadding="0"><tr><td>
  <table border="0" cellspacing="0" cellpadding="3" width=500>
    <tr>
      <td colspan="2" bgcolor="#DDDDDD"><b><font face="Tahoma,Arial,Helvetica" size="2">Restore Gossamer Links from backup file</font></b></td>
    </tr>
    <tr>
      <td valign="top" align="left">
        <font face="Tahoma,Arial,Helvetica" size="2">
          Location of Backup File:
        </font>
      </td>
      <td valign="top" align="left">
        <input type="text" name="source" size="40" ];
    print qq[value="].html_escape($self->{cgi}{source}).qq[" ] if $self->{cgi}{source} && ($self->{cgi}{transfer} eq 'BKS2');
    print qq[style="font-family: Tahoma, Arial, Helvetica; font-size: 10pt">
      </td>
    </tr>
    <tr>
        <td colspan="2"><br><center><input type="submit" value="Restore Data"></center><br></td>
    </tr>
  </table>
  </td></tr></table>
  </form>
  <br><br>

</form>
</body>

</html>
];
}

sub show_help {
    my $self = shift;
    _print_headers();
    print <<'HTML';
<html>

<head>
<title>Gossamer Links Import Help</title>
</head>

<body bgcolor="#FFFFFF">
<table border="1" cellpadding="0" cellspacing="0"><tr><td>
	<table bgColor="#ffffff" border="0" cellPadding="3" cellSpacing="3" width="500" valign="top">
	  <tr>
		<td align="left" bgColor="navy"><b><font color="#ffffff" size="2" face="Tahoma,Arial,Helvetica">Links
		  SQL Import Help</font></b></td>
	  </tr>
	  <tr>
		<td>
		  <p align="center"><b><font color="#000000" size="2" face="Tahoma,Arial,Helvetica">Links SQL Import Help</font></b></p>
		  <p><font size="2" face="Tahoma,Arial,Helvetica">Below is a list of all the options available to you when importing
		  data into Gossamer Links.</font></td>
	  </tr>
	</table>
	</td></tr>
</table>
<br><br>
<table cellpadding="3" cellspacing="0" border="1" width="500">
  <tr>
    <td valign="top" align="left" width="25%">
      <font face="Tahoma,Arial,Helvetica" size="2">
        <b><u>Column</u></b>
      </font>
    </td>
    <td valign="top" align="center">
      <font face="Tahoma,Arial,Helvetica" size="2">
        <b><u>Description</u></b>
      </font>
    </td>
  </tr>
  <tr>
    <td valign="top" align="left" width="25%">
      <font face="Tahoma,Arial,Helvetica" size="2">
        Error File:
      </font>
    </td>
    <td valign="top" align="left">
      <font face="Tahoma,Arial,Helvetica" size="2">
        If present, all errors will be written to the filename provided. The
        errors will be appended to the end, with a header including the date
        written before any errors.
      </font>
    </td>
  </tr>
  <tr>
    <td valign="top" align="left" width="25%">
      <font face="Tahoma,Arial,Helvetica" size="2">
        Show Mild Warnings
      </font>
    </td>
    <td valign="top" align="left">
      <font face="Tahoma,Arial,Helvetica" size="2">
        If this option is selected, 'mild' warnings (indicating minor errors
        such as setting the username associated with a link to 'admin' because
        of insufficient information to create a user) will be displayed in the
        error file. If unchecked, such errors are never displayed.
      </font>
    </td>
  </tr>
  <tr>
    <td valign="top" align="left" width="25%">
      <font face="Tahoma,Arial,Helvetica" size="2">
        Critical Warnings
      </font>
    </td>
    <td valign="top" align="left">
      <font face="Tahoma,Arial,Helvetica" size="2">
        If this option is enabled, all warnings (such as not being able to
        import a Category or Link for whatever reason) will be promoted to
        critical errors, stopping the import. This field has NO effect on mild
        warnings - this is, mild warnings will NOT cause the script to abort.
      </font>
    </td>
  </tr>
  <tr>
    <td valign="top" align="left" width="25%">
      <font face="Tahoma,Arial,Helvetica" size="2">
        Clear Tables
      </font>
    </td>
    <td valign="top" align="left">
      <font face="Tahoma,Arial,Helvetica" size="2">
        With this option enabled, all tables will be cleared before importing.
        This has no effect when exporting to a delimited text file.
      </font>
    </td>
  </tr>
  <tr>
    <td valign="top" align="left" width="25%">
      <font face="Tahoma,Arial,Helvetica" size="2">
        Straight Import
      </font>
    </td>
    <td valign="top" align="left">
      <font face="Tahoma,Arial,Helvetica" size="2">
        With this option enabled, Link IDs will not be changed for the new
        database. That is, a Link with ID 12 in the old database will still be
        12 in the new Gossamer Links database. This option is not recommended unless
        you are linking directly to a link using its ID and must preserve the
        existing link numbering. This option <b>requires</b> that the <i>Clear
        Tables</i> option be enabled.
      </font>
    </td>
  </tr>
  <tr>
    <td valign="top" align="left" width="25%">
      <font face="Tahoma,Arial,Helvetica" size="2">
        Show Warnings
      </font>
    </td>
    <td valign="top" align="left">
      <font face="Tahoma,Arial,Helvetica" size="2">
        With this option enabled, all warnings will be displayed to the
        browser (as well as the log if a log is specified). This option is
        automatically enabled if no log file is specified.
      </font>
    </td>
  </tr>
  <tr>
    <td valign="top" align="left" width="25%">
      <font face="Tahoma,Arial,Helvetica" size="2">
        Recreate Non-standard Columns
      </font>
    </td>
    <td valign="top" align="left">
      <font face="Tahoma,Arial,Helvetica" size="2">
        If this option is enabled, when the import finds extra (custom) columns
        in the source database that do not have an equivelant extra column in
        the destination table, they will be created in the destination table so
        that all data will be imported.
      </font>
    </td>
  </tr>
  <tr>
    <td valign="top" align="left" width="25%">
      <font face="Tahoma,Arial,Helvetica" size="2">
        Create Missing Categories
      </font>
    </td>
    <td valign="top" align="left">
      <font face="Tahoma,Arial,Helvetica" size="2">
        This option, if enabled, causes the import to create any categories
        that are "missing". A category can be missing when a category such as
        "A/B/C" exists, but the category "A/B" does not. This option will make
        the import create the "A/B" category, as well as the "A" category (if
        necessary (i.e. it doesn't exist)).<br>
        A category is also considered "missing" if a link refers to a category
        that does not exist (Links 1.x and 2.x only).
      </font>
    </td>
  </tr>
  <tr>
    <td valign="top" align="left" width="25%">
      <font face="Tahoma,Arial,Helvetica" size="2">
        Extra Data Integrity
      </font>
    </td>
    <td valign="top" align="left">
      <font face="Tahoma,Arial,Helvetica" size="2">
        This option makes the import check each time a category is imported to
        ensure that no duplicate categories will be created by the import. If a
        duplicate is identified, the duplicated category will only be inserted
        once. Note that this option will most likely make the script take
        several times longer to import data, and should only be used if you
        suspect that there may be duplicate categories.
      </font>
    </td>
  </tr>
</table>
</body>

</html>
HTML
}

sub html_pre_format {
    local $_ = shift;
    s/&/&amp;/g;
    s/</&lt;/g;
    s/>/&gt;/g;
    $_;
}


sub _print_headers {
# ------------------------------------------------------------------
# Prints the HTTP headers. Loads Links config file to see if we
# should use nph headers or not.
#
    print $IN->header ( -nph => $CFG->{nph_headers} );
}

"Do I *look* like a false value?"
