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

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

/**
* Get sorting information from GET parameters.
* @return Returns an array containing the sort field name and sort descending
*      value
*/
function GetSortInfo()
{
    global $SysConfig;

    $Schema = new MetadataSchema();
    $SortField = NULL;
    $SortFieldId = GetArrayValue($_GET, "SF");
    $SortDescending = GetArrayValue($_GET, "SD");

    # use specified sort field
    if ($SortFieldId)
    {
        $Field = $Schema->GetField(intval($SortFieldId));

        if ($Field instanceof MetadataField
            && $Field->Status() == MetadataSchema::MDFSTAT_OK)
        {
            $SortField = $Field;
        }
    }

    # use the default sort field
    if (is_null($SortField))
    {
        $Field = $Schema->GetField(intval($SysConfig->DefaultSortField()));

        if ($Field instanceof MetadataField
            && $Field->Status() == MetadataSchema::MDFSTAT_OK)
        {
            $SortField = $Field;
        }
    }

    # use the sort order specified
    if (!is_null($SortDescending))
    {
        $SortDescending = (bool) $SortDescending;
    }

    # use the sort order defaults for the given sort field
    else if (!is_null($SortField))
    {
        switch ($SortField->Type())
        {
            case MetadataSchema::MDFTYPE_NUMBER:
            case MetadataSchema::MDFTYPE_DATE:
            case MetadataSchema::MDFTYPE_TIMESTAMP:
                $SortDescending = TRUE; break;
            default:
                $SortDescending = FALSE; break;
        }
    }

    # otherwise sort descending by default
    else
    {
        $SortDescending = TRUE;
    }

    $SortFieldName = $SortField instanceof MetadataField
        ? $SortField->Name() : $SortField;

    return array($SortFieldName, $SortDescending);
}

/**
* Perform a search using the given search groups and sorting info.
* @param array $SearchGroups Search group parameters for the search engine.
* @param string $SortFieldName Name of the field to sort by.
* @param bool $SortDescending TRUE to sort the results in descending order.
* @return Returns an array of search results.
*/
function PerformSearch(array $SearchGroups, $SortFieldName, $SortDescending)
{
    global $AF, $SysConfig, $User;

    $Schema = new MetadataSchema();
    $SearchEngine = new SPTSearchEngine();
    $SearchEngine->AddResultFilterFunction("Folders_FilterOutTempResources");

    # if global search results filter is specified
    if (function_exists("FilterSearchResults"))
    {
        $SearchEngine->AddResultFilterFunction("FilterSearchResults");
    }

    # if local search results filter is specified
    if (function_exists("Local_FilterSearchResult"))
    {
        $SearchEngine->AddResultFilterFunction("Local_FilterSearchResult");
    }

    # filter out unreleased resources if the user should not see them
    if (!$User->HasPriv(PRIV_RELEASEADMIN, PRIV_RESOURCEADMIN))
    {
        $SearchGroup = array();
        $ReleaseField = $Schema->GetFieldByName("Release Flag");
        $AddedByField = $Schema->GetFieldByName("Added By Id");

        # add condition to keep only released resources
        $SearchGroup["SearchStrings"]["Release Flag"] = "=1";
        $SearchGroup["Logic"] = SearchEngine::LOGIC_AND;

        # add condition to keep resources added by the user
        if ($User->HasPriv(PRIV_MYRESOURCEADMIN))
        {
            $SearchGroup["SearchStrings"]["Added By Id"] = "=" . $User->Name();
            $SearchGroup["Logic"] = SearchEngine::LOGIC_OR;
        }

        $SearchGroups[$ReleaseField->Id()] = $SearchGroup;
    }

    # signal keyword search if appropriate
    if (isset($SearchGroups["MAIN"]["SearchStrings"]["XXXKeywordXXX"]))
    {
        $SignalResult = $AF->SignalEvent("EVENT_KEYWORD_SEARCH", array(
            "Keywords" =>
                $SearchGroups["MAIN"]["SearchStrings"]["XXXKeywordXXX"]));
        $SearchGroups["MAIN"]["SearchStrings"]["XXXKeywordXXX"]
            = $SignalResult["Keywords"];
    }

    $SearchGroups["MAIN"]["Logic"] = $SysConfig->SearchTermsRequired() ?
            SearchEngine::LOGIC_AND : SearchEngine::LOGIC_OR;

    # signal event to allow modification of search parameters
    $SignalResult = $GLOBALS["AF"]->SignalEvent("EVENT_FIELDED_SEARCH", array(
        "SearchGroups" => $SearchGroups,
        "User" => $GLOBALS["G_User"],
        "SavedSearch" => NULL));
    $SearchGroups = $SignalResult["SearchGroups"];

    # perform search
    $SearchResults = $SearchEngine->GroupedSearch(
        $SearchGroups,
        0,
        9999999,
        $SortFieldName,
        $SortDescending);

    return $SearchResults;
}

/**
* Callback function used with search engine objects to filter out temporary
* resources.
* @param int $Id Resource ID to check.
* @return Returns TRUE if the resource ID is less than zero.
*/
function Folders_FilterOutTempResources($Id)
{
    return $Id < 0;
}

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

# check authorization and setup HTML suppression and page redirection
if (!Folders_Common::ApiPageCompletion("P_Folders_ManageFolders")) return;

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

# get the currently selected folder if no folder ID is given
if (!strlen($FolderId))
{
    $FolderFactory = new Folders_FolderFactory($User->Id());
    $FolderId = $FolderFactory->GetSelectedFolder()->Id();
}

try
{
    $FolderFactory = new Folders_FolderFactory($User->Id());
    $ResourceFolder = $FolderFactory->GetResourceFolder();
    $Folder = new Folders_Folder($FolderId);

    # add items only if the resource folder contains this folder, which implies
    # that the user owns the folder and it's a valid folder of resources
    if ($ResourceFolder->ContainsItem($Folder->Id()))
    {
        $SearchGroups = SavedSearch::TranslateUrlParametersToSearchGroups($_GET);
        list($SortFieldName, $SortDescending) = GetSortInfo();

        $SearchResults = PerformSearch(
            $SearchGroups,
            $SortFieldName,
            $SortDescending);

        # get a list of valid ResourceIds, use this to filter what we add
        $ValidIds = array();
        $RFactory = new ResourceFactory();
        foreach ($RFactory->GetItemIds() as $Id)
            $ValidIds[$Id] = 1;

        # add each result that is valid
        $ToAdd = array();
        foreach ($SearchResults as $ResourceId => $Score)
        {
            if (isset($ValidIds[$ResourceId]))
                $ToAdd []= $ResourceId;
        }

        $Folder->AppendItems( $ToAdd );
    }
} catch (Exception $Exception) {}
