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

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

# Helper function to deal with data summary arrays:
function CreateOrIncrement(&$Array, $Key)
{
    if (!isset($Array[$Key]))
        $Array[$Key] = 1;
    else
        $Array[$Key]++;
}

/**
* Summarize view counts after a specified date
* @param $StartDate Starting date
* @return array View count summary
*/
function GetViewCountData($StartTS)
{
    $Recorder = $GLOBALS["G_PluginManager"]->GetPlugin("MetricsRecorder");
    $Reporter = $GLOBALS["G_PluginManager"]->GetPlugin("MetricsReporter");

    $StartDate = date('Y-m-d', $StartTS);

    $Data = $Reporter->CacheGet("ViewCounts".$StartDate);

    if (is_null($Data))
    {

        $RFactory = new ResourceFactory();
        $AllResourceIds = $RFactory->GetItemIds();

        $Data = $Recorder->GetFullRecordViewCounts(
            MetadataSchema::SCHEMAID_DEFAULT,
            $StartDate, NULL, 0, 15,
            $Reporter->ConfigSetting("PrivsToExcludeFromCounts") );
        $Data["StartDate"] = $StartDate;
        $Data["EndDate"]   = date('Y-m-d');

        $Data["Total"] = $Recorder->GetEventCounts(
            "MetricsRecorder", MetricsRecorder::ET_FULLRECORDVIEW,
            NULL, $StartDate, NULL, NULL,
            $AllResourceIds, NULL,
            $Reporter->ConfigSetting("PrivsToExcludeFromCounts") );

        $Reporter->CachePut("ViewCounts".$StartDate, $Data);
    }

    return $Data;
}

/**
* Summarize URL clicks after a specified date
* @param $StartDate starting date
* @param $Field MetadataField of interest
* @return array View count summary
*/
function GetClickCountData($StartTS, $Field)
{
    $Recorder = $GLOBALS["G_PluginManager"]->GetPlugin("MetricsRecorder");
    $Reporter = $GLOBALS["G_PluginManager"]->GetPlugin("MetricsReporter");

    $StartDate = date('Y-m-d', $StartTS);

    $Data = $Reporter->CacheGet("ClickCounts".$StartDate);

    if (is_null($Data))
    {
        $Data = $Recorder->GetUrlFieldClickCounts(
            $Field->Id(), $StartDate,
            NULL, 0, 15, $Reporter->ConfigSetting("PrivsToExcludeFromCounts") );
        $Data["StartDate"] = $StartDate;
        $Data["EndDate"]   = date('Y-m-d');

        $Data["Total"] = $Recorder->GetEventCounts(
            "MetricsRecorder", MetricsRecorder::ET_URLFIELDCLICK,
            NULL, $StartDate, NULL, NULL,
            NULL, $Field->Id(),
            $Reporter->ConfigSetting("PrivsToExcludeFromCounts") );

        $Reporter->CachePut("ClickCounts".$StartDate, $Data);
    }

    return $Data;
}

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

PageTitle("Collection Usage Metrics");

# make sure user has sufficient permission to view report
if (!CheckAuthorization(PRIV_COLLECTIONADMIN)) {  return;  }

# Grab ahold of the relevant metrics objects:
$Recorder = $GLOBALS["G_PluginManager"]->GetPlugin("MetricsRecorder");
$Reporter = $GLOBALS["G_PluginManager"]->GetPlugin("MetricsReporter");

if (isset($_GET["US"]) && $_GET["US"]==1)
{
    $Reporter->CacheClear();
    $GLOBALS["AF"]->SetJumpToPage("P_MetricsReporter_CollectionReports");
    return;
}


$Now = time();
$Past = array(
    "Day"   => $Now -       86400,
    "Week"  => $Now -   7 * 86400,
    "Month" => $Now -  30 * 86400,
    "Year"  => $Now - 365 * 86400
);

$StartTime = microtime(TRUE);

#
# Grab weekly, monthly, and yearly view counts:
#

$H_WeeklyViewCountData  = GetViewCountData( $Past["Week"] );
$H_MonthlyViewCountData = GetViewCountData( $Past["Month"] );
$H_YearlyViewCountData  = GetViewCountData( $Past["Year"] );

#
# Grab weekly, monthly, and yearly URL click counts:
#

$Schema = new MetadataSchema();
$H_UrlField = $Schema->GetFieldByMappedName("Url");

if (isset($H_UrlField))
{
    $H_WeeklyClickCountData  = GetClickCountData( $Past["Week"],  $H_UrlField );
    $H_MonthlyClickCountData = GetClickCountData( $Past["Month"], $H_UrlField );
    $H_YearlyClickCountData  = GetClickCountData( $Past["Year"],  $H_UrlField );
}

#
# Plot total resources vs time
#
$TotalResourceCountData = array();
foreach ( $Recorder->GetSampleData(MetricsRecorder::ST_RESOURCECOUNT ) as
          $SampleDate => $SampleValue )
    $TotalResourceCountData[ strtotime( $SampleDate) ] = array( $SampleValue );
ksort( $TotalResourceCountData );

$H_ResourceCountGraph = new Graph(Graph::TYPE_DATE, $TotalResourceCountData );
$H_ResourceCountGraph->XLabel("Date");
$H_ResourceCountGraph->YLabel( "Total Resources");

#
# Plot newly created resources per day
#
$NewResourceCountData = array();

$Prev = NULL;
foreach ($TotalResourceCountData as $TS => $Count)
{
    if ($Prev !== NULL)
    {
        $NewResourceCountData[ $TS ] = array( max(0, $Count[0] - $Prev) );
    }
    $Prev = $Count[0];
}

$H_NewResourceGraph = new Graph(Graph::TYPE_DATE_BAR, $NewResourceCountData );
$H_NewResourceGraph->XLabel("Date");
$H_NewResourceGraph->YLabel("New Resources");

#
# Plot URL clicks per day:
#
$UrlClickData = $Reporter->CacheGet("UrlClickData");
if (is_null($UrlClickData))
{
    $UrlClickData = array();
    foreach( $Recorder->GetEventCounts(
                 "MetricsRecorder", MetricsRecorder::ET_URLFIELDCLICK, "DAY",
                 NULL, NULL, NULL, NULL, NULL,
                 $Reporter->ConfigSetting("PrivsToExcludeFromCounts") ) as $TS => $Count )
    {
        if (!isset($UrlClickData[$TS]))
        {
            $UrlClickData[$TS] = array($Count);
        }
        else
        {
            $UrlClickData[$TS][0] += $Count ;
        }
    }
    $Reporter->CachePut("UrlClickData", $UrlClickData);
}

$H_UrlClickGraph = new Graph(Graph::TYPE_DATE_BAR, $UrlClickData );
$H_UrlClickGraph->XLabel("Date");
$H_UrlClickGraph->YLabel("Resource URL Clicks");

#
# Determine top searches and plot searches/day
#

$Data = $Reporter->CacheGet("SearchData");
if (is_null($Data))
{
    $UserCache = array();

    $H_SearchDataDayPriv = array();
    $H_SearchDataDayUnpriv = array();

    $H_SearchDataWeekPriv = array();
    $H_SearchDataWeekUnpriv = array();

    $H_SearchDataMonthPriv = array();
    $H_SearchDataMonthUnpriv = array();

    $AllSearches = $Recorder->GetEventData(
        "MetricsRecorder", MetricsRecorder::ET_SEARCH,  date('Y-m-d', $Past["Month"]) );
    $AllSearches += $Recorder->GetEventData(
        "MetricsRecorder", MetricsRecorder::ET_ADVANCEDSEARCH,  date('Y-m-d',$Past["Month"]) );

    foreach ($AllSearches as $Row)
    {
        # If there was a search string recorded
        #  (Note that the Metrics Data is sometimes missing a search string,
        #   and the cause for that has not yet been determined..)
        if (strlen($Row["DataOne"]))
        {
            # If we had a logged in user:
            if (strlen($Row["UserId"]))
            {
                # Determine if we've already checked their permissions against the
                #  list of exclusions from the Metrics Reporter.
                if (!isset($UserCache[$Row["UserId"]]))
                {
                    # If we haven't check their perms and cache the result:
                    $ThisUser = new CWUser($Row["UserId"]);

                    $UserCache[$Row["UserId"]] = call_user_func_array(
                        array($ThisUser, "HasPriv"),
                            $Reporter->ConfigSetting("PrivsToExcludeFromCounts") );
                }

                # Pull cached perms data out:
                $Privileged = $UserCache[$Row["UserId"]];
            }
            else
            {
                 # If there was no user logged in, count them as non-priv:
                $Privileged = FALSE;
            }

            $TS = strtotime( $Row["EventDate"] );

            if ($Privileged)
            {
                if ($Past["Month"] < $TS)
                    CreateOrIncrement( $H_SearchDataMonthPriv, $Row["DataOne"]);
                if ($Past["Week"] < $TS)
                    CreateOrIncrement( $H_SearchDataWeekPriv, $Row["DataOne"]);
                if ($Past["Day"] < $TS)
                    CreateOrIncrement( $H_SearchDataDayPriv, $Row["DataOne"]);
            }
            else
            {
                if ($Past["Month"] < $TS)
                    CreateOrIncrement( $H_SearchDataMonthUnpriv, $Row["DataOne"]);
                if ($Past["Week"] < $TS)
                    CreateOrIncrement( $H_SearchDataWeekUnpriv, $Row["DataOne"]);
                if ($Past["Day"] < $TS)
                    CreateOrIncrement( $H_SearchDataDayUnpriv, $Row["DataOne"]);
            }
        }
    }

    # Sort the data in descending order:
    arsort($H_SearchDataDayPriv);
    arsort($H_SearchDataDayUnpriv);
    arsort($H_SearchDataWeekPriv);
    arsort($H_SearchDataWeekUnpriv);
    arsort($H_SearchDataMonthPriv);
    arsort($H_SearchDataMonthUnpriv);

    $Reporter->CachePut("SearchData", array(
                              "H_SearchDataDayPriv" => $H_SearchDataDayPriv,
                              "H_SearchDataDayUnpriv" => $H_SearchDataDayUnpriv,
                              "H_SearchDataWeekPriv" => $H_SearchDataWeekPriv,
                              "H_SearchDataWeekUnpriv" => $H_SearchDataWeekUnpriv,
                              "H_SearchDataMonthPriv" => $H_SearchDataMonthPriv,
                              "H_SearchDataMonthUnpriv" => $H_SearchDataMonthUnpriv) );
}
else
{
    $H_SearchDataDayPriv = $Data["H_SearchDataDayPriv"];
    $H_SearchDataDayUnpriv = $Data["H_SearchDataDayUnpriv"];
    $H_SearchDataWeekPriv = $Data["H_SearchDataWeekPriv"];
    $H_SearchDataWeekUnpriv = $Data["H_SearchDataWeekUnpriv"];
    $H_SearchDataMonthPriv = $Data["H_SearchDataMonthPriv"];
    $H_SearchDataMonthUnpriv = $Data["H_SearchDataMonthUnpriv"];
}


$SearchDataByDay = $Reporter->CacheGet("SearchDataByDay");
if (is_null($SearchDataByDay))
{
    # Pull out totals for regular + advanced searches:
    $AllSearches = $Recorder->GetEventCounts(
        "MetricsRecorder",
        array(MetricsRecorder::ET_SEARCH, MetricsRecorder::ET_ADVANCEDSEARCH),
        "DAY" );

    # Pull out the searches by unprivileged users:
    $UnprivSearches = $Recorder->GetEventCounts(
        "MetricsRecorder",
        array(MetricsRecorder::ET_SEARCH, MetricsRecorder::ET_ADVANCEDSEARCH),
        "DAY",
        NULL, NULL, NULL,
        NULL, NULL,
        $Reporter->ConfigSetting("PrivsToExcludeFromCounts") );

    # Massage the data into the format that the Graph object wants:
    $SearchDataByDay = array();
    foreach ($AllSearches as $TS => $Count ){
        $ThisUnpriv = array_key_exists( $TS, $UnprivSearches) ?
            $UnprivSearches[$TS] : 0 ;

        $SearchDataByDay [ $TS ] =
            array( $ThisUnpriv, $Count - $ThisUnpriv );
    }

    $Reporter->CachePut("SearchDataByDay", $SearchDataByDay);
}

# Graph the searches per day:
$H_SearchGraph = new Graph(Graph::TYPE_DATE_BAR, $SearchDataByDay);
$H_SearchGraph->XLabel("Date");
$H_SearchGraph->YLabel("Searches");
$H_SearchGraph->Legend( array("Unprivileged","Privileged") );

#
# Generate a plot of OAI data
#

$OaiDataByDay = $Reporter->CacheGet("OaiDataByDay");
if (is_null($OaiDataByDay))
{

    $OaiDataByDay = array();
    foreach ($Recorder->GetEventData(
                 "MetricsRecorder", MetricsRecorder::ET_OAIREQUEST) as $Row)
    {
        $TS = strtotime( date( 'Y-m-d', strtotime($Row["EventDate"])));

        if (!isset($OaiDataByDay[$TS]))
            $OaiDataByDay[$TS] = array(1);
        else
            $OaiDataByDay[$TS][0]++;
    }

    $Reporter->CachePut("OaiDataByDay", $OaiDataByDay);
}

$H_OaiRequestGraph = new Graph(Graph::TYPE_DATE_BAR, $OaiDataByDay);
$H_OaiRequestGraph->XLabel("Date");
$H_OaiRequestGraph->YLabel("OAI Requests");
$H_OaiRequestGraph->Scale(Graph::WEEKLY);

#
# Resource shares
#
$Data = $Reporter->CacheGet("Shares");

# we must have access to the SocialMedia plugin to gather sharing data
if (is_null($Data) && $GLOBALS["G_PluginManager"]->PluginEnabled("SocialMedia"))
{
    $RFactory = new ResourceFactory();

    $ResourceIds = array();
    foreach ($RFactory->GetItemIds() as $ResourceId)
        $ResourceIds[ $ResourceId ] = 1;

    $SharesData = array();
    $H_ShareData = array(
        "Week" => array(),
        "Month" => array(),
        "Year" => array() );

    $ShareTypeMap = array(
        SocialMedia::SITE_EMAIL => 0,
        SocialMedia::SITE_FACEBOOK => 1,
        SocialMedia::SITE_TWITTER => 2,
        SocialMedia::SITE_LINKEDIN => 3,
        SocialMedia::SITE_GOOGLEPLUS => 4
        );

    foreach ($Recorder->GetEventData(
                 "SocialMedia", "ShareResource",
                 NULL, NULL, NULL,
                 NULL, NULL, $Reporter->ConfigSetting("PrivsToExcludeFromCounts") ) as $Event)
    {
        # Skip non-event shares:
        if (!isset($ResourceIds[ $Event["DataOne"] ] ))
            continue;

        $TS =  strtotime($Event["EventDate"]);

        $SharesData[$TS] = array(0, 0, 0, 0, 0);
        $SharesData[$TS][ $ShareTypeMap[$Event["DataTwo"] ] ] = 1;

        foreach (array("Week","Month","Year") as $Period)
        {
            if ($Past[$Period] < $TS)
                CreateOrIncrement( $H_ShareData[$Period], $Event["DataOne"]);
        }

    }

    $Reporter->CachePut(
        "Shares",
        array(
            "SharesData" => $SharesData,
            "H_ShareData" => $H_ShareData ) );
}
else
{
    $SharesData = $Data["SharesData"];
    $H_ShareData = $Data["H_ShareData"];
}

# only use share data if the we have it
if (isset($SharesData) && isset($H_ShareData))
{
    $H_SharesPerDay = new Graph(Graph::TYPE_DATE_BAR, $SharesData );
    $H_SharesPerDay->XLabel("Date");
    $H_SharesPerDay->YLabel("Resource Shares");
    $H_SharesPerDay->Legend( array("Email", "Facebook", "Twitter", "LinkedIn", "GooglePlus") );
    $H_SharesPerDay->Scale(Graph::WEEKLY);
}
