<?PHP

#
#   FILE:  SPT--SavedSearch.php
#
#   METHODS PROVIDED:
#       SavedSearch()
#           - constructor
#       SomeMethod($SomeParameter, $AnotherParameter)
#           - short description of method
#
#   POTENTIAL ISSUES:
#       - GetSearchGroupsAsTextDescription() does not take into account
#           operators other than "="
#
#   NOTES:
#       - the "$SearchGroups" values used herein contain a multi-dimentional
#           array in the form of:
#               $Criteria["MAIN"]["SearchStrings"][<field names>] = <value>
#           for fields with a single value, and:
#               $Criteria[<field ID>]["SearchStrings"][<field name>][] = <value>
#           for fields with multiple values
#
#   AUTHOR:  Edward Almasy
#
#   Part of the Scout Portal Toolkit
#   Copyright 2005 Internet Scout Project
#   http://scout.wisc.edu
#

# search frequency mnemonics (must match those in SPT--InstallComplete.php)

class SavedSearch {

    # ---- PUBLIC INTERFACE --------------------------------------------------
    const SEARCHFREQ_NEVER =      0;
    const SEARCHFREQ_HOURLY =     1;
    const SEARCHFREQ_DAILY =      2;
    const SEARCHFREQ_WEEKLY =     3;
    const SEARCHFREQ_BIWEEKLY =   4;
    const SEARCHFREQ_MONTHLY =    5;
    const SEARCHFREQ_QUARTERLY =  6;
    const SEARCHFREQ_YEARLY =     7;

    # object constructor
    function SavedSearch($SearchId, $SearchName = NULL, $UserId = NULL, 
            $Frequency = NULL, $SearchGroups = NULL)
    {
        # get our own database handle
        $this->DB = new SPTDatabase();

        # if search ID was provided
        if ($SearchId !== NULL)
        {
            # save search ID
            $this->SearchId = intval($SearchId);

            # initialize our local copies of data
            $this->DB->Query("SELECT * FROM SavedSearches"
                    ." WHERE SearchId = '".$this->SearchId."'");
            $this->Record = $this->DB->FetchRow();

            # update search details where provided
            if ($SearchName) {  $this->SearchName($SearchName);  }
            if ($UserId)     {  $this->SearchName($UserId);  }
            if ($Frequency)  {  $this->SearchName($Frequency);  }
        }
        else
        {
            # add new saved search to database
            $this->DB->Query("INSERT INTO SavedSearches"
                    ." (SearchName, UserId, Frequency) VALUES ("
                    ."'".addslashes($SearchName)."', "
                    .intval($UserId).", "
                    .intval($Frequency).")");

            # retrieve and save ID of new search locally
            $this->SearchId = $this->DB->LastInsertId("SavedSearches");

            # save frequency and user ID locally
            $this->Record["SearchName"] = $SearchName;
            $this->Record["UserId"] = $UserId;
            $this->Record["Frequency"] = $Frequency;
        }

        # if search parameters provided
        if ($SearchGroups != NULL)
        {
            # save search parameters
            $this->SearchGroups($SearchGroups);
        }
    }

    # get/set search parameters
    function SearchGroups($NewSearchGroups = NULL)
    {
        $Schema = new MetadataSchema();

        # if new search parameters were supplied
        if ($NewSearchGroups)
        {
            # remove existing entries for this search from the database
            $this->DB->Query("DELETE FROM SavedSearchTextParameters WHERE SearchId = ".$this->SearchId);
            $this->DB->Query("DELETE FROM SavedSearchIdParameters WHERE SearchId = ".$this->SearchId);

            # for each search group
            foreach ($NewSearchGroups as $GroupIndex => $Group)
            {
                # if group holds single parameters
                if ($GroupIndex == "MAIN")
                {
                    # for each field within group
                    foreach ($Group["SearchStrings"] as $FieldName => $Value)
                    {
                        # convert value array to single value (if necessary)
                        if (is_array($Value))
                        {
                            $ConvertedValue = "";
                            foreach ($Value as $SingleValue)
                            {
                                $ConvertedValue .= $SingleValue." ";
                            }
                            $Value = trim($ConvertedValue);
                        }

                        # add new text search parameter entry to database
                        if ($FieldName == "XXXKeywordXXX")
                        {
                            $FieldId = -101;
                        }
                        else
                        {
                            $Field = $Schema->GetFieldByName($FieldName);
                            $FieldId = $Field->Id();
                        }
                        $this->DB->Query("INSERT INTO SavedSearchTextParameters"
                                ." (SearchId, FieldId, SearchText) VALUES"
                                ." (".$this->SearchId.", ".$FieldId.", '".addslashes($Value)."')");
                    }
                }
                else
                {
                    # convert value(s) as appropriate for field type
                    $FieldId = $GroupIndex;
                    $Field = $Schema->GetField($FieldId);
                    $FieldName = $Field->Name();
                    $Values = SavedSearch::TranslateValues($Field, $Group["SearchStrings"][$FieldName], "SearchGroup to Database");
                        
                    # for each converted value
                    foreach ($Values as $Value)
                    {
                        # add new ID search parameter entry to database
                        $this->DB->Query("INSERT INTO SavedSearchIdParameters"
                                ." (SearchId, FieldId, SearchValueId) VALUES"
                                ." (".$this->SearchId.", ".$FieldId.", ".$Value.")");
                    }
                }
            }

            # save search parameters locally
            $this->SearchGroups = $NewSearchGroups;
        }
        else
        {
            # if search groups not already read in
            if (!isset($this->SearchGroups))
            {
                # for each text search parameter
                $SearchGroups = array();
                $this->DB->Query("SELECT * FROM SavedSearchTextParameters WHERE SearchId = ".$this->SearchId);
                while ($Record = $this->DB->FetchRow())
                {
                    # add parameter to search criteria
                    if ($Record["FieldId"] == -101)
                    {
                        $SearchGroups["MAIN"]["SearchStrings"]["XXXKeywordXXX"] = 
                                $Record["SearchText"];
                    }
                    else
                    {
                        $Field = $Schema->GetField($Record["FieldId"]);
                        $SearchGroups["MAIN"]["SearchStrings"][$Field->Name()] = 
                                $Record["SearchText"];
                    }
                }

                # for each value ID search parameter
                $this->DB->Query("SELECT * FROM SavedSearchIdParameters WHERE SearchId = ".$this->SearchId);
                while ($Record = $this->DB->FetchRow())
                {
                    # translate value based on field type
                    $FieldId = $Record["FieldId"];
                    if (!isset($Fields[$FieldId])) {  $Fields[$FieldId] = new MetadataField($FieldId);  }
                    $Values = SavedSearch::TranslateValues($Fields[$FieldId], 
                            $Record["SearchValueId"], "Database to SearchGroup");

                    # add parameter to search criteria
                    foreach ($Values as $Value)
                    {
                        $SearchGroups[$FieldId]["SearchStrings"][$Fields[$FieldId]->Name()][] = $Value;
                    }
                }

                # set appropriate logic in search parameters
                foreach ($SearchGroups as $GroupIndex => $Group)
                {
                    $SearchGroups[$GroupIndex]["Logic"] = 
                            ($GroupIndex == "MAIN") ? SearchEngine::SEARCHLOGIC_AND 
                            : SearchEngine::SEARCHLOGIC_OR;
                }

                # save search parameters locally
                $this->SearchGroups = $SearchGroups;
            }
        }

        # return search parameters to caller
        return $this->SearchGroups;
    }

    # get/set name of search
    function SearchName($NewValue = DB_NOVALUE)
    {
        return $this->DB->UpdateValue("SavedSearches", "SearchName", $NewValue,
               "SearchId = ".$this->SearchId, $this->Record, TRUE);
    }

    # get ID of search
    function GetSearchId()
    {
        return $this->SearchId;
    }

    # get/set user ID
    function UserId($NewValue = DB_NOVALUE)
    {
        return intval($this->DB->UpdateValue("SavedSearches", "UserId", $NewValue,
               "SearchId = ".$this->SearchId, $this->Record));
    }

    # get/set search frequency
    function Frequency($NewValue = DB_NOVALUE)
    {
        return $this->DB->UpdateValue("SavedSearches", "Frequency", $NewValue,
               "SearchId = ".$this->SearchId, $this->Record);
    }

    # set date search was last run to current date/time
    function UpdateDateLastRun()
    {
        $this->DB->Query("UPDATE SavedSearches SET DateLastRun = NOW() WHERE SearchId = ".$this->SearchId);
    }

    # get/set date search was last run
    function DateLastRun($NewValue = DB_NOVALUE)
    {
        return $this->DB->UpdateValue("SavedSearches", "DateLastRun", $NewValue,
               "SearchId = ".$this->SearchId, $this->Record);
    }

    # get search parameters in the form of URL GET-encoded values
    # (e.g. returns something like F2=madison&F4=american+history&G22=17-41)
    # (may be called statically by supplying $SearchGroups value)
    function TranslateSearchGroupsToUrlParameters($SearchGroups = NULL)
    {
        # if search groups were not supplied
        if ($SearchGroups == NULL)
        {
            # if we are part of an instance
            if (isset($this) && ($this instanceof SavedSearch))
            {
                # use our search groups
                $SearchGroups = $this->SearchGroups();
            }
            else
            {
                # return empty string to caller
                return "";
            }
        }

        # assume that no parameters will be found
        $UrlPortion = "";
    
        # for each group in parameters
        $Schema = new MetadataSchema();
        foreach ($SearchGroups as $GroupIndex => $Group)
        {
            # if group holds single parameters
            if ($GroupIndex == "MAIN")
            {
                # for each field within group
                foreach ($Group["SearchStrings"] as $FieldName => $Value)
                {
                    # add segment to URL for this field
                    if ($FieldName == "XXXKeywordXXX")
                    {
                        $FieldId = "K";
                    }
                    else
                    {
                        $Field = $Schema->GetFieldByName($FieldName);
                        $FieldId = $Field->Id();
                    }
                    if (is_array($Value))
                    {
                        $UrlPortion .= "&F".$FieldId."=";
                        $ValueString = "";
                        foreach ($Value as $SingleValue)
                        {
                            $ValueString .= $SingleValue." ";
                        }
                        $UrlPortion .= urlencode(trim($ValueString));
                    }
                    else
                    {
                        $UrlPortion .= "&F".$FieldId."=".urlencode($Value);
                    }
                }
            }
            else
            {
                # convert value based on field type
                $FieldId = $GroupIndex;
                $Field = $Schema->GetField($FieldId);
                $FieldName = $Field->Name();
                $Values = SavedSearch::TranslateValues($Field, $Group["SearchStrings"][$FieldName], "SearchGroup to Database");

                # add values to URL
                $FirstValue = TRUE;
                foreach ($Values as $Value)
                {
                    if ($FirstValue)
                    {   
                        $FirstValue = FALSE;
                        $UrlPortion .= "&G".$FieldId."=".$Value;
                    }
                    else
                    {   
                        $UrlPortion .= "-".$Value;
                    }
                }
            }
        }
        
        # trim off any leading "&"  
        if (strlen($UrlPortion)) {  $UrlPortion = substr($UrlPortion, 1);  }
        
        # return URL portion to caller
        return $UrlPortion;
    }

    # set search groups from URL (GET method) parameters
    # (returns search group array)
    function TranslateUrlParametersToSearchGroups($GetVars)
    {
        # if URL segment was passed in instead of GET var array
        if (is_string($GetVars))
        {
            # split URL segment into GET var array
            $VarAssignments = explode("&", $GetVars);
            $GetVars = array();
            foreach ($VarAssignments as $VarAss)
            {
                $VarAssBits = explode("=", $VarAss);
                if (isset($VarAssBits[1]))
                {
                    $GetVars[$VarAssBits[0]] = urldecode($VarAssBits[1]);
                }
            }
        }

        # start with empty list of parameters
        $SearchGroups = array();
                
        # for each possible metadata field ID 
        $Schema = new MetadataSchema();
        $HighestFieldId = $Schema->GetHighestFieldId();
        for ($FieldId = 0;  $FieldId <= $HighestFieldId;  $FieldId++)
        {           
            # if field exists for this ID
            $Field = $Schema->GetField($FieldId);
            if ($Field)
            {
                # if URL included literal value for this field
                $FieldName = $Field->Name();
                if (isset($GetVars["F".$FieldId]))
                {
                    # retrieve value and add to search parameters
                    $SearchGroups["MAIN"]["SearchStrings"][$FieldName] = $GetVars["F".$FieldId];
                }
                
                # if URL included group value for this field
                if (isset($GetVars["G".$FieldId]))
                {
                    # retrieve and parse out values
                    $Values = explode("-", $GetVars["G".$FieldId]);

                    # translate values
                    $Values = SavedSearch::TranslateValues($Field, $Values, "Database to SearchGroup");

                    # add values to searchgroups
                    $SearchGroups[$FieldId]["SearchStrings"][$FieldName] = $Values;
                }
            }
        }

        # if keyword psuedo-field was included in URL
        if (isset($GetVars["FK"]))
        {
            # retrieve value and add to search parameters
            $SearchGroups["MAIN"]["SearchStrings"]["XXXKeywordXXX"] = $GetVars["FK"];
        }
    
        # set search logic
        foreach ($SearchGroups as $GroupIndex => $Group)
        {
            $SearchGroups[$GroupIndex]["Logic"] = ($GroupIndex == "MAIN") 
                    ? SearchEngine::SEARCHLOGIC_AND : SearchEngine::SEARCHLOGIC_OR;
        }

        # save parameters (if we're an instance)
        if (isset($this) && ($this instanceof SavedSearch))
        {
            $this->SearchGroups($SearchGroups);
        }
    
        # return parameters to caller
        return $SearchGroups;
    }

    # return multi-line string describing search criteria
    # (may be called statically by supplying $SearchGroups value)
    function GetSearchGroupsAsTextDescription($SearchGroups = NULL, 
            $IncludeHtml = TRUE, $StartWithBreak = TRUE, $TruncateLongWordsTo = 0)
    {
        # if search groups were not supplied
        if ($SearchGroups == NULL)
        {
            # if we are part of an instance
            if (isset($this) && ($this instanceof SavedSearch))
            {
                # use our search groups
                $SearchGroups = $this->SearchGroups();
            }
            else
            {
                # return empty string to caller
                return "";
            }
        }

        # start with empty description
        $Descrip = "";

        # set characters used to indicate literal strings
        $LiteralStart = $IncludeHtml ? "<i>" : "\"";
        $LiteralEnd = $IncludeHtml ? "</i>" : "\"";
        $LiteralBreak = $IncludeHtml ? "<br>\n" : "\n";

        # if this is a simple keyword search
        if (isset($SearchGroups["MAIN"]["SearchStrings"]["XXXKeywordXXX"])
            && (count($SearchGroups) == 1)
            && (count($SearchGroups["MAIN"]["SearchStrings"]) == 1))
        {
            # just use the search string
            $Descrip .= $LiteralStart.htmlspecialchars($SearchGroups["MAIN"]["SearchStrings"]["XXXKeywordXXX"]).$LiteralEnd.$LiteralBreak;
        }
        else
        {
            # start description on a new line (if requested)
            if ($StartWithBreak)
            {
                $Descrip .= $LiteralBreak;
            }

            # define list of phrases used to represent logical operators
            $WordsForOperators = array(
                    "=" => "is",
                    ">" => "is greater than",
                    "<" => "is less than",
                    ">=" => "is at least",
                    "<=" => "is no more than",
                    "!" => "is not",
                    );

            # for each search group
            foreach ($SearchGroups as $GroupIndex => $Group)
            {
                # if group is main
                if ($GroupIndex == "MAIN")
                {
                    # for each field in group
                    foreach ($Group["SearchStrings"] as $FieldName => $Value)
                    { 
                        # convert keyword pseudo-field name if necessary
                        if ($FieldName == "XXXKeywordXXX") {  $FieldName = "Keyword";  }
    
                        # determine wording based on operator
                        preg_match("/^[=><!]+/", $Value, $Matches);
                        if (count($Matches) && isset($WordsForOperators[$Matches[0]]))
                        {
                            $Value = preg_replace("/^[=><!]+/", "", $Value);
                            $Wording = $WordsForOperators[$Matches[0]];
                        }
                        else
                        {
                            $Wording = "contains";
                        }
                            
                        # add criteria for field
                        $Descrip .= $FieldName." ".$Wording." "
                                .$LiteralStart.htmlspecialchars($Value)
                                        .$LiteralEnd.$LiteralBreak;
                    }
                }
                else
                {
                    # for each field in group
                    foreach ($Group["SearchStrings"] as $FieldName => $Values)
                    {   
                        # translate values
                        $Values = SavedSearch::TranslateValues($FieldName, $Values, "SearchGroup to Display");
    
                        # for each value
                        $FirstValue = TRUE;
                        foreach ($Values as $Value)
                        {
                            # determine wording based on operator
                            preg_match("/^[=><!]+/", $Value, $Matches);
                            $Operator = $Matches[0];
                            $Wording = $WordsForOperators[$Operator];
                            
                            # strip off operator
                            $Value = preg_replace("/^[=><!]+/", "", $Value);
    
                            # add text to description
                            if ($FirstValue)
                            {
                                $Descrip .= $FieldName." ".$Wording." ".$LiteralStart.htmlspecialchars($Value).$LiteralEnd.$LiteralBreak;
                                $FirstValue = FALSE;
                            }
                            else
                            {
                                $Descrip .= ($IncludeHtml ? "&nbsp;&nbsp;&nbsp;&nbsp;" : "    ")
                                        ."or ".$Wording." ".$LiteralStart
                                        .htmlspecialchars($Value).$LiteralEnd
                                        .$LiteralBreak;
                            }
                        }
                    }
                }
            }
        }

        # if caller requested that long words be truncated
        if ($TruncateLongWordsTo > 4)
        {
            # break description into words
            $Words = explode(" ", $Descrip);

            # for each word
            $NewDescrip = "";
            foreach ($Words as $Word)
            {
                # if word is longer than specified length
                if (strlen(strip_tags($Word)) > $TruncateLongWordsTo)
                {
                    # truncate word and add ellipsis
                    $Word = substr($Word, 0, ($TruncateLongWordsTo - 3))."...";
                }

                # add word to new description
                $NewDescrip .= " ".$Word;
            }

            # set description to new description
            $Descrip = $NewDescrip;
        }

        # return description to caller
        return $Descrip;
    }

    # get list of fields to be searched (returns array of field names)
    # (may be called statically by supplying search groups)
    function GetSearchFieldNames($SuppliedSearchGroups = NULL)
    {
        # make sure search groups are loaded
        if ($SuppliedSearchGroups !== NULL)
        {
            $SearchGroups = $SuppliedSearchGroups;
        }
        else
        {
            if (!isset($this->SearchGroups)) {  $this->SearchGroups();  }
            $SearchGroups = $this->SearchGroups;
        }

        # start out assuming no fields are being searched
        $FieldNames = array();

        # for each search group defined
        foreach ($SearchGroups as $GroupIndex => $Group)
        {
            # for each field in group
            foreach ($Group["SearchStrings"] as $FieldName => $Values)
            {   
                # add field name to list of fields being searched
                $FieldNames[] = $FieldName;
            }
        }

        # return list of fields being searched to caller
        return $FieldNames;
    }

    # return array of possible search frequency descriptions with mnemonics as indices
    # (frequencies may be excluded from list by supplying them as arguments)
    static function GetSearchFrequencyList()
    {
        # define list with descriptions
        $FreqDescr = array(
                self::SEARCHFREQ_NEVER     => "Never",
                self::SEARCHFREQ_HOURLY    => "Hourly",
                self::SEARCHFREQ_DAILY     => "Daily",
                self::SEARCHFREQ_WEEKLY    => "Weekly",
                self::SEARCHFREQ_BIWEEKLY  => "Bi-Weekly",
                self::SEARCHFREQ_MONTHLY   => "Monthly",
                self::SEARCHFREQ_QUARTERLY => "Quarterly",
                self::SEARCHFREQ_YEARLY    => "Yearly",
                );

        # for each argument passed in
        $Args = func_get_args();
        foreach ($Args as $Arg)
        {
            # remove value from list
            $FreqDescr = array_diff_key($FreqDescr, array($Arg => ""));
        }

        # return list to caller
        return $FreqDescr;
    }

    # remove search from database
    # (NOTE:  object is no longer usable after this call!)
    function Delete()
    {
        $this->DB->Query("DELETE FROM SavedSearches WHERE SearchId = '".addslashes($this->SearchId)."'");
        $this->DB->Query("DELETE FROM SavedSearchTextParameters WHERE SearchId = '".addslashes($this->SearchId)."'");
        $this->DB->Query("DELETE FROM SavedSearchIdParameters WHERE SearchId = '".addslashes($this->SearchId)."'");
    }


    # ---- PRIVATE INTERFACE -------------------------------------------------

    var $SearchId;
    var $Record;
    var $SearchGroups;

    # utility function to convert between value representations
    # (method accepts a value or array and always return an array)
    # (this is needed because values are represented differently:
    #                                 FLAG    USER    OPTION
    #     in DB / in URL / in forms   0/1     123     456    
    #     used in SearchGroups        0/1     jdoe    cname
    #     displayed to user           On/Off  jdoe    cname
    # where "123" and "456" are option or controlled name IDs)
    static function TranslateValues($FieldOrFieldName, $Values, $TranslationType)
    {
        # start out assuming we won't find any values to translate
        $ReturnValues = array();

        # convert field name to field object if necessary
        if (is_object($FieldOrFieldName))
        {
            $Field = $FieldOrFieldName;
        }
        else
        {
            static $Schema;
            if (!isset($Schema)) {  $Schema = new MetadataSchema();  }
            $Field = $Schema->GetFieldByName($FieldOrFieldName);
        }

        # if incoming value is not an array
        if (!is_array($Values))
        {
            # convert incoming value to an array
            $Values = array($Values);
        }

        # for each incoming value
        foreach ($Values as $Value)
        {
            switch ($TranslationType)
            {
                case "SearchGroup to Display":
                    # if field is Flag field
                    if ($Field->Type() == MetadataSchema::MDFTYPE_FLAG)
                    {
                        # translate value to true/false label and add leading operator
                        $ReturnValues[] = ($Value == "=1") ? "=".$Field->FlagOnLabel() : "=".$Field->FlagOffLabel();
                    }
                    elseif ($Field->Name() == "Cumulative Rating")
                    {
                        # translate numeric value to stars
                        $StarStrings = array(
                                "20" => "*",
                                "40" => "**",
                                "60" => "***",
                                "80" => "****",
                                "100" => "*****",
                                );
                        preg_match("/[0-9]+$/", $Value, $Matches);
                        $Number = $Matches[0];
                        preg_match("/^[=><!]+/", $Value, $Matches);
                        $Operator = $Matches[0];
                        $ReturnValues[] = $Operator.$StarStrings[$Number];
                    }
                    else
                    {
                        # use value as is
                        $ReturnValues[] = $Value;
                    }
                    break;

                case "SearchGroup to Database":
                    # strip off leading operator on value
                    $Value = preg_replace("/^[=><!]+/", "", $Value);
        
                    # look up index for value
                    if ($Field->Type() & (MetadataSchema::MDFTYPE_FLAG|MetadataSchema::MDFTYPE_NUMBER))
                    {
                        # (for flag or number fields the value index is already what is used in SearchGroups)
                        if ($Value >= 0)
                        {
                            $ReturnValues[] = $Value;
                        }
                    }
                    elseif ($Field->Type() == MetadataSchema::MDFTYPE_USER)
                    {
                        # (for user fields the value index is the user ID)
                        $User = new SPTUser(strval($Value));
                        if ($User)
                        {
                            $ReturnValues[] = $User->Id();
                        }
                    }
                    elseif ($Field->Type() == MetadataSchema::MDFTYPE_OPTION)
                    {
                        if (!isset($PossibleFieldValues))
                        {  
                            $PossibleFieldValues = $Field->GetPossibleValues();
                        }
                        $NewValue = array_search($Value, $PossibleFieldValues);
                        if ($NewValue !== FALSE)
                        {
                            $ReturnValues[] = $NewValue;
                        }
                    }
                    else
                    {
                        $NewValue = $Field->GetIdForValue($Value);
                        if ($NewValue !== NULL)
                        {
                            $ReturnValues[] = $NewValue;
                        }
                    }
                    break;

                case "Database to SearchGroup":
                    # look up value for index
                    if ($Field->Type() == MetadataSchema::MDFTYPE_FLAG)
                    {
                        # (for flag fields the value index (0 or 1) is already what is used in Database)
                        if ($Value >= 0)
                        {
                            $ReturnValues[] = "=".$Value;
                        }
                    }
                    elseif ($Field->Type() == MetadataSchema::MDFTYPE_NUMBER)
                    {
                        # (for flag fields the value index (0 or 1) is already what is used in Database)
                        if ($Value >= 0)
                        {
                            $ReturnValues[] = ">=".$Value;
                        }
                    }
                    elseif ($Field->Type() == MetadataSchema::MDFTYPE_USER)
                    {
                        $User = new SPTUser(intval($Value));
                        if ($User)
                        {
                            $ReturnValues[] = "=".$User->Get("UserName");
                        }
                    }
                    elseif ($Field->Type() == MetadataSchema::MDFTYPE_OPTION)
                    {
                        if (!isset($PossibleFieldValues))
                        {
                            $PossibleFieldValues = $Field->GetPossibleValues();
                        }

                        if (isset($PossibleFieldValues[$Value]))
                        {
                            $ReturnValues[] = "=".$PossibleFieldValues[$Value];
                        }
                    }
                    else
                    {
                        $NewValue = $Field->GetValueForId($Value);
                        if ($NewValue !== NULL)
                        {
                            $ReturnValues[] = "=".$NewValue;
                        }
                    }
                    break;
            }
        }

        # return array of translated values to caller
        return $ReturnValues;
    }
}


?>
