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

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

/**
 * Get sorting information from GET parameters.
 * @return array 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->Status() == MetadataSchema::MDFSTAT_OK)
        {
            $SortField = $Field;
        }
    }

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

        if ($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);
}

/**
 * Peform a search using the given search groups and sorting info.
 * @param array $SearchGroups search group parameters
 * @param string $SortFieldName name of the field to sort by
 * @param bool $SortDescending TRUE to sort descending
 * @return array search results
 */
function PerformSearch(array $SearchGroups, $SortFieldName, $SortDescending)
{
    global $AF, $SysConfig, $User;

    $Schema = new MetadataSchema();
    $SearchEngine = new SPTSearchEngine();

    function FilterOutTempResources($Id) {  return ($Id < 0);  }

    $SearchEngine->AddResultFilterFunction("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;
}

# ----- 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);

        # enforce a limit on how many resources can be added at once to avoid
        # performance issues
        if (count($SearchResults) <= Folders_Common::MAX_RESOURCES_PER_ADD)
        {
            # add each result
            foreach ($SearchResults as $ResourceId => $Score)
            {
                $Resource = new Resource($ResourceId);

                if ($Resource->Status() === 1)
                {
                    $Folder->AppendItem($Resource->Id());
                }
            }
        }
    }
} catch (Exception $Exception) {}
