<?PHP
#
#   FILE:  ExportDataExecute.php
#
#   Part of the Collection Workflow Integration System (CWIS)
#   Copyright 2011-2013 Edward Almasy and Internet Scout Research Group
#   http://scout.wisc.edu/cwis/
#

# ----- EXPORTED FUNCTIONS ---------------------------------------------------

# see if export is complete
function ExportComplete()
{
    global $ExportComplete;
    return ($ExportComplete == 1) ? true : false;
}

# print Resource Count
function PrintResourceCount()
{
    global $ResourceCount;
    print $ResourceCount;
}

# print link to downloadable exported file
function PrintExportLink()
{
    global $ExportFileName;

    print "<a href=\"./".$ExportFileName."\">";
}

# ----- LOCAL FUNCTIONS ------------------------------------------------------

# eliminate an array element
function EliminateArrayElement($Array, $Indice)
{
   if (array_key_exists($Indice, $Array))
   {
       $temp = $Array[0];
       $Array[0] = $Array[$Indice];
       $Array[$Indice] = $temp;
       array_shift($Array);

       //reacomodamos índices
       for ($i = 0 ; $i < $Indice ; $i++)
       {
           $dummy = $Array[$i];
           $Array[$i] = $temp;
           $temp = $dummy;
       }
   }
   return $Array;
}

# do/while loop, this is the main event
function DoWhileLoop()
{
    global $fpi, $fpo, $ExportComplete, $User, $ResourceCount,
        $FSeek, $TotalLineCount;

    # build partial query for dynamic fields
    $Schema = new MetadataSchema();
    $Fields = $Schema->GetFields();

    # write out the header line only on first time
    if (!empty($fpo) && $FSeek == 0)
    {
        $Header = NULL;
        # loop through each field
        foreach ($Fields as $Field)
        {
            if ($Field->Enabled() &&
                $Field->Type() != MetadataSchema::MDFTYPE_IMAGE &&
                $Field->Type() != MetadataSchema::MDFTYPE_FILE )
            {
                $Header .= $Field->Name()."\t";
            }
        }
        # replace trailing tab with newline
        $Header = substr($Header, 0, strlen($Header)-1)."\n";
        fwrite($fpo, $Header);
    }

    $InputLineCount = 0;

    while (!feof($fpi) && $InputLineCount < 50 && $ExportComplete == 0)
    {
        $ResourceId = fgets($fpi, 4096);
        $FSeek += strlen($ResourceId);
        $ResourceId = trim($ResourceId);

        if (empty($ResourceId))
            break;

        $ResourceCount++;
        $InputLineCount++;

        # get the all the values for the resource
        $Resource = new Resource($ResourceId);
        $Result = $Resource->GetAsArray();

        # must iterate over each ControlledName, Option, Classification, and Reference
        $NotDoneYet = TRUE;
        while ($NotDoneYet)
        {
            $NotDoneYet = FALSE;
            $Record = NULL;

            # loop through each field
            foreach ($Fields as $Field)
            {
                if ($Field->Enabled())
                {
                    $FName = $Field->Name();

                    # skip images and files.
                    if ($Field->Type() &
                        (MetadataSchema::MDFTYPE_IMAGE|MetadataSchema::MDFTYPE_FILE) )
                    {
                        continue;
                    }
                    # process Dates
                    else if ($Field->Type() & MetadataSchema::MDFTYPE_DATE)
                    {
                        $Date = $Result["$FName"];
                        $Record .= $Date->Formatted();
                    }
                    # User fields
                    else if ($Field->Type() & MetadataSchema::MDFTYPE_USER)
                    {
                        $TempUser = $Result["$FName"];
                        $Record .= $TempUser->Get("UserName");
                    }
                    # Controlled names, options, references, and trees
                    else if ($Field->Type() &
                             (MetadataSchema::MDFTYPE_CONTROLLEDNAME|
                              MetadataSchema::MDFTYPE_OPTION|
                              MetadataSchema::MDFTYPE_REFERENCE|
                              MetadataSchema::MDFTYPE_TREE ))
                    {
                        if (count($Result["$FName"]) > 0)
                        {
                            $NotDoneYet = TRUE;
                            $DataObject = array_pop($Result["$FName"]);

                            $DataValue = ($DataObject instanceof Resource) ?
                                $DataObject->Get("Title") :
                                $DataObject->Name() ;

                            $DataValue = preg_replace("/([\t\r\n])/", " ",
                                                      $DataValue);
                            $Record .= $DataValue;
                        }
                    }
                    else
                    {
                        # strip out linefeeds, carriage returns, and tabs
                        $DataValue = $Result["$FName"];
                        $DataValue = preg_replace("/([\t\r\n])/", " ",
                                        $DataValue);
                        $Record .= $DataValue;
                    }
                }
                $Record .= "\t";
            }
            # replace last tab with a newline
            $Record = substr($Record, 0, strlen($Record)-1)."\n";
            if (!empty($fpo))
                fwrite($fpo, $Record);
        }
    }
}

# function to get list of matching files
function ListDir($DirPath, $Pattern)
{
    static $ResultArray = array();

    $Handle = opendir($DirPath);
    while ($File = readdir($Handle))
    {
        if ($File == '.' || $File == '..')
            continue;
        if (is_dir($DirPath.$File))
            continue;
        else if (preg_match($Pattern, $File))
            $ResultArray[]=$DirPath.$File;
    }
    closedir($Handle);
    return $ResultArray;
}

# ----- MAIN -----------------------------------------------------------------

# non-standard global variables
global $ExportComplete;
global $FSeek;
global $ResourceCount;
global $TotalLineCount;
global $ExportFileName;
global $fpi;
global $fpo;

# check if current user is authorized
if (!CheckAuthorization(PRIV_SYSADMIN, PRIV_COLLECTIONADMIN)) {  return;  }

$ClassDB = new Database();

if (isset($_SERVER["PATH_TRANSLATED"])
        && strlen($_SERVER["PATH_TRANSLATED"]))
{
    $ScriptFileName = $_SERVER["PATH_TRANSLATED"];
}
elseif (isset($_SERVER["SCRIPT_FILENAME"])
        && strlen($_SERVER["SCRIPT_FILENAME"]))
{
    $ScriptFileName = $_SERVER["SCRIPT_FILENAME"];
}
elseif (isset($_SERVER["PATH_INFO"])
        && strlen($_SERVER["PATH_INFO"]))
{
    $ScriptFileName = $_SERVER["PATH_INFO"];
}
$TempDir = dirname($ScriptFileName).
            "/tmp/";

# make sure destination dir exists
if (!file_exists($TempDir))
{
    $ErrorMessage = "Error: Destination directory ".$TempDir.
                    " doesn't exist.";
    $AF->SetJumpToPage("ExportData&amp;ERR=".urlencode($ErrorMessage));
    return;
}

# make sure destination dir is writable
if (!is_writable($TempDir))
{
    $ErrorMessage = "Error: Destination directory ".$TempDir.
                    " is not writable.";
    $AF->SetJumpToPage("ExportData&amp;ERR=".urlencode($ErrorMessage));
    return;
}

# open import file for reading
if (isset($_GET["IP"]))
{
    $InputPath = $_GET["IP"];
}
else
{
    $InputPath = substr($ScriptFileName, 0, strrpos($ScriptFileName, '/')).
        "/tmp/InputData.".$User->Get("UserId");
    $RN = rand();
    if (is_readable($InputPath) )
    {
        rename($InputPath, $InputPath.".".$RN);
    }
    $InputPath = $InputPath.".".$RN;
}

if (isset($_POST["Submit"]))
    $Submit = $_POST["Submit"];
else
    $Submit = NULL;

if ($Submit == "Cancel")
{
    $AF->SetJumpToPage("SysAdmin");
    return;
}

# export all records, create new InputData file
if ($Submit == "Export All Resources")
{
    $RFactory = new ResourceFactory();
    $Resources = $RFactory->GetItemIds();

    $fp = fopen($InputPath, "w");
    foreach ($Resources as $ResourceId)
    {
       fwrite($fp, $ResourceId."\n");
    }
    fclose($fp);
}

## init variables -- first time thru they will be null
$FSeek          = isset($_GET["FS"])?intval($_GET["FS"]):0;
$ExportComplete = isset($_GET["EC"])?intval($_GET["EC"]):0;
$ResourceCount  = isset($_GET["RC"])?intval($_GET["RC"]):0;
$TotalLineCount = isset($_GET["LC"])?intval($_GET["LC"]):0;

# open input file for reading
if (is_readable($InputPath))
{
    $fpi = fopen($InputPath, "r");
}
else
{
    $ErrorMessage = "Cannot open Resource ID Filename: $InputPath<br>";
    $AF->SetJumpToPage("ExportData&amp;ERR=".urlencode($ErrorMessage));
    return;
}

# open export path
if ( isset($_GET["EP"]) )
{
    $ExportPath = $_GET["EP"];
    $ExportFileName   = $_GET["FN"];
}
else
{
    $ExportFileName = "tmp/Metadata_".date("YmdHis").".txt";
    $ExportPath = dirname($ScriptFileName)."/".$ExportFileName;

    # remove any old exported files
    $OldExportFiles = ListDir(dirname($ScriptFileName)."/tmp/",
                              "/^(InputD|Metad)ata/");
    if (is_array($OldExportFiles))
    {
        $Now = time();
        foreach ($OldExportFiles as $OldFile)
        {
            # Delete export files > 1 day old (86400 s)
            if( $Now - filemtime($OldFile) > 86400 )
            {
                unlink($OldFile);
            }
        }
    }
}

$fpo = fopen($ExportPath, "a");
if ($fpo == FALSE)
{
    $ErrorMessage = "Cannot open Export Filename: $ExportPath<br>";
    $AF->SetJumpToPage("ExportData&amp;ERR=".urlencode($ErrorMessage));
    return;
}

# seek to the next line
if ($FSeek > 0)
{
    fseek($fpi, $FSeek);
}

# the main work happenes here
DoWhileLoop();

if (feof($fpi))
{
    $ExportComplete = 1;
}

#  Time to auto-refresh?
if ($ExportComplete == 0)
{
    $AutoRefreshToPage = "index.php?P=ExportDataExecute".
        "&amp;IP=".$InputPath .
        "&amp;EC=".$ExportComplete .
        "&amp;RC=".$ResourceCount .
        "&amp;LC=".$TotalLineCount .
        "&amp;FS=".$FSeek .
        "&amp;EP=".$ExportPath .
        "&amp;FN=".$ExportFileName ;
}
else
{
    fclose($fpi);
    fclose($fpo);
    unlink($InputPath);
}

PageTitle("Export Data");
