<?php
#
#   FILE:  SPT--DBAddFieldComplete.php
#
#   FUNCTIONS PROVIDED:
#
#   FUNCTIONS EXPECTED:
#       None
#
#   Part of the Scout Portal Toolkit
#   Copyright 2001 Internet Scout Project
#   http://scout.cs.wisc.edu
#

#PageTitle("Add Database Field Complete");

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


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

# populate the tree field with data from specified file
function PopulateTree($Field, $FileName)
{
    $DB = new SPTDatabase();

    if (!file_exists($FileName))
        return FALSE;

    $FP = fopen($FileName, 'r');

    while (!feof($FP))
    {
        $ClassificationName = fgets($FP, 16384);

        # last line read, exit
        if (empty($ClassificationName))
            break;

        $NewClass = new Classification(NULL, $ClassificationName,
                            $Field->Id());
    }
    return TRUE;
}

/**
 * Take data from the input form on DBAddField and save it into a Field object
 * Checks completeness of required fields for data that is about to go into the database,
 * But allows incomplete or incorrect field specifications as the field is edited.
 */
function SaveFormData()
{
    global $Field, $F_FieldType, $F_FieldName, $F_Enabled, $F_Optional, 
        $F_Viewable, $F_DefaultValue,$F_UsesQualifiers, 
        $F_HasItemLevelQualifiers, $F_DefaultQualifier, 
        $F_IncludeInKeywordSearch, $F_IncludeInAdvancedSearch, 
        $F_SearchWeight, $F_TextFieldSize, $F_MaxLength, $F_MinValue, 
        $F_MaxValue, $F_DateFormat, $F_ParagraphRows, $F_ParagraphCols, 
        $F_FlagOnLabel, $F_FlagOffLabel, $F_AllowMultiple, $F_Description, 
        $F_DefaultAltText, $F_MaxHeight, $F_MaxWidth, $F_MaxPreviewHeight, 
        $F_MaxPreviewWidth, $F_MaxThumbnailHeight, $F_MaxThumbnailWidth, 
        $F_UseForOaiSets, $F_PointPrecision, $F_PointDecimalDigits, 
        $F_DefaultValue2, $ErrorMessage;

    # Set name and type
    $Field->Name($F_FieldName);
    $Field->Type($F_FieldType);

    # Test the required fields.
    if ( ! $Field->IsTempItem() )
    {
        CheckRequiredFields();

        # Be sure that the name was valid:
        if ($Field->Status() != MetadataSchema::MDFSTAT_OK)
        {
            if ($Field->Status() == MetadataSchema::MDFSTAT_DUPLICATENAME)
            {
                $ErrorMessage = "ERROR: Duplicate field name.";
            }
            else if ($Field->Status() == MetadataSchema::MDFSTAT_ILLEGALNAME)
            {
                $ErrorMessage = "ERROR: Illegal field name.";
            }
        }

        # Bail if anything went wrong
        if (isset($ErrorMessage))
            return;

        # percolate DefaultQualifier for tree fields
        if ($F_FieldType == MetadataSchema::MDFTYPE_TREE)
        {
            SetQualifierIdForClassifications();
        }

        # set DefaultQualifier for Controlled Name fields
        if ($F_FieldType == MetadataSchema::MDFTYPE_CONTROLLEDNAME)
        {
            SetQualifierIdForControlledNames();
        }
    }

    if ($Field->Type() == MetadataSchema::MDFTYPE_POINT)
    {
        if (isset($F_DefaultValue) && isset($F_DefaultValue2))
        {
            $Field->DefaultValue(array("X" => $F_DefaultValue,
                                       "Y" => $F_DefaultValue2));
        }
    }
    else
    {
        $Field->DefaultValue($F_DefaultValue);
    }

    # set the attributes
    if ($F_DefaultQualifier == "--")
        $F_DefaultQualifier = NULL;

    # Set attributes which are unconditional
    foreach( array("Enabled","Optional","Viewable","UsesQualifiers",
                   "HasItemLevelQualifiers", "DefaultQualifier",
                   "IncludeInKeywordSearch", "IncludeInAdvancedSearch",
                   "UseForOaiSets") as $Attribute )
    {
        eval('$Field->'.$Attribute.'($F_'.$Attribute.');');
    }

    # Set attributes which must be non-empty:
    foreach( array("Description","DateFormat","FlagOnLabel",
                   "FlagOffLabel","DefaultAltText")
             as $Attribute )
    {
        eval('if (!empty($F_'.$Attribute.')) '
             .'$Field->'.$Attribute.'($F_'.$Attribute.');');
    }

    # Set attributes which must be numeric:
    foreach( array("TextFieldSize", "MaxLength","MinValue","MaxValue",
                   "ParagraphRows","ParagraphCols","AllowMultiple",
                   "MaxHeight","MaxWidth","MaxPreviewHeight",
                   "MaxPreviewWidth","MaxThumbnailHeight","MaxThumbnailWidth",
                   "PointPrecision","PointDecimalDigits") as $Attribute )
    {
        eval('if (is_numeric($F_'.$Attribute.')) '
             .'$Field->'.$Attribute.'($F_'.$Attribute.');');
    }

    # Set search weight
    if (is_numeric($F_SearchWeight))
    {
        # -force search weight between 1 and 20
        if ($F_SearchWeight < 1) $F_SearchWeight = 1;
        if ($F_SearchWeight > 20) $F_SearchWeight = 20;
        $Field->SearchWeight($F_SearchWeight);
    }

    if ( !$Field->IsTempItem() )
    {
        # save privilege settings
        if (isset($_POST["F_ViewPriv"]))
            {  $Field->ViewingPrivilege($_POST["F_ViewPriv"]);  }
        if (isset($_POST["F_AuthorPriv"]))
            {  $Field->AuthoringPrivilege($_POST["F_AuthorPriv"]);  }
        if (isset($_POST["F_EditPriv"]))
            {  $Field->EditingPrivilege($_POST["F_EditPriv"]);  }
    }
}

# add new field
function AddNewField()
{
    global $Field, $F_FieldID;

    # all new fields are by default NOT required by SPT
    $Field->RequiredBySPT("0");

    # Dump the data into a temp field
    SaveFormData();

    # convert the field from temp to real
    $Field->IsTempItem(FALSE);
    $F_FieldId = $Field->Id();

    # Save the real field into the DB
    SaveFormData();
}

# delete a field
function DeleteField()
{
    global $F_FieldId, $Schema, $SysConfig;

    # must re-assign browsing field id if that's what is being deleted
    if ($SysConfig->BrowsingFieldId() == $F_FieldId)
    {
        $Fields = $Schema->GetFields(MetadataSchema::MDFTYPE_TREE);
        foreach ($Fields as $Field)
        {
            if ($Field->Id() != $F_FieldId)
            {
                $SysConfig->BrowsingFieldId($Field->Id());
                break;
            }
        }
    }

    # drop the field
    $Field = $Schema->DropField($F_FieldId);

    # remove from OAIFieldMappings too
    $DB = new SPTDatabase();
    $DB->Query("Delete from OAIFieldMappings where SPTFieldId=".$F_FieldId);
}

# function to set DefaultQualifier at all levels in a tree
# if not already set to some other value
function SetQualifierIdForClassifications()
{
    global $Field;

    $F_UsesQualifiers = $_POST["F_UsesQualifiers"];
    $F_HasItemLevelQualifiers = $_POST["F_HasItemLevelQualifiers"];
    $F_DefaultQualifier = $_POST["F_DefaultQualifier"];

    if ($F_UsesQualifiers && $F_DefaultQualifier)
    {
        $ClassFactory = new ClassificationFactory();
        $ClassIds = $ClassFactory->GetItemIds("FieldId = ".$Field->Id());
        foreach ($ClassIds as $Id)
        {
            $Class = new Classification($Id);
            $OldQualifierId = $Class->QualifierId();
            $Qualifier = new Qualifier($OldQualifierId);

            # check if qualifier already assigned and is legit
            if (is_null($OldQualifierId) || $OldQualifierId == 0 ||
                is_null($Qualifier->Name()))
            {
                    $Class->QualifierId($F_DefaultQualifier);
            }
        }
    }
}

# function to set DefaultQualifier for a ControlledName field
# if not already set to some other value
function SetQualifierIdForControlledNames()
{
    global $Field;

    $F_UsesQualifiers = $_POST["F_UsesQualifiers"];
    $F_HasItemLevelQualifiers = $_POST["F_HasItemLevelQualifiers"];
    $F_DefaultQualifier = $_POST["F_DefaultQualifier"];

    if ($F_UsesQualifiers && $F_DefaultQualifier)
    {
        $CNFactory = new ControlledNameFactory();
        $CNFactory->GetItemIds("FieldId = ".$Field->Id());
        foreach ($CNIds as $Id)
        {
            $CN = new ControlledName($Id);

            $OldQualifierId = $CN->QualifierId();
            $Qualifier = new Qualifier($OldQualifierId);

            # check if qualifier already assigned and is legit
            if (is_null($OldQualifierId) || $OldQualifierId == 0 ||
                is_null($Qualifier->Name()))
            {
                    $CN->QualifierId($F_DefaultQualifier);
            }
        }
    }
}

function CheckRequiredFields()
{
    global $ErrorMessage, $Field, $F_FieldType, $F_FieldName, $F_Enabled, 
        $F_Optional, $F_Viewable, $F_DefaultValue,$F_UsesQualifiers, 
        $F_HasItemLevelQualifiers, $F_DefaultQualifier, 
        $F_IncludeInKeywordSearch, $F_IncludeInAdvancedSearch, 
        $F_SearchWeight, $F_TextFieldSize, $F_MaxLength, $F_MinValue, 
        $F_MaxValue, $F_DateFormat, $F_ParagraphRows, $F_ParagraphCols, 
        $F_FlagOnLabel, $F_FlagOffLabel, $F_AllowMultiple, $F_Description, 
        $F_DefaultAltText, $F_MaxHeight, $F_MaxWidth, $F_MaxPreviewHeight, 
        $F_MaxPreviewWidth, $F_MaxThumbnailHeight, $F_MaxThumbnailWidth, 
        $F_PointPrecision, $F_PointDecimalDigits;

    if (empty($F_FieldName))
    {
        $ErrorMessage = "ERROR: Missing required FieldName Field.";
    }
    if (empty($F_Description))
    {
        $ErrorMessage = "ERROR: Missing required Description Field.";
    }

    switch($F_FieldType)
    {
        case MetadataSchema::MDFTYPE_TEXT:
        case MetadataSchema::MDFTYPE_URL:
            if (empty($F_TextFieldSize))
            {
                $ErrorMessage = "ERROR: Missing required TextFieldSize Field.";
            }
            if (empty($F_MaxLength))
            {
                $ErrorMessage = "ERROR: Missing required MaxLength Field.";
            }
            break;

        case MetadataSchema::MDFTYPE_POINT:
            if (empty($F_PointPrecision))
            {
                $ErrorMessage = "ERROR: Missing required field PointPrecision.";
            }
            if (empty($F_PointDecimalDigits))
            {
                $ErrorMessage = "ERROR: Missing required field PointDecimalDigits.";
            }
            break;

        case MetadataSchema::MDFTYPE_PARAGRAPH:
            if (empty($F_ParagraphRows))
            {
                $ErrorMessage = "ERROR: Missing required ParagraphRows Field.";
            }
            if (empty($F_ParagraphCols))
            {
                $ErrorMessage = "ERROR: Missing required ParagraphCols Field.";
            }
            break;

        case MetadataSchema::MDFTYPE_FLAG:
            if (empty($F_FlagOnLabel))
            {
                $ErrorMessage = "ERROR: Missing required FlagOnLabel Field.";
            }
            if (empty($F_FlagOffLabel))
            {
                $ErrorMessage = "ERROR: Missing required FlagOffLabel Field.";
            }
            break;

        case MetadataSchema::MDFTYPE_IMAGE:
            if (empty($F_DefaultAltText))
            {
                $ErrorMessage = "ERROR: Missing required DefaultAltText Field.";
            }
            break;

        case MetadataSchema::MDFTYPE_POINT:
            if (empty($F_PointPrecision))
            {
                $ErrorMessage = "ERROR: Missing required PointPrecision FIeld.";
            }
            if (empty($F_PointDecimalDigits))
            {
                $ErrorMessage = "ERROR: Missing required PointDecimalDigits Field.";
            }
            break;
    }
}

# remove Qaulifier assocation for this field
function RemoveQualifierAssociation()
{
    global $F_FieldId, $Schema;

    # Get the field
    $Field = $Schema->GetField($F_FieldId);

    $F_AllowedQualifiers = $_POST["F_AllowedQualifiers"];
    if (isset($F_AllowedQualifiers) && $F_AllowedQualifiers != "--")
        $Field->UnassociateWithQualifier($F_AllowedQualifiers);
}

# add Qualifier assocation for this field
function AddQualifierAssociation()
{
    global $F_FieldId, $Schema;

    # Get the field
    $Field = $Schema->GetField($F_FieldId);

    $F_AvailableQualifiers = $_POST["F_AvailableQualifiers"];
    if (isset($F_AvailableQualifiers) && $F_AvailableQualifiers != "--")
        $Field->AssociateWithQualifier($F_AvailableQualifiers);

}

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

# non-standard global variables
global $ErrorMessage, $F_AllowMultiple, $F_DateFormat, $F_DefaultAltText,
    $F_DefaultQualifier, $F_DefaultValue, $F_DefaultValue2, $F_Description,
    $F_Enabled, $F_FieldId, $F_FieldName, $F_FieldType, $F_FlagOffLabel,
    $F_FlagOnLabel, $F_HasItemLevelQualifiers, $F_IncludeInAdvancedSearch,
    $F_IncludeInKeywordSearch, $F_MaxHeight, $F_MaxLength, $F_MaxPreviewHeight,
    $F_MaxPreviewWidth, $F_MaxThumbnailHeight,$F_MaxThumbnailWidth, $F_MaxValue,
    $F_MaxWidth, $F_MinValue, $F_Optional, $F_ParagraphCols, $F_ParagraphRows,
    $F_SearchWeight, $F_TextFieldSize, $F_UseForOaiSets, $F_UsesQualifiers,
    $F_Viewable, $Field, $Schema;

if (!CheckAuthorization(PRIV_SYSADMIN, PRIV_COLLECTIONADMIN)) {  return;  }

$Schema = new MetadataSchema();
$F_FieldId = $Schema->GetCurrentEditedItemId();

# get the field
$Field = $Schema->GetField($F_FieldId);

# Pull set vars from $_POST
foreach ( array("FieldName", "FieldType", "Enabled","Optional",
                "Viewable", "DefaultValue","DefaultValue2","UsesQualifiers",
                "HasItemLevelQualifiers","DefaultQualifier",
                "IncludeInKeywordSearch","IncludeInAdvancedSearch",
                "SearchWeight", "TextFieldSize","MaxLength","MinValue",
                "MaxValue","DateFormat","ParagraphRows","ParagraphCols",
                "FlagOnLabel","FlagOffLabel","AllowMultiple",
                "Description","DefaultAltText","MaxHeight","MaxWidth",
                "MaxPreviewHeight","MaxPreviewWidth","MaxThumbnailHeight",
                "MaxThumbnailWidth","UseForOaiSets") as $Var )
{
    eval('$F_'.$Var.'=isset($_POST["F_'.$Var.'"]) ? '
         .'$_POST["F_'.$Var.'"] : NULL;');
}

if ($_POST["Submit"] == "Add New Field")
{
    AddNewField();
    if (isset($ErrorMessage))
    {
        $AF->SetJumpToPage("index.php?P=DBAddField&amp;"
                           ."ErrorMessage=".urlencode($ErrorMessage));
    }
    else
    {
        $AF->SetJumpToPage("index.php?P=DBConfirmAddField&amp;"
                           ."F_FieldName=".urlencode($F_FieldName));
        $Schema->ClearCurrentEditedItemId();
    }
}
else if ($_POST["Submit"] == "Update Field")
{
    SaveFormData();
    if (isset($ErrorMessage))
    {
        $AF->SetJumpToPage("index.php?P=DBAddField&amp;"
                           ."ErrorMessage=".urlencode($ErrorMessage));
    }
    else
    {
        $AF->SetJumpToPage("DBEditor");
        $Schema->ClearCurrentEditedItemId();
    }
}
else if ($_POST["Submit"] == "Populate Field")
{
    SaveFormData();
    $AF->SetJumpToPage("PopulateField&ID=".$Field->Id());
}
else if ($_POST["Submit"] == "Add Another Field")
{
    $AF->SetJumpToPage("DBAddField");
    $Schema->ClearCurrentEditedItemId();
}
else if ($_POST["Submit"] == "Edit Fields")
{
    $AF->SetJumpToPage("DBEditor");
    $Schema->ClearCurrentEditedItemId();
}
else if (substr($_POST["Submit"], 0, 6) == "Delete")
{
    if (isset($_POST["OkayToDelete"]))
    {
        DeleteField();
        $AF->SetJumpToPage("DBEditor");
        $Schema->ClearCurrentEditedItemId();
    }
    else
    {
        $AF->SetJumpToPage("index.php?P=DBConfirmDeleteField&amp;"
                           ."F_FieldName=".urlencode($F_FieldName)."&amp;"
                           ."F_FieldId=".urlencode($F_FieldId));
    }
}
else if ($_POST["Submit"] == "Cancel")
{
    # delete temporary field and clear current edit id
    if (isset($F_FieldId))
    {
        $Field = $Schema->GetField($F_FieldId);
        if ($Field->IsTempItem())
            DeleteField();
    }
    $Schema->ClearCurrentEditedItemId();
    $AF->SetJumpToPage("DBEditor");
}
else if ($_POST["Submit"] == "Remove ==>")
{
    SaveFormData();
    RemoveQualifierAssociation();
}
else if ($_POST["Submit"] == "<== Add")
{
    SaveFormData();
    AddQualifierAssociation();
}
else if ($_POST["Submit"] == "Populate")
{
    $F_PopulateTree = $_POST["F_PopulateTree"];
    if (!empty($F_PopulateTree))
    {
        $Field = $Schema->GetField($F_FieldId);
        if ($Field->Type() == MetadataSchema::MDFTYPE_TREE)
        {
            $Status = PopulateTree($Field, $F_PopulateTree);
            if ($Status == FALSE)
            {
                $ErrorMessage = "WARNING: Cannot populate tree.".
                "\"$F_PopulateTree\" not found";
            }
            else
            {
                $ErrorMessage =
                    "Field populated successfully.";
            }
        }
    }
    else
    {
        $ErrorMessage = "You must select a taxonomy.";
    }
    $Session->PassVariable("ErrorMessage", $ErrorMessage);

    $AF->SetJumpToPage("DBPopulateTree");
}
else if (isset($_POST["Submit"]))
{
    $F_FieldType = $_POST["Submit"];
    SaveFormData();

    $AF->SetJumpToPage("index.php?P=DBAddField&amp;"
                       ."F_FieldType=".$F_FieldType);
}
else
{
    if (isset($ErrorMessage))
    {
        $AF->SetJumpToPage("index.php?P=DBAddField&amp;"
                           ."ErrorMessage=".urlencode($ErrorMessage));
    }
    else
    {
        $AF->SetJumpToPage("index.php?P=DBAddField");
    }
}

?>
