<?php /* ----------------------------------------------------------------------------------- This module contains two merge functions, one for date and one for country arrays plus ancillary functions. (c) Copyright 2004 Arthur Sale, University of Tasmania ----------------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------------ This function computes an integer datestamp to a month resolution. (c) Copyright 2004 Arthur Sale, University of Tasmania Parameters: An array and an index into it Returns: Result: the datestamp ------------------------------------------------------------------------------ */ function datestamp(&$x, $j) // reference parameter for efficiency, not changed // invalid dates return zero, ie earlier than any possible date. { if ($j < count($x)) { // $mo is in {0..11} $mo = (int) strpos('JanFebMarAprMayJunJulAugSepOctNovDec', $x[$j]["month"])/3; return (int) $x[$j]["year"]*12 + $mo; } else { return 0; } } /* ------------------------------------------------------------------------------ This function merges two date arrays, to produce a single consolidated array. Note that either of the two arrays might be missing a view for a month or more. Precondition: both arrays are ordered in descending order of date (latest first) as is the result array. (c) Copyright 2004 Arthur Sale, University of Tasmania Parameters: Two date-ordered arrays: abstracts and downloads Returns: Result: merged array also ordered by date NJS 2006-01-18: Added count of distinct countries. ------------------------------------------------------------------------------ */ function merge_dates(&$aa, &$ad) // reference parameters for efficiency, not changed { $merged = array(); // start of all arrays $i = 0; $indexa = 0; $indexd = 0; // set up the rest of the loop invariant $datea = datestamp($aa,0); $dated = datestamp($ad,0); // $datei is initialized to the most recent date for which an access is recorded $datei = max($datea, $dated); while (($datea + $dated) != 0) { // Loop invariant: All elements prior to $indexa in $aa and $indexd in $ad // have been transferred to $merged (ie all dates *after* $datei) // Progress: $date1 is decremented by 1 (ie one month *earlier*) // Termination: No more elements, signalled by both datestamps == 0. if (($datea == $datei) and ($dated == $datei)) { // Both are valid and equal to the current date being displayed, the majority case $merged[$i] = array( "downloads" => $ad[$indexd]["count"], "dcountries" => $ad[$indexd]["countries"], "abstracts" => $aa[$indexa]["count"], "acountries" => $aa[$indexa]["countries"], "month" => $ad[$indexd]["month"], // same value as aa "year" => $ad[$indexd]["year"] // same value as aa ); $indexa++; $indexd++; $datea = datestamp($aa,$indexa); $dated = datestamp($ad,$indexd); } elseif ($datea == $datei) { // aa (but not ad) is equal to the current date being displayed $merged[$i] = array( "downloads" => 0, "dcountries" => 0, "abstracts" => $aa[$indexa]["count"], "acountries" => $aa[$indexa]["countries"], "month" => $aa[$indexa]["month"], "year" => $aa[$indexa]["year"] ); $indexa++; $datea = datestamp($aa,$indexa); } elseif ($dated == $datei) { // ad (but not aa) is equal to the current date being displayed $merged[$i] = array( "downloads" => $ad[$indexd]["count"], "dcountries" => $ad[$indexd]["countries"], "abstracts" => 0, "acountries" => 0, "month" => $ad[$indexd]["month"], "year" => $ad[$indexd]["year"] ); $indexd++; $dated = datestamp($ad,$indexd); } else { // Neither aa nor ad are equal to the current date being displayed // So generate an empty record $monthname = array('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'); $merged[$i] = array( "downloads" => 0, "dcountries" => 0, "abstracts" => 0, "acountries" => 0, "month" => $monthname[$datei % 12], // NJS 2006-06-14 BUG FIX: added () around the expression // to ensure that the (int) is applied to the whole thing. // We were getting fractional years in the output :( "year" => (int) ( $datei / 12 ) ); } // Progress: one more entry in $merged, and date earlier by one month $i++; $datei--; } return $merged; } /* ------------------------------------------------------------------------------ This function merges two country arrays, to produce a single consolidated array. Note that either of the two arrays might be missing a country in the other. (c) Copyright 2004 Arthur Sale, University of Tasmania Precondition: both arrays are ordered in descending order of views. Postcondition: result array contains records for every country in $aa and $ad, and is ordered in descending order of download views. ------------------------------------------------------------------------------ */ function merge_countries($aa, &$ad) // reference parameter $ad for efficiency, not changed, // however the $aa value parameter is altered and is not prapogated back { $merged = array(); // Copy acrosss the download array, adding counts from the abstract array as needed. for ($i=0; $i<count($ad); $i++) { $merged[$i] = array( "country_code" => $ad[$i]["country_code"], "country_name" => $ad[$i]["country_name"], "country_downloads" => $ad[$i]["count"], "country_abstracts" => 0 ); $c_code = $merged[$i]["country_code"]; for ($j=0; $j<count($aa); $j++) { if ($c_code == $aa[$j]["country_code"]) { // matching country in abstracts $merged[$i]["country_abstracts"] = $aa[$j]["count"]; // render this entry dead in future with reserved country code $aa[$j]["country_code"] = '=='; // and get out of the loop break; } } // for on $j } // for on $i // Copy what is left of the abstract array $i = count($merged); for ($j=0; $j<count($aa); $j++) { if ($aa[$j]["country_code"] != '==') { // country with only abstract views, so copy $merged[$i] = array( "country_code" => $aa[$j]["country_code"], "country_name" => $aa[$j]["country_name"], "country_downloads" => 0, "country_abstracts" => $aa[$j]["count"] ); // and increment $i $i++; } } // for on $j return $merged; } ?>