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

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

/**
* Determine if an old plugin configuration value is different from a new one.
* @param mixed $OldValue Old plugin configuration value.
* @param mixed $NewValue New plugin configuration value.
* @return Returns TRUE if the values are different and FALSE otherwise.
*/
function DidValueChange($OldValue, $NewValue)
{
    # didn't change if they are identical
    if ($OldValue === $NewValue)
    {
        return FALSE;
    }

    # need special cases from this point because PHP returns some odd results
    # when performing loose equality comparisons:
    # http://php.net/manual/en/types.comparisons.php#types.comparisions-loose

    # consider NULL and an empty string to be the same. this is in case a plugin
    # uses NULL when it's installed and receives an empty value from the form.
    # $_POST values are always strings
    if (is_null($OldValue) && is_string($NewValue) && !strlen($NewValue)
        || is_null($NewValue) && is_string($OldValue) && !strlen($OldValue))
    {
        return FALSE;
    }

    # if they both appear to be numbers and are equal
    if (is_numeric($OldValue) && is_numeric($NewValue) && $OldValue == $NewValue)
    {
        return FALSE;
    }

    # true-like values
    if ($OldValue === TRUE && ($NewValue === 1 || $NewValue === "1")
        || $NewValue === TRUE && ($OldValue === 1 || $OldValue === "1"))
    {
        return FALSE;
    }

    # false-like values
    if ($OldValue === FALSE && ($NewValue === 0 || $NewValue === "0")
        || $NewValue === FALSE && ($OldValue === 0 || $OldValue === "0"))
    {
        return FALSE;
    }

    # arrays
    if (is_array($OldValue) && is_array($NewValue))
    {
        # they certainly changed if the counts are different
        if (count($OldValue) != count($NewValue))
        {
            return TRUE;
        }

        # the algorithm for associative arrays is slightly different from
        # sequential ones. the values for associative arrays must match the keys
        if (count(array_filter(array_keys($OldValue), "is_string")))
        {
            foreach ($OldValue as $Key => $Value)
            {
                # it changed if the keys don't match
                if (!array_key_exists($Key, $NewValue))
                {
                    return TRUE;
                }

                # the arrays changed if a value changed
                if (DidValueChange($Value, $NewValue[$Key]))
                {
                    return TRUE;
                }
            }
        }

        # sequential values don't have to have the same keys, just the same
        # values
        else
        {
            # sort them so all the values match up if they're equal
            sort($OldValue);
            sort($NewValue);

            foreach ($OldValue as $Key => $Value)
            {
                # the arrays changed if a value changed
                if (DidValueChange($Value, $NewValue[$Key]))
                {
                    return TRUE;
                }
            }
        }

        # the arrays are equal
        return FALSE;
    }

    # they changed
    return TRUE;
}

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

PageTitle("Plugin Configuration");

# check that the user has sufficient privileges
if (!CheckAuthorization(PRIV_SYSADMIN)) {  return;  }

$PluginName = isset($_GET["PN"]) ? $_GET["PN"] : NULL;
$G_Plugin = $G_PluginManager->GetPlugin($PluginName);

if ($G_Plugin && isset($_POST["Submit"]))
{
    if ($_POST["Submit"] == "Save Changes")
    {
        # for each configuration parameter
        $Attribs = $G_Plugin->GetAttributes();
        foreach ($Attribs["CfgSetup"] as $Name => $Params)
        {
            # determine form field name (matches mechanism in HTML)
            $FieldName = "F_".preg_replace("/[^a-zA-Z0-9]/", "", $Name);

            # assume the plugin value will not change
            $DidValueChange = FALSE;
            $OldValue = $G_Plugin->ConfigSetting($Name);

            # retrieve value based on configuration parameter type
            switch ($Params["Type"])
            {
                case "Flag":
                    # if radio buttons were used
                    if (array_key_exists("OnLabel", $Params)
                            && array_key_exists("OffLabel", $Params))
                    {
                        if (isset($_POST[$FieldName]))
                        {
                            $NewValue = ($_POST[$FieldName] == "1") ? TRUE : FALSE;

                            # flag that the values changed if they did
                            $DidValueChange = DidValueChange($OldValue, $NewValue);

                            $G_Plugin->ConfigSetting($Name, $NewValue);
                        }
                    }
                    # else checkbox was used
                    else
                    {
                        $NewValue = isset($_POST[$FieldName]) ? TRUE : FALSE;

                        # flag that the values changed if they did
                        $DidValueChange = DidValueChange($OldValue, $NewValue);

                        $G_Plugin->ConfigSetting($Name, $NewValue);
                    }
                    break;

                case "Option":
                    $NewValue = GetArrayValue($_POST, $FieldName, array());

                    # flag that the values changed if they did
                    $DidValueChange = DidValueChange($OldValue, $NewValue);

                    $G_Plugin->ConfigSetting($Name, $NewValue);
                    break;

                case "Privileges":
                case "MetadataField":
                    $NewValue = GetArrayValue($_POST, $FieldName, array());
                    if ($NewValue == "-1") {  $NewValue = array();  }

                    # flag that the values changed if they did
                    $DidValueChange = DidValueChange($OldValue, $NewValue);

                    $G_Plugin->ConfigSetting($Name, $NewValue);
                    break;

                default:
                    if (isset($_POST[$FieldName]))
                    {
                        $NewValue = $_POST[$FieldName];

                        # flag that the values changed if they did
                        $DidValueChange = DidValueChange($OldValue, $NewValue);

                        $G_Plugin->ConfigSetting($Name, $NewValue);
                    }
                    break;
            }

            # signal that the config setting changed if it did
            if ($DidValueChange)
            {
                $AF->SignalEvent("EVENT_PLUGIN_CONFIG_CHANGE", array(
                    "PluginName" => $Attribs["Name"],
                    "ConfigSetting" => $Name,
                    "OldValue" => $OldValue,
                    "NewValue" => $NewValue));
            }
        }
    }

    $AF->SetJumpToPage("Plugins");
}
