<?PHP

$GLOBALS["G_ErrMsgs"] = SiteUpgrade320_PerformUpgrade();

/**
* Perform all of the site upgrades for 3.2.0.
* @return Returns NULL on success and an eror message if an error occurs.
*/
function SiteUpgrade320_PerformUpgrade()
{
    try
    {
        Msg(1, "Migrating Google Analytics settings to plugin...");
        SiteUpgrade320_TransferGoogleAnalyticsSetting();

        Msg(1, "Fixing HTML entity encoding in the database...");
        SiteUpgrade320_FixEntityEncoding();

        Msg(2, "Populating LastMatchingIds column of the database...");
        SiteUpgrade320_PopulateSavedSearchIds();
    }

    catch (Exception $Exception)
    {
        return array($Exception->getMessage(),
                "Exception Trace:<br/><pre>"
                        .$Exception->getTraceAsString()."</pre>");
    }
}

/**
* Remove entity encoding from the database where it was helpfully added by CKEditor
*/
function SiteUpgrade320_FixEntityEncoding()
{
    global $G_SysConfig;

    $DB = new Database();

    # iterate over all the schemas
    foreach (MetadataSchema::GetAllSchemas() as $Schema)
    {
        # and iterate over the fields that might contain entities
        foreach ($Schema->GetFields(MetadataSchema::MDFTYPE_TEXT |
                                    MetadataSchema::MDFTYPE_PARAGRAPH) as $Field)
        {
            # pull out all the values for this field
            $DBName = $Field->DBFieldName();
            $DB->Query("SELECT ResourceId, ".$DBName." AS Val "
                       ."FROM Resources WHERE ".$DBName." IS NOT NULL");
            $Values = $DB->FetchColumn("Val", "ResourceId");

            # iterate over all of those
            foreach ($Values as $Id => $Val)
            {
                # if stripping entities out of a value changes it,
                # update the database with the new, stripped value
                $ValStripped = html_entity_decode($Val,
                        ENT_COMPAT, $G_SysConfig->DefaultCharacterSet());
                if ($Val != $ValStripped)
                {
                    $DB->Query(
                        "UPDATE Resources SET ".$DBName."='".addslashes($ValStripped)."'"
                        ." WHERE ResourceId=".$Id);
                }
            }
        }
    }
}

/**
* Populate the LastUpdatedIds column for saved searches.
*/
function SiteUpgrade320_PopulateSavedSearchIds()
{
    # get searches that need to be run
    $SSFactory = new SavedSearchFactory();
    $Searches = $SSFactory->GetItems();

    # for each search
    foreach ($Searches as $Search)
    {
        # if LastMatches for this search is already populated,
        # continue along to the next search
        if (count($Search->LastMatches()) > 0)
        {
            continue;
        }

        # get objects we'll need
        if (!isset($SearchEngine)) { $SearchEngine = new SPTSearchEngine();  }
        if (!isset($RFactory))     { $RFactory = new ResourceFactory();      }

        # retrieve search criteria and target user
        $SearchGroups = $Search->SearchGroups();
        $EndUser = new CWUser(intval($Search->UserId()));

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

        # attempt to perform the search
        try
        {
            $SearchResults = $SearchEngine->GroupedSearch($SearchGroups);
        }
        catch (Exception $e)
        {
            # if the search failed for any reason (e.g., it references
            # a deleted field) continue on to the next search
            continue;
        }

        # remove resources that the user cannot view
        $ViewableResourceIds = $RFactory->FilterNonViewableResources(
            array_keys($SearchResults), $EndUser);
        $SearchResults = array_intersect_key(
            $SearchResults, array_flip($ViewableResourceIds));

        # if search results were found
        if (count($SearchResults))
        {
            #save these matches for future comparisons
            $Search->SaveLastMatches(array_keys($SearchResults));
        }
    }
}

/**
* Transfer Google Analytics settings to plugin and DROP necessary
* column from SystemConfiguration
*/
function SiteUpgrade320_TransferGoogleAnalyticsSetting()
{
    # check if transfer has already been done
    $DB = new Database();
    $TransferComplete = $DB->FieldExists("SystemConfiguration", "AddGoogleAnalytics") ?
                      FALSE : TRUE;
    if ($TransferComplete) { return; }

    # migrate to plugin if plugin is not enabled
    $Enabled = $GLOBALS["G_PluginManager"]->PluginEnabled("GoogleAnalytics");

    if (!$Enabled)
    {
        $GoogleAnalyticsPlugin =
                $GLOBALS["G_PluginManager"]->GetPlugin("GoogleAnalytics", TRUE);

        $DB->Query("SELECT * FROM SystemConfiguration");
        $UseGoogleAnalytics = $DB->FetchField("AddGoogleAnalytics");
        $DB->Query("SELECT * FROM SystemConfiguration");
        $GoogleAnalyticsCode = $DB->FetchField("GoogleAnalyticsCode");

        # validate Analytics Code
        $Pattern = "/UA-[0-9]{6}-[0-9]+/";
        $GoogleAnalyticsCodeValid = preg_match($Pattern, $GoogleAnalyticsCode, $Match);


        # if user used Google Analytics before
        if ($UseGoogleAnalytics && $GoogleAnalyticsCodeValid)
        {
            $GoogleAnalyticsCode = $Match[0];
            $GoogleAnalyticsPlugin->ConfigSetting("TrackingId", $GoogleAnalyticsCode);

            # enable Google Analytics
            $GLOBALS["G_PluginManager"]->PluginEnabled("GoogleAnalytics", TRUE);
        }
    }


    # drop the unnecessary field from SystemConfiguration
    $DB->Query("ALTER TABLE SystemConfiguration DROP COLUMN `AddGoogleAnalytics`");
    $DB->Query("ALTER TABLE SystemConfiguration DROP COLUMN `GoogleAnalyticsCode`");
}
