<?PHP
#
#   FILE:  Edit.php
#
#   Part of the Collection Workflow Integration System (CWIS)
#   Copyright 2011 Internet Scout Project
#   http://scout.wisc.edu/
#

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

/**
* Print Metadata Field Option List.
* @param string $Name Form name to use.
* @param mixed $Rule Rule to get the MetadataField from.
*/
function Rules_PrintMetadataFieldOptionList($Name, $Rule)
{
    global $G_Schema;

    $Selected = $Rule["Conditions"]["FieldId"];

    print $G_Schema->GetFieldsAsOptionList($Name, NULL, $Selected, FALSE);
}

/**
* Print rules operator form elements.
* @param mixed $Rule Rule to print.
*/
function Rules_PrintRuleOperator($Rule)
{
    global $G_Schema;

    $Field = $G_Schema->GetField($Rule["Conditions"]["FieldId"]);
    $Type = ($Field instanceof MetadataField) ? $Field->Type() : NULL;

    switch ($Type)
    {
        case MetadataSchema::MDFTYPE_NUMBER:
        case MetadataSchema::MDFTYPE_DATE:
        case MetadataSchema::MDFTYPE_TIMESTAMP:
            Rules_PrintNumericRuleOperator($Rule);
            break;

        case MetadataSchema::MDFTYPE_FLAG:
            Rules_PrintFlagRuleOperator($Rule);
            break;

        case MetadataSchema::MDFTYPE_TREE:
        case MetadataSchema::MDFTYPE_CONTROLLEDNAME:
        case MetadataSchema::MDFTYPE_OPTION:
            Rules_PrintControlledRuleOperator($Rule);
            break;

        case MetadataSchema::MDFTYPE_USER:
            Rules_PrintUserRuleOperator($Rule);
            break;

        case MetadataSchema::MDFTYPE_IMAGE:
        case MetadataSchema::MDFTYPE_FILE:
            Rules_PrintFileRuleOperator($Rule);
            break;

        default:
            Rules_PrintBasicRuleOperator($Rule);
            break;
    }
}

/**
* Print the value for which a rule is checking.
* @param mixed $Rule Rule being printed.
*/
function Rules_PrintRuleValue($Rule)
{
    global $G_Schema;

    $Field = $G_Schema->GetField($Rule["Conditions"]["FieldId"]);
    $Type = ($Field instanceof MetadataField) ? $Field->Type() : NULL;

    switch ($Type)
    {
        case MetadataSchema::MDFTYPE_NUMBER:
            Rules_PrintNumericRuleValue($Rule);
            break;

        case MetadataSchema::MDFTYPE_DATE:
        case MetadataSchema::MDFTYPE_TIMESTAMP:
            Rules_PrintDateRuleValue($Rule);
            break;

        case MetadataSchema::MDFTYPE_TREE:
        case MetadataSchema::MDFTYPE_CONTROLLEDNAME:
        case MetadataSchema::MDFTYPE_OPTION:
            Rules_PrintControlledRuleValue($Rule);
            break;

        case MetadataSchema::MDFTYPE_USER:
            Rules_PrintUserRuleValue($Rule);
            break;

        default:
            Rules_PrintNoRuleValue($Rule);
            break;
    }
}

/**
* Print an OptionList of rule types.
* @param mixed $Rule Rule being printed.
*/
function Rules_PrintRuleType($Rule)
{
    $Items = array(
        "EMAIL" => "Send an e-mail to");
    $Selected = "EMAIL";

    PrintOptionList("F_Type", $Items, $Selected);
}

/**
* Print option list of user privileges restrictions for a rule (i.e.,
*   users having a selected priv will be affected by this rule).
* @param mixed $Rule Rule being printed.
*/
function Rules_RuleUserPrivilegeRestrictions($Rule)
{
    $Actions = $Rule["Actions"];

    $UserPrivilegeRestrictions = GetArrayValue(
        $Actions,
        "UserPrivilegeRestrictions");

    $PrivilegeFactory = new PrivilegeFactory();
    $PrivilegeList = $PrivilegeFactory->GetPrivileges(TRUE, FALSE);
    $PrivilegeList = array(0 => "--") + $PrivilegeList;

    # remove the disabled privilege from the options
    unset($PrivilegeList[PRIV_USERDISABLED]);

    PrintOptionList(
        "F_UserPrivilegeRestrictions",
        $PrivilegeList,
        $UserPrivilegeRestrictions,
        "", 1, 1, FALSE, NULL, "auto");
}

/**
* Print option list of User fields for a UserIs rule.
* @param mixed $Rule Rule being printed.
*/
function Rules_RuleUserIsField($Rule)
{
    global $G_Schema;

    $Actions = $Rule["Actions"];
    $UserFields = $G_Schema->GetFields(MetadataSchema::MDFTYPE_USER);
    $Options = array(0 => "--");
    $UserIsFieldValue = GetArrayValue($Actions, "UserIsField");

    foreach ($UserFields as $Id => $Field)
    {
        $Options[$Id] = $Field->GetDisplayName();
    }

    PrintOptionList("F_UserIsField", $Options, $UserIsFieldValue);
}

/**
* Print an OptionList of available Mailer templates, with the
*   currently active one selected.
* @param mixed $Rule Rule being printed.
*/
function Rules_RuleTemplateId($Rule)
{
    global $G_PluginManager;

    $TemplateId = $Rule["Actions"]["TemplateId"];

    $MailerPlugin = $G_PluginManager->GetPlugin("Mailer");
    $TemplateList = $MailerPlugin->GetTemplateList();

    PrintOptionList(
        "F_TemplateId",
        $TemplateList,
        $TemplateId,
        "", 1, 1, FALSE, NULL, "auto");
}

/**
* Get the Id of a rule.
* @param mixed $Rule Rule being printed.
* @return int Rule Id.
*/
function Rules_GetRuleId($Rule)
{
    return $Rule["RuleId"];
}

/**
* Get the FieldId that a Rule is testing against.
* @param mixed $Rule Rule being printed.
* @return int Metadata Field Id.
*/
function Rules_GetRuleFieldId($Rule)
{
    global $G_Schema;

    $Field = $G_Schema->GetField($Rule["Conditions"]["FieldId"]);
    $Id = ($Field instanceof MetadataField) ? $Field->Id() :
        $Rule["Conditions"]["FieldId"];

    return $Id;
}

/**
* Get the name of the MetadataField that a rule tests against.
* @param mixed $Rule Rule being printed.
* @return string Metadata Field name.
*/
function Rules_GetRuleFieldName($Rule)
{
    global $G_Schema;

    $Field = $G_Schema->GetField($Rule["Conditions"]["FieldId"]);
    $Name = ($Field instanceof MetadataField) ? $Field->GetDisplayName() :
          "INVALID FIELD (Id=".$Rule["Conditions"]["FieldId"].")";

    return $Name;
}

/**
* Determine if at least one email template exists.
* @return TRUE if at least one email template exists.
*/
function Rules_AtLeastOneEmailTemplate()
{
    global $G_PluginManager;

    $MailerPlugin = $G_PluginManager->GetPlugin("Mailer");
    $TemplateList = $MailerPlugin->GetTemplateList();
    $AtLeastOne = count($TemplateList) > 0;

    return $AtLeastOne;
}

/**
* Determine if a rule could be checking a value.
* @param mixed $Rule Rule to check.
* @return TRUE for rules that don't compare against a desired value,
*     FALSE otherwise.
*/
function Rules_NeverHasValue($Rule)
{
    global $G_Schema;

    $Field = $G_Schema->GetField($Rule["Conditions"]["FieldId"]);
    $Type = ($Field instanceof MetadataField) ? $Field->Type() : NULL;

    switch ($Type)
    {
        case MetadataSchema::MDFTYPE_NUMBER:
        case MetadataSchema::MDFTYPE_DATE:
        case MetadataSchema::MDFTYPE_TIMESTAMP:
        case MetadataSchema::MDFTYPE_TREE:
        case MetadataSchema::MDFTYPE_CONTROLLEDNAME:
        case MetadataSchema::MDFTYPE_OPTION:
        case MetadataSchema::MDFTYPE_USER:
            return FALSE;

        default:
            return TRUE;
    }
}

/**
* Get the description of the operator in a rule.
* @param mixed $Rule Rule to check.
* @return string Operator description.
*/
function Rules_GetRuleOperator($Rule)
{
    $Schema = new MetadataSchema();
    $Field = $Schema->GetField($Rule["Conditions"]["FieldId"]);
    $Type = ($Field instanceof MetadataField) ? $Field->Type() : NULL;

    switch ($Type)
    {
        case MetadataSchema::MDFTYPE_NUMBER:
        case MetadataSchema::MDFTYPE_DATE:
        case MetadataSchema::MDFTYPE_TIMESTAMP:
            $Operator = Rules_GetNumericRuleOperator($Rule);
            break;

        case MetadataSchema::MDFTYPE_FLAG:
            $Operator = Rules_GetFlagRuleOperator($Rule);
            break;

        case MetadataSchema::MDFTYPE_TREE:
        case MetadataSchema::MDFTYPE_CONTROLLEDNAME:
        case MetadataSchema::MDFTYPE_OPTION:
            $Operator = Rules_GetControlledNameRuleOperator($Rule);
            break;

        case MetadataSchema::MDFTYPE_USER:
            $Operator = Rules_GetUserRuleOperator($Rule);
            break;

        case MetadataSchema::MDFTYPE_IMAGE:
        case MetadataSchema::MDFTYPE_FILE:
            $Operator = Rules_GetFileRuleOperator($Rule);
            break;

        default:
            $Operator = Rules_GetBasicRuleOperator($Rule);
            break;
    }

    return $Operator;
}

/**
* Get the constant for the basic rule operator.
* @param mixed $Rule Rule to check.
*/
function Rules_GetBasicRuleOperator($Rule)
{
    return 1;
}

/**
* Convert operator strings from a Rule (e.g. "=") to numeric codes.
* @param mixed $Rule Rule to check.
* @return int Operator code.
*/
function Rules_GetNumericRuleOperator($Rule)
{
    $Operator = GetArrayValue($Rule["Conditions"], "Operator");

    if (!$Operator)
    {
        return 1;
    }

    $Map = array(
        "=" => 2,
        "!=" => 3,
        "<" => 4,
        ">" => 5,
        "<=" => 6,
        ">=" => 7);

    return GetArrayValue($Map, $Operator);
}

/**
* Get rule operators for a rule checking a Flag field.
* @param mixed $Rule Rule to check.
* @return int Operator code.
*/
function Rules_GetFlagRuleOperator($Rule)
{
    $Operator = GetArrayValue($Rule["Conditions"], "Operator");

    if (!$Operator)
    {
        return 1;
    }

    $Value = GetArrayValue($Rule["Conditions"], "Value");

    return $Value ? 8 : 9;
}

/**
* Get rule operators for a rule checking a ControlledName field.
* @param mixed $Rule Rule to check.
* @return int Operator code.
*/
function Rules_GetControlledNameRuleOperator($Rule)
{
    $Operator = GetArrayValue($Rule["Conditions"], "Operator");

    return !$Operator ? 1 : 10;
}

/**
* Get rule operators for a rule checking a User field.
* @param mixed $Rule Rule to check.
* @return int Operator code.
*/
function Rules_GetUserRuleOperator($Rule)
{
    $Operator = GetArrayValue($Rule["Conditions"], "Operator");

    return !$Operator ? 1 : 11;
}

/**
* Get rule operators for a rule checking a File file.d
* @param mixed $Rule Rule to check.
* @return int Operator code.
*/
function Rules_GetFileRuleOperator($Rule)
{
    return 1;
}

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

global $G_Schema;
global $G_RulesPlugin;
global $G_Rule;
global $G_Field;
global $G_AtLeastOneEmailTemplate;
global $G_NeverHasValue;
global $G_Title;
global $G_IsEditing;

# check that user should be on this page
CheckAuthorization(PRIV_COLLECTIONADMIN, PRIV_SYSADMIN);

$G_Schema = new MetadataSchema();
$G_RulesPlugin = $G_PluginManager->GetPlugin("Rules");
$G_AtLeastOneEmailTemplate = Rules_AtLeastOneEmailTemplate();

$RuleId = GetArrayValue($_GET, "RuleId");

# create a skeleton rule if no ID given
if (is_null($RuleId))
{
    $FieldId = GetArrayValue($_GET, "FieldId");
    $G_Field = $G_Schema->GetField($FieldId);

    # require a valid field ID when creating rules
    if (is_null($FieldId) || $G_Field->Status() != MetadataSchema::MDFSTAT_OK)
    {
        $AF->SetJumpToPage("P_Rules_List");
        return;
    }

    $G_Rule = array(
        "RuleId" => NULL,
        "Enabled" => FALSE,
        "Conditions" => array(
            "FieldId" => $G_Field->Id(),
            "Operator" => NULL,
            "Value" => NULL),
        "Actions" => array(
            "Type" => NULL,
            "TemplateId" => NULL,
            "UserPrivilegeRestrictions" => NULL,
            "UserIsField" => NULL));

    $G_NeverHasValue = Rules_NeverHasValue($G_Rule);
    $G_Title = "Add Rule";
    $G_IsEditing = FALSE;
}

# otherwise try to get the rule
else
{
    $Rules = $G_RulesPlugin->GetRules();
    $G_Rule = GetArrayValue($Rules, $RuleId);

    # invalid rule ID, so go back to the list page
    if (is_null($G_Rule))
    {
        $AF->SetJumpToPage("P_Rules_List");
        return;
    }

    $G_Field = $G_Schema->GetField($G_Rule["Conditions"]["FieldId"]);
    $G_NeverHasValue = Rules_NeverHasValue($G_Rule);
    $G_Title = "Edit Rule";
    $G_IsEditing = TRUE;
}

PageTitle($G_Title);
