"Fossies" - the Fresh Open Source Software Archive

Member "betterawstats/core/data.inc.php" (18 Mar 2008, 13382 Bytes) of package /linux/www/old/betterawstats-1.0.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) PHP source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 <?php
    2 /**
    3  * betterawstats, an alternative display for awstats data
    4  *
    5  * @author      Oliver Spiesshofer, support at betterawstats dot com
    6  * @copyright   2008 Oliver Spiesshofer
    7  * @version     1.0
    8  * @link        http://betterawstats.com
    9 
   10  * Based on the GPL AWStats Totals script by:
   11  * Jeroen de Jong <jeroen@telartis.nl>
   12  * copyright   2004-2006 Telartis
   13  * version 1.13 (http://www.telartis.nl/xcms/awstats)
   14  *
   15  * This program is free software; you can redistribute it and/or
   16  * modify it under the terms of the GNU General Public License
   17  * as published by the Free Software Foundation; either version 2
   18  * of the License, or (at your option) any later version.
   19  *
   20  * This program is distributed in the hope that it will be useful,
   21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   23  * GNU General Public License for more details.
   24  *
   25  * You should have received a copy of the GNU General Public License
   26  * along with this program; if not, write to the Free Software
   27  * Foundation, Inc., 59 Temple Place','Suite 330, Boston, MA  02111-1307, USA.
   28  */
   29 
   30 /**
   31  * File contents:
   32  *
   33  * This file contains functions that read data from files process it and store it
   34  * in an array. This concerns library-data as well as stats-data. Language files
   35  * are NOT processed here.
   36  */
   37 
   38 
   39 // this file can't be used on its own
   40 if (strpos ($_SERVER['PHP_SELF'], 'data.inc.php') !== false) {
   41     die ('This file can not be used on its own!');
   42 }
   43 
   44 /**
   45 * Data function: read the data directories this function is called by
   46 * baw_match_files() and itself recursively
   47 *
   48 * @param    str     $dir  directory
   49 * @return   arr     ALL files found in that directory
   50 *
   51 */
   52 function baw_parse_dir($dir = false) {
   53     global $BAW_CONF;
   54     if ($dir == false) {
   55        $dir = $BAW_CONF['path_data'];
   56     }
   57     if (!file_exists($dir)) {
   58         echo baw_raise_error('datafilesdir', array($dir));
   59         return array();
   60     }
   61     // add trailing slash if not exists
   62     if (substr($dir, -1) != '/') {
   63         $dir .= '/';
   64     }
   65     baw_debug('dbg_start_parse_dir', $dir);
   66     $files = array();
   67     if ($dh = @opendir($dir)) {
   68         while (($file = readdir($dh)) !== false) {
   69             if (!preg_match('/^\./s', $file)) {
   70                 if (is_dir($dir.$file)) {
   71                     $newdir = $dir.$file.'/';
   72                     $files = array_merge($files, baw_parse_dir($newdir));
   73                     baw_debug('dbg_found_dir', $dir);
   74                 } else {
   75                     $files[] = $dir.$file;
   76                     baw_debug('dbg_found_file', $file);
   77                 }
   78             }
   79         }
   80         closedir($dh);
   81     }
   82     baw_debug('dbg_finished_parse_dir', $dir);
   83     return $files;
   84 }
   85 
   86 /*
   87 * Data function: find all files that contain the data for the current month and
   88 * 12 month before now to write a rolling month data chart. This function is called
   89 * by index.php
   90 *
   91 * fills the gl. arrays: $BAW_CURR['years'], $BAW_CURR['months'], $BAW_DFILES
   92 *
   93 */
   94 function baw_match_files() {
   95     global $BAW_CURR, $BAW_CONF, $BAW_CONF_DIS, $BAW_MES, $BAW_DFILES, $BAW_SERVERS;
   96     // read all the files in the directory
   97     $dirfiles = baw_parse_dir();
   98     $pat_others = '/awstats(\d{6})\.((.+))\.txt$/';
   99     // go through all files and find matching ones
  100     $year_array = array();
  101     $month_array = array();
  102     foreach ($dirfiles as $file) {
  103         $filename = explode("/", $file);
  104         $filename = $filename[count($filename)-1];
  105         if (preg_match($pat_others, $file, $match)) {
  106             $month = substr($filename, 7, 2);
  107             $year = substr($filename, 9, 4);
  108             $year_array[$year] = $year;
  109             $month_array[$month] = $BAW_MES[$month + 59];
  110             // future feature where the admin can tell which sites to read/ exclude
  111             // if (!$BAW_CONF['filter_configs'] || in_array($site, $BAW_CONF['filter_configs'])) {
  112             $site = $match[2];
  113             $BAW_DFILES[$site][$year.$month] = array(
  114                 'file' => $file,
  115                 'map' => null
  116             );
  117             // add the sites to another array since we need that for the config editor
  118             $BAW_SERVERS[$site] = $site;
  119             baw_debug("site found for month $month and year $year: $file, SITE: {$site}");
  120         }
  121     }
  122     if (count($year_array)>0) {
  123         $year_array = array_unique($year_array);
  124         ksort($year_array);
  125     }
  126     if (count($month_array)>0) {
  127         ksort($month_array);
  128         $month_array = array_unique($month_array);
  129     }
  130     $BAW_CURR['years'] = $year_array;
  131     $BAW_CURR['months'] = $month_array;
  132     // since we added sites with each file, remove duplicates
  133     ksort($BAW_DFILES);
  134     ksort($BAW_SERVERS);
  135     $BAW_SERVERS = array('show_all' => $BAW_MES['cfg_show_all']) + $BAW_SERVERS;
  136     if (!isset($BAW_CURR['site_name'])) {
  137         $BAW_CURR['site_name'] = key($BAW_DFILES); // we dont have a selected, take first in line
  138         reset($BAW_DFILES);
  139     }
  140 }
  141 
  142 /*
  143 * Data function: calculate the month-data by summing up days and retrieving
  144 * single-value data. This function is called by different display-functions
  145 *
  146 * @param    arr     $t  TIME data array of the current file
  147 * @param    arr     $g  GENERAL data array of the current file
  148 * @return   arr     summed dataset for processing
  149 *
  150 */
  151 function baw_calc_monthdata($t, $g) {
  152     baw_debug("Calculating Month-data");
  153     $pages = 0;
  154     $hits = 0;
  155     $bandwidth = 0;
  156     $not_viewed_pages = 0;
  157     $not_viewed_hits = 0;
  158     $not_viewed_bandwidth = 0;
  159     $num_t = count($t);
  160     for ($i=0; $i<$num_t; $i++) {
  161         $pages += $t[$i][0];
  162         $hits += $t[$i][1];
  163         $bandwidth += $t[$i][2];
  164         $not_viewed_pages += $t[$i][3];
  165         $not_viewed_hits += $t[$i][4];
  166         $not_viewed_bandwidth += $t[$i][5];
  167     }
  168     $result = array(
  169         $g['TotalUnique'][0],
  170         $g['TotalVisits'][0],
  171         $pages,
  172         $hits,
  173         $bandwidth,
  174         $not_viewed_pages,
  175         $not_viewed_hits,
  176         $not_viewed_bandwidth
  177     );
  178     return $result;
  179 }
  180 
  181 /*
  182 * Data Function: read data from awstats library files (perl format)
  183 * Opens a file, reads the contents and does corrections and makes PHP out of PERL
  184 * This function is called by the file library.inc.php
  185 *
  186 * @param    str     $file    path to the library file
  187 * @param    str     $data    the name of the array in the file
  188 * @return   arr     summed dataset for processing
  189 *
  190 */
  191 function baw_get_library($file, $data) {
  192     global $BAW_CONF, $BAW_LOGTYPE;
  193     $file = $BAW_CONF['path_lib'] . $file;
  194     baw_debug("Trying to read library data ($data) from file: $file");
  195     if (!file_exists($file)) {
  196         echo baw_raise_error('libraryfiles', array($file));
  197         exit;
  198     }
  199     // read the whole file in one go
  200     $file_text = file_get_contents($file);
  201     // these are to attempt to convert the perl data file to PHP
  202 
  203     $search = array(
  204         "\$LogType eq 'S'",
  205         "= ", // remove spaces between = and (
  206         "@",
  207         "%",
  208         "'=>'",
  209         "=(",
  210         "=\n(",
  211         "=\r(",
  212         "=\r\n(",
  213         ",,",
  214         ' target="_blank"',
  215         ' [new window]',
  216         '<a href="',
  217         '&',
  218         '/" Searc',
  219     );
  220     $replace  = array(
  221         "\$LogType = 'S'",
  222         "=",
  223         "$",
  224         "$",
  225         "', '",
  226         "= array(",
  227         "= array(",
  228         "= array(",
  229         "= array(",
  230         ",",
  231         " ",
  232         " ",
  233         '<a class="ext_link" href="',
  234         '&amp;',
  235         '/" title="Searc'
  236     );
  237     $file_text = str_replace($search, $replace, $file_text);
  238 
  239     $check = eval($file_text);
  240     // check if we have an error with the conversion
  241     if ($check === false) {
  242         echo baw_raise_error('libraryeval', array($file, $data));
  243     }
  244     if (is_array($data)) {
  245         $a = 0;
  246         foreach($data as $arr_name) {
  247             $countpairs = count($$arr_name);
  248             $parr = $$arr_name;
  249             for ($i=0; $i<$countpairs; $i=$i+2) {
  250                 $new_arr[$a][$parr[$i]] = $parr[$i+1];
  251             }
  252             $a++;
  253         }
  254     } else {
  255         $countpairs = count($$data);
  256         $parr = $$data;
  257         for ($i=0; $i<$countpairs; $i=$i+2) {
  258             $new_arr[$parr[$i]] = $parr[$i+1];
  259         }
  260     }
  261     return $new_arr;
  262 }
  263 
  264 /*
  265 * Data Function: read data from awstats data file. Identifies the file to read,
  266 * locates the data-map, reads the data. This function is called by every single
  267 * display-function on need for data. Some data might be read twice or more.
  268 *
  269 * @param    str     $site    which site do we read
  270 * @param    str     $data_type    the name of the data-type to read
  271 * @param    str     $date    YYYYMM, date of datafile
  272 * @return   arr     data from file as assoc. array
  273 *
  274 */
  275 function baw_data($site, $data_type, $date) {
  276     global $BAW_CONF, $BAW_LIB, $BAW_CURR, $BAW_DFILES;
  277     $MAP = array();
  278     baw_debug("reading  $site datafile, type $data_type from $date");
  279     // we have to remove the linebreaks otherwise they end up in the data
  280     $brs_arr = array("\n", "\r");
  281     $brr_arr = array("", "");
  282     $dataset = array();
  283     // reduce the dataset to the necessary data
  284     if (!isset($BAW_DFILES[$site][$date])) {
  285         return false;
  286     } else {
  287         $dataset[$date] = $BAW_DFILES[$site][$date];
  288     }
  289 
  290     // iterate each data file
  291     $file = $dataset[$date]['file'];
  292     $f = fopen($file, 'r');
  293     $map = $dataset[$date]['map'];
  294     baw_debug("reading site $site datafile, date $date, file $file");
  295 
  296     // read the map if required
  297     if ($map == null) {
  298         baw_read_filemap($f, $site, $date);
  299         if (!isset($BAW_DFILES[$site][$date]['map'][$data_type])) {
  300             return false;
  301         } else {
  302             $offset = $BAW_DFILES[$site][$date]['map'][$data_type];
  303         }
  304     } else if (isset($map[$data_type])) {
  305         $offset = $map[$data_type];
  306         baw_debug("data map present, reading data $data_type from offset $offset");
  307     } else {
  308         baw_debug("data map present, type $data_type not existant in map!");
  309         return false;
  310     }
  311     $filedata = array();
  312 
  313     fseek($f , $offset, SEEK_SET);
  314     $check = 1;
  315     while ($check !== 0) {
  316         baw_debug("reading aditional line to find data...");
  317         $firstline = fgets($f, 20000);
  318         $check = strpos($firstline,"BEGIN_$data_type");
  319     }
  320 
  321     if ($check !== 0) {
  322         $err_data = array($file, $firstline);
  323         echo baw_raise_error('datafile', $err_data);
  324         exit;
  325     }
  326     $index = explode(' ', $firstline);
  327     $lines_count = $index[1];
  328     baw_debug("Data $data_type found at offset ". ftell($f) . " instead of $offset (" . (ftell($f) - $offset) . " diff), is $lines_count lines long, reading now:");
  329     for ($i=0; $i<$lines_count;$i++) {
  330         baw_debug("reading Line $data_type $i");
  331         $str = fgets($f, 20000);
  332         if (substr($str,0,4) == 'END_') { // this is a security check since sometimes we are off
  333             continue;
  334         }
  335         // remove linebreaks from string
  336         $str = str_replace($brs_arr,$brr_arr, $str);
  337         $line_arr = explode(' ', $str);
  338         // shift first element as array name
  339         $first_element = array_shift($line_arr);
  340         // check if one dataset has occurred twice and would
  341         // overwrite another. SIDER and PAGEREF had this issue for sure.
  342         if (!isset($filedata[$first_element])) {
  343             $filedata[$first_element] = $line_arr;
  344         } else {
  345             foreach ($line_arr as $no => $line_item) {
  346                 if (is_numeric($line_item)) {
  347                     // this could cause trouble in case this was a date, percentage etc.
  348                     $filedata[$first_element][$no] += $line_item;
  349                 }
  350             }
  351         }
  352     }
  353     fclose($f);
  354     baw_debug("data read, file closed");
  355     return $filedata;
  356 }
  357 
  358 /*
  359 * Data Function: read the filemap at the begginning of a data file. This function
  360 * is called only by baw_data if the data was not read before.
  361 *
  362 * @param    obj     &$f    file-handler to read
  363 * @param    str     $site    the concerned site
  364 * @param    str     $date    YYYYMM, date of datafile
  365 * adds the data to gl. array $BAW_DFILES
  366 *
  367 */
  368 function baw_read_filemap(&$f, $site, $date) {
  369     global $BAW_DFILES;
  370     // $f = fopen($file, 'r');
  371     $str ='';
  372     $check = 1;
  373     // read this file until we hit the offsets
  374     while ($check !== 0) {
  375         $str = fgets($f, 20000);
  376         // check for XML Data
  377         if (strstr($str, '<xml') !== false) { // we have XML
  378             echo baw_raise_error('xmldata');
  379             exit;
  380         }
  381         $check = strpos($str, 'BEGIN_MAP');
  382     }
  383     $check = explode(' ', $str);
  384     $lines_count = $check[1]; // line length of the map
  385     baw_debug("found data map for file, has $lines_count lines");
  386     // now read x more lines
  387     for ($i=0; $i<$lines_count;$i++) { // read the complete offset map
  388         $str = fgets($f, 512);
  389         // split the info in string - byte offset
  390         $check = explode(' ', $str);
  391         $type = substr($check[0], 4);
  392         $offset = $check[1];
  393         if ($offset > 1) {
  394             baw_debug("data type $type, starts at offset $offset");
  395             $BAW_DFILES[$site][$date]['map'][$type] = $offset;
  396         } else {
  397             echo baw_raise_error('datafileindex', $err_data);
  398             exit;
  399         }
  400     }
  401     baw_debug("map read");
  402 }
  403 ?>