Reupload after bitbucket wipe

This commit is contained in:
Chris Lynch
2013-12-25 18:43:29 -05:00
commit 965453909e
5942 changed files with 99045 additions and 0 deletions

296
web/includes/class_db.php Normal file
View File

@ -0,0 +1,296 @@
<?php
/*
HLstatsX Community Edition - Real-time player and clan rankings and statistics
Copyleft (L) 2008-20XX Nicholas Hastings (nshastings@gmail.com)
http://www.hlxcommunity.com
HLstatsX Community Edition is a continuation of
ELstatsNEO - Real-time player and clan rankings and statistics
Copyleft (L) 2008-20XX Malte Bayer (steam@neo-soft.org)
http://ovrsized.neo-soft.org/
ELstatsNEO is an very improved & enhanced - so called Ultra-Humongus Edition of HLstatsX
HLstatsX - Real-time player and clan rankings and statistics for Half-Life 2
http://www.hlstatsx.com/
Copyright (C) 2005-2007 Tobias Oetzel (Tobi@hlstatsx.com)
HLstatsX is an enhanced version of HLstats made by Simon Garner
HLstats - Real-time player and clan rankings and statistics for Half-Life
http://sourceforge.net/projects/hlstats/
Copyright (C) 2001 Simon Garner
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
For support and installation notes visit http://www.hlxcommunity.com
*/
/* Profile support:
To see SQL run counts and run times, set the $profile variable below to something
that evaluates as true.
Add the following table to your database:
CREATE TABLE IF NOT EXISTS `hlstats_sql_web_profile` (
`queryid` int(11) NOT NULL AUTO_INCREMENT,
`source` tinytext NOT NULL,
`run_count` int(11) NOT NULL,
`run_time` float NOT NULL,
PRIMARY KEY (`queryid`),
UNIQUE KEY `source` (`source`(64))
) ENGINE=MyISAM;
*/
if ( !defined('IN_HLSTATS') ) { die('Do not access this file directly.'); }
class DB_mysql
{
var $db_addr;
var $db_user;
var $db_pass;
var $db_name;
var $link;
var $last_result;
var $last_query;
var $last_insert_id;
var $profile = 0;
var $querycount = 0;
var $last_calc_rows = 0;
function DB_mysql($db_addr, $db_user, $db_pass, $db_name, $use_pconnect = false)
{
$this->db_addr = $db_addr;
$this->db_user = $db_user;
$this->db_pass = $db_pass;
$this->querycount = 0;
if ( $use_pconnect )
{
$this->link = @mysql_pconnect($db_addr, $db_user, $db_pass);
}
else
{
$this->link = @mysql_connect($db_addr, $db_user, $db_pass);
}
if ( $this->link )
{
$q = @mysql_query("SET NAMES 'utf8'", $this->link);
@mysql_free_result($q);
if ( $db_name != '' )
{
$this->db_name = $db_name;
if ( !@mysql_select_db($db_name, $this->link) )
{
@mysql_close($this->db_connect_id);
$this->error("Could not select database '$db_name'. Check that the value of DB_NAME in config.php is set correctly.");
}
}
return $this->link;
}
else
{
$this->error('Could not connect to database server. Check that the values of DB_ADDR, DB_USER and DB_PASS in config.php are set correctly.');
}
}
function data_seek($row_number, $query_id = 0)
{
if ( !$query_id )
{
$result = $this->last_result;
}
if ( $query_id )
{
return @mysql_data_seek($query_id, $row_number);
}
return false;
}
function fetch_array($query_id = 0)
{
if ( !$query_id )
{
$query_id = $this->last_result;
}
if ( $query_id )
{
return @mysql_fetch_array($query_id);
}
return false;
}
function fetch_row($query_id = 0)
{
if ( !$query_id )
{
$query_id = $this->last_result;
}
if ( $query_id )
{
return @mysql_fetch_row($query_id);
}
return false;
}
function fetch_row_set($query_id = 0)
{
if ( !$query_id )
{
$query_id = $this->last_result;
}
if ( $query_id )
{
$rowset = array();
while ( $row = $this->fetch_array($query_id) )
$rowset[] = $row;
return $rowset;
}
return false;
}
function free_result($query_id = 0)
{
if ( !$query_id )
{
$query_id = $this->last_result;
}
if ( $query_id )
{
return @mysql_free_result($query_id);
}
return false;
}
function insert_id()
{
return $this->last_insert_id;
}
function num_rows($query_id = 0)
{
if ( !$query_id )
{
$query_id = $this->last_result;
}
if ( $query_id )
{
return @mysql_num_rows($query_id);
}
return false;
}
function calc_rows()
{
return $this->last_calc_rows;
}
function query($query, $showerror=true, $calcrows=false)
{
$this->last_query = $query;
$starttime = microtime(true);
if($calcrows == true)
{
/* Add sql_calc_found_rows to this query */
$query = preg_replace('/select/i', 'select sql_calc_found_rows', $query, 1);
}
$this->last_result = @mysql_query($query, $this->link);
$endtime = microtime(true);
$this->last_insert_id = @mysql_insert_id($this->link);
if($calcrows == true)
{
$calc_result = @mysql_query("select found_rows() as rowcount");
if($row = mysql_fetch_assoc($calc_result))
{
$this->last_calc_rows = $row['rowcount'];
}
}
$this->querycount++;
if ( defined('DB_DEBUG') && DB_DEBUG == true )
{
echo "<p><pre>$query</pre><hr /></p>";
}
if ( $this->last_result )
{
if($this->profile)
{
$backtrace = debug_backtrace();
$profilequery = "insert into hlstats_sql_web_profile (source, run_count, run_time) values ".
"('".basename($backtrace[0]['file']).':'.$backtrace[0]['line']."',1,'".($endtime-$starttime)."')"
."ON DUPLICATE KEY UPDATE run_count = run_count+1, run_time=run_time+".($endtime-$starttime);
@mysql_query($profilequery, $this->link);
}
return $this->last_result;
}
else
{
if ($showerror)
{
$this->error('Bad query.');
}
else
{
return false;
}
}
}
function result($row, $field, $query_id = 0)
{
if ( !$query_id )
{
$query_id = $this->last_result;
}
if ( $query_id )
{
return @mysql_result($query_id, $row, $field);
}
return false;
}
function escape($string)
{
if ( $this->link )
{
return @mysql_real_escape_string($string, $this->link);
}
else
{
return @mysql_real_escape_string($string);
}
}
function error($message, $exit=true)
{
error(
"<b>Database Error</b><br />\n<br />\n" .
"<i>Server Address:</i> $this->db_addr<br />\n" .
"<i>Server Username:</i> $this->db_user<br /><br />\n" .
"<i>Error Diagnostic:</i><br />\n$message<br /><br />\n" .
"<i>Server Error:</i> (" . @mysql_errno() . ") " . @mysql_error() . "<br /><br />\n" .
"<i>Last SQL Query:</i><br />\n<pre style=\"font-size:2px;\">$this->last_query</pre>",
$exit
);
}
}
?>

View File

@ -0,0 +1,559 @@
<?php
/*
HLstatsX Community Edition - Real-time player and clan rankings and statistics
Copyleft (L) 2008-20XX Nicholas Hastings (nshastings@gmail.com)
http://www.hlxcommunity.com
HLstatsX Community Edition is a continuation of
ELstatsNEO - Real-time player and clan rankings and statistics
Copyleft (L) 2008-20XX Malte Bayer (steam@neo-soft.org)
http://ovrsized.neo-soft.org/
ELstatsNEO is an very improved & enhanced - so called Ultra-Humongus Edition of HLstatsX
HLstatsX - Real-time player and clan rankings and statistics for Half-Life 2
http://www.hlstatsx.com/
Copyright (C) 2005-2007 Tobias Oetzel (Tobi@hlstatsx.com)
HLstatsX is an enhanced version of HLstats made by Simon Garner
HLstats - Real-time player and clan rankings and statistics for Half-Life
http://sourceforge.net/projects/hlstats/
Copyright (C) 2001 Simon Garner
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
For support and installation notes visit http://www.hlxcommunity.com
* Table
* Generates an HTML table.
*
* @package HLstatsX Community Edition
* @author Nicholas Hastings (nshastings@gmail.com)
* @copyright HLstatsX Community Edition
* @version 2008
* @access public
*/
class Table
{
var $columns;
var $keycol;
var $sort;
var $sortorder;
var $sort2;
var $page;
var $showranking;
var $numperpage;
var $var_page;
var $var_sort;
var $var_sortorder;
var $sorthash;
var $ajax;
var $columnlist;
var $startitem;
var $maxpagenumbers = 20;
function Table ($columns, $keycol, $sort_default, $sort_default2,
$showranking=false, $numperpage=50, $var_page='page',
$var_sort='sort', $var_sortorder='sortorder', $sorthash='',
$sort_default_order='desc', $ajax = false)
{
global $g_options;
$this->columns = $columns;
$this->keycol = $keycol;
$this->showranking = $showranking;
$this->numperpage = $numperpage;
$this->var_page = $var_page;
$this->var_sort = $var_sort;
$this->var_sortorder = $var_sortorder;
$this->sorthash = $sorthash;
$this->sort_default_order = $sort_default_order;
$this->ajax = ( $g_options['playerinfo_tabs'] ) ? $ajax : false;
$this->page = valid_request(intval($_GET[$var_page]), 1);
$this->sort = valid_request($_GET[$var_sort], 0);
$this->sortorder = valid_request($_GET[$var_sortorder], 0);
if ($this->page < 1)
{
$this->page = 1;
}
$this->startitem = ($this->page - 1) * $this->numperpage;
foreach ($columns as $col)
{
if ($col->sort != 'no')
{
$this->columnlist[] = $col->name;
}
}
if (!is_array($this->columnlist) || !in_array($this->sort, $this->columnlist))
{
$this->sort = $sort_default;
}
if ($this->sortorder != 'asc' && $this->sortorder != 'desc')
{
$this->sortorder = $this->sort_default_order;
}
if ($this->sort == $sort_default2)
{
$this->sort2 = $sort_default;
}
else
{
$this->sort2 = $sort_default2;
}
}
function start($numitems, $width=100, $align='center')
{
global $g_options, $game, $realgame, $db;
$numpages = ceil($numitems / $this->numperpage);
?>
<div class="subblock">
<table class="data-table">
<tr class="data-table-head">
<?php
$totalwidth = 0;
if ($this->showranking)
{
$totalwidth += 5;
echo "<td style=\"width:5%;text-align:right;\" class=\"fSmall\">Rank</td>\n";
}
foreach ($this->columns as $col)
{
$totalwidth += $col->width;
echo "<td style=\"width:$col->width%;text-align:$col->align;\" class=\"fSmall\">";
if ($col->sort != 'no')
{
echo getSortArrow($this->sort, $this->sortorder, $col->name,
$col->title, $this->var_sort, $this->var_sortorder,
$this->sorthash);
}
else
{
echo $col->title;
}
echo "</td>\n";
}
?>
</tr>
<?php
if ($totalwidth != 100)
{
error("Warning: Column widths do not add to 100%! (=$totalwidth%)", false);
}
$rank = ($this->page - 1) * $this->numperpage + 1;
}
function draw ($result, $numitems, $width=100, $align='center')
{
global $g_options, $game, $realgame, $db;
$numpages = ceil($numitems / $this->numperpage);
?>
<div class="subblock" style="width:<?php echo $width; ?>%;text-align:<?php echo $align; ?>;">
<table class="data-table">
<tr class="data-table-head">
<?php
$totalwidth = 0;
if ($this->showranking)
{
$totalwidth += 5;
echo "<td style=\"width:5%;text-align=:right;\" class=\"fSmall\">Rank</td>\n";
}
foreach ($this->columns as $col)
{
$totalwidth += $col->width;
echo "<td style=\"width:$col->width%;text-align:$col->align;\" class=\"fSmall\">";
if ($col->sort != 'no')
{
echo getSortArrow($this->sort, $this->sortorder, $col->name,
$col->title, $this->var_sort, $this->var_sortorder,
$this->sorthash, $this->ajax);
}
else
{
echo $col->title;
}
echo "</td>\n";
}
?>
</tr>
<?php
if ($totalwidth != 100)
{
error("Warning: Column widths do not add to 100%! (=$totalwidth%)", false);
}
$rank = ($this->page - 1) * $this->numperpage + 1;
while ($rowdata = $db->fetch_array($result))
{
echo "<tr>\n";
$i = 0;
if ($this->showranking)
{
$c = ($i % 2) + 1;
$i++;
echo "<td style=\"text-align:right;\" class=\"bg$c\">$rank</td>\n";
}
foreach ($this->columns as $col)
{
$c = ($i % 2) + 1;
$class="";
$cellbody = '';
$colval = $rowdata[$col->name];
if ($col->align != 'left')
{
$colalign = " style=\"text-align:$col->align;\"";
}
else
{
$colalign = "";
}
$class = "bg$c";
if (($col->icon) || ($col->flag))
{
$cellbody = '&nbsp;';
}
if ($col->link)
{
if (strpos($col->link, 'javascript:') === false) {
$link = str_ireplace('%k', urlencode($rowdata[$this->keycol]), $col->link);
$cellbody .= "<a href=\"" . $g_options['scripturl'] . "?$link\">";
}
else
{
$col->link = str_replace('\\\\', '', $col->link);
$link = str_ireplace('%k', $rowdata[$this->keycol], $col->link);
$cellbody .= "<a href=\"$link\">";
}
}
if ($col->icon)
{
$image = getImage("/$col->icon");
if ($image)
{
$cellbody .= '<img src="'.$image['url']. "\" class=\"tableicon\" alt=\"$col->icon\" />";
}
}
elseif ($col->flag)
{
#$link = ereg_replace("%f", $col->link);
if ($g_options['countrydata'] == 1) {
if ($rowdata['flag'] == '') {
$rowdata['flag'] = '0';
$alt_text = 'No Country';
} else {
$alt_text = ucfirst(strtolower($rowdata['country']));
}
$cellbody .= '<img src="' . getFlag($rowdata['flag'])."\" class=\"tableicon\" alt=\"$alt_text\" title=\"$alt_text\" />";
}
else
{
$col->flag = 'player';
$cellbody .= '<img src="' . IMAGE_PATH . "/$col->flag.gif\" class=\"tableicon\" alt=\"$col->icon.gif\" />";
}
}
switch ($col->type)
{
case 'timestamp':
$cellbody = timestamp_to_str($colval);
break;
case 'roleimg':
$image = getImage("/games/$game/roles/".strtolower($colval));
// check if image exists for game -- otherwise check realgame
if ($image)
{
$cellbody .= '<img src="' . $image['url'] . '" alt="' . $col->fname[$colval] . '" title="' . $col->fname[$colval] . '" />&nbsp;';
}
elseif ($image = getImage("/games/$realgame/roles/".strtolower($colval)))
{
$cellbody .= '<img src="' . $image['url'] . '" alt="' . $col->fname[$colval] . '" title="' . $col->fname[$colval] . '" />&nbsp;';
}
if ($col->fname[$colval] != '')
{
$cellbody .= '<b>'.$col->fname[$colval].'</b>';
}
else
{
$cellbody .= '<b>'.ucwords(preg_replace('/_/', ' ', $colval)).'</b>';
}
break;
case 'weaponimg':
// Check if game has the image -- if not, failback to real game. If not, no image.
$image = getImage("/games/$realgame/weapons/".strtolower($colval));
if ($image)
{
$cellbody .= '<img src="' . $image['url'] . '" ' . $image['size'] . ' alt="'.$col->fname[$colval].'" title="'.$col->fname[$colval].'" />';
}
elseif ($image = getImage("/games/$realgame/weapons/".strtolower($colval)))
{
$cellbody .= '<img src="' . $image['url'] . '" ' . $image['size'] . ' alt="'.$col->fname[$colval].'" title="'.$col->fname[$colval].'" />';
}
else
{
$cellbody .= '<b>' . (($col->fname[$colval] != '') ? $col->fname[$colval] : ucwords(preg_replace('/_/', ' ', $colval))) . '</b>';
}
break;
case 'bargraph':
$cellbody .= '<img src="' . IMAGE_PATH . '/bar';
if ($colval > 40)
$cellbody .= '6';
elseif ($colval > 30)
$cellbody .= '5';
elseif ($colval > 20)
$cellbody .= '4';
elseif ($colval > 10)
$cellbody .= '3';
elseif ($colval > 5)
$cellbody .= '2';
else
$cellbody .= '1';
$cellbody .= '.gif" style="width:';
if ($colval < 1)
$cellbody .= '1';
elseif ($colval > 100)
$cellbody .= '100';
else
$cellbody .= sprintf("%d", $colval + 0.5);
$cellbody .= "%;\" class=\"bargraph\" alt=\"$colval%\" />";
break;
case 'heatmap':
$heatmap = getImage("/games/$game/heatmaps/$colval-kill");
$heatmapthumb = getImage("/games/$game/heatmaps/$colval-kill-thumb");
if ($heatmap) {
$cellbody .= "<span style=\"text-align: center;\"><a href=\"" . $heatmap['url'] . "\" rel=\"boxed\"><img width=\"20\" height=\"16\" src=\"" . $heatmapthumb['url'] . "\" /></a></span>";
} else {
$cellbody .= "&nbsp;";
}
break;
default:
if ($this->showranking && $rank == 1 && $i == 1)
$cellbody .= '<b>';
if ((is_numeric($colval)) && ($colval >= 1000))
$colval = number_format($colval);
$colval = nl2br(htmlspecialchars($colval, ENT_COMPAT));
if ($col->embedlink == 'yes')
{
$colval = preg_replace(array('/%A%([^ %]+)%/','/%\/A%/'), array("<a href=\"$1\">", '</a>'), $colval);
}
$cellbody .= $colval;
if ($this->showranking && $rank == 1 && $i == 1)
$cellbody .= '</b>';
break;
}
if ($col->link)
{
$cellbody .= '</a>';
}
if ($col->append)
{
$cellbody .= $col->append;
}
if ($col->skill_change) {
if ($rowdata['last_skill_change'] == '')
$rowdata['last_skill_change'] = 0;
if ($rowdata['last_skill_change'] == 0)
$cellbody .= "&nbsp;<img src=\"" . IMAGE_PATH
. "/t1.gif\" alt=\"".$rowdata['last_skill_change']." Points\" />";
elseif ($rowdata['last_skill_change'] > 0)
$cellbody .= "&nbsp;<img src=\"" . IMAGE_PATH
. "/t0.gif\" alt=\"".$rowdata['last_skill_change']." Points\" />";
elseif ($rowdata['last_skill_change'] < 0)
$cellbody .= "&nbsp;<img src=\"" . IMAGE_PATH
. "/t2.gif\" alt=\"".$rowdata['last_skill_change']." Points\" />";
}
echo "<td$colalign class=\"$class\">"
. $cellbody
. "</td>\n";
$i++;
}
echo "</tr>\n\n";
$rank++;
}
?>
</table>
</div><br /><br />
<?php
if ($numpages > 1)
{
?>
<div class="subblock" style="text-align:right;">
<span style="text-align:right;">
<?php
echo 'Page: ';
$start = $this->page - intval($this->maxpagenumbers / 2);
if ($start < 1) $start=1;
$end = $numpages;
if ($end > $this->maxpagenumbers + $start-1)
$end = $this->maxpagenumbers + $start-1;
if ($end - $start + 1 < $this->maxpagenumbers)
$start = $end - $this->maxpagenumbers + 1;
if ($start < 1) $start=1;
if ($start > 1)
{
if ($start > 2)
$this->_echoPageNumber(1, "First page", "", " ...");
else
$this->_echoPageNumber(1, 1);
}
for ($i=$start; $i <= $end; $i++)
{
if ($i == $this->page)
{
echo "<b>$i</b> ";
}
else
{
$this->_echoPageNumber($i, $i);
}
if ($i == $end && $i < $numpages)
{
if ($i < $numpages - 1)
$this->_echoPageNumber($numpages, "Last page", "... ");
else
$this->_echoPageNumber($numpages, 10);
}
}
?>
</span>
</div><br /><br />
<?php
}
}
function _echoPageNumber ($number, $label, $prefix='', $postfix='')
{
global $g_options;
echo "$prefix<a href=\"" . $g_options['scripturl'] . '?'
. makeQueryString($this->var_page, $number);
if ($this->sorthash)
echo "#$this->sorthash";
if ($this->ajax)
echo "\" onclick=\"Tabs.refreshTab({'" . $this->var_page . "': " . $number . "}); return false;";
echo "\">$label</a>$postfix ";
}
}
//
// TableColumn
//
// Data structure for the properties of a column in a Table
//
class TableColumn
{
var $name;
var $title;
var $align = 'left';
var $width = 20;
var $icon;
var $link;
var $sort = 'yes';
var $type = 'text';
var $embedlink = 'no';
var $flag;
function TableColumn ($name, $title, $attrs="", $fname=null)
{
$this->name = $name;
$this->title= $title;
$allowed_attrs = array(
'align',
'width',
'icon',
'link',
'sort',
'append',
'type',
'embedlink',
'flag',
'skill_change',
'heatmap'
);
parse_str($attrs);
foreach ($allowed_attrs as $a)
{
if (isset($$a))
{
$this->$a = mystripslashes($$a);
}
}
$this->fname = $fname;
}
}

569
web/includes/functions.php Normal file
View File

@ -0,0 +1,569 @@
<?php
/*
HLstatsX Community Edition - Real-time player and clan rankings and statistics
Copyleft (L) 2008-20XX Nicholas Hastings (nshastings@gmail.com)
http://www.hlxcommunity.com
HLstatsX Community Edition is a continuation of
ELstatsNEO - Real-time player and clan rankings and statistics
Copyleft (L) 2008-20XX Malte Bayer (steam@neo-soft.org)
http://ovrsized.neo-soft.org/
ELstatsNEO is an very improved & enhanced - so called Ultra-Humongus Edition of HLstatsX
HLstatsX - Real-time player and clan rankings and statistics for Half-Life 2
http://www.hlstatsx.com/
Copyright (C) 2005-2007 Tobias Oetzel (Tobi@hlstatsx.com)
HLstatsX is an enhanced version of HLstats made by Simon Garner
HLstats - Real-time player and clan rankings and statistics for Half-Life
http://sourceforge.net/projects/hlstats/
Copyright (C) 2001 Simon Garner
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
For support and installation notes visit http://www.hlxcommunity.com
*/
if (!defined('IN_HLSTATS'))
{
die('Do not access this file directly.');
}
/**
* getOptions()
*
* @return Array All the options from the options/perlconfig table
*/
function getOptions()
{
global $db;
$result = $db->query("SELECT `keyname`,`value` FROM hlstats_Options WHERE opttype >= 1");
while ($rowdata = $db->fetch_row($result))
{
$options[$rowdata[0]] = $rowdata[1];
}
if ( !count($options) )
{
error('Warning: Could not find any options in table <b>hlstats_Options</b>, database <b>' .
DB_NAME . '</b>. Check HLstats configuration.');
}
$options['MinActivity'] = $options['MinActivity'] * 86400;
return $options;
}
// Test if flags exists
/**
* getFlag()
*
* @param string $flag
* @param string $type
* @return string Either the flag or default flag if none exists
*/
function getFlag($flag, $type='url')
{
$image = getImage('/flags/'.strtolower($flag));
if ($image)
return $image[$type];
else
return IMAGE_PATH.'/flags/0.gif';
}
/**
* valid_request()
*
* @param string $str
* @param boolean $numeric
* @return mixed request
*/
function valid_request($str, $numeric = false)
{
$search_pattern = array("/[^A-Za-z0-9\[\]*.,=()!\"$%&^`<60>':;߲<>#+~_\-|<>\/\\\\@{}<7D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ]/");
$replace_pattern = array('');
$str = preg_replace($search_pattern, $replace_pattern, $str);
if ( $numeric == false )
{
if ( get_magic_quotes_gpc() )
return $str = htmlspecialchars(stripslashes($str), ENT_QUOTES);
else
return $str = htmlspecialchars($str, ENT_QUOTES);
}
else
{
if ( is_numeric($str) )
return intval($str);
else
return -1;
}
}
/**
* timestamp_to_str()
*
* @param integer $timestamp
* @return string Formatted Timestamp
*/
function timestamp_to_str($timestamp)
{
if ($timestamp != '')
{
return sprintf('%dd&nbsp;%02d:%02d:%02dh', $timestamp / 86400, $timestamp / 3600 % 24, $timestamp /
60 % 60, $timestamp % 60);
}
return '-';
}
/**
* error()
* Formats and outputs the given error message. Optionally terminates script
* processing.
*
* @param mixed $message
* @param bool $exit
* @return void
*/
function error($message, $exit = true)
{
global $g_options;
?>
<table border="1" cellspacing="0" cellpadding="5">
<tr>
<td class="errorhead">ERROR</td>
</tr>
<tr>
<td class="errortext"><?php echo $message; ?></td>
</tr>
</table>
<?php if ($exit)
exit;
}
//
// string makeQueryString (string key, string value, [array notkeys])
//
// Generates an HTTP GET query string from the current HTTP GET variables,
// plus the given 'key' and 'value' pair. Any current HTTP GET variables
// whose keys appear in the 'notkeys' array, or are the same as 'key', will
// be excluded from the returned query string.
//
/**
* makeQueryString()
*
* @param mixed $key
* @param mixed $value
* @param mixed $notkeys
* @return
*/
function makeQueryString($key, $value, $notkeys = array())
{
if (!is_array($notkeys))
$notkeys = array();
$querystring = '';
foreach ($_GET as $k => $v)
{
$v = valid_request($v, 0);
if ($k && $k != $key && !in_array($k, $notkeys))
{
$querystring .= urlencode($k) . '=' . rawurlencode($v) . '&amp;';
}
}
$querystring .= urlencode($key) . '=' . urlencode($value);
return $querystring;
}
//
// void pageHeader (array title, array location)
//
// Prints the page heading.
//
/**
* pageHeader()
*
* @param mixed $title
* @param mixed $location
* @return
*/
function pageHeader($title = '', $location = '')
{
global $db, $g_options;
if ( defined('PAGE') && PAGE == 'HLSTATS' )
include (PAGE_PATH . '/header.php');
elseif ( defined('PAGE') && PAGE == 'INGAME' )
include (PAGE_PATH . '/ingame/header.php');
}
//
// void pageFooter (void)
//
// Prints the page footer.
//
/**
* pageFooter()
*
* @return
*/
function pageFooter()
{
global $g_options;
if ( defined('PAGE') && PAGE == 'HLSTATS' )
include (PAGE_PATH . '/footer.php');
elseif ( defined('PAGE') && PAGE == 'INGAME' )
include (PAGE_PATH . '/ingame/footer.php');
}
/**
* getSortArrow()
*
* @param mixed $sort
* @param mixed $sortorder
* @param mixed $name
* @param mixed $longname
* @param string $var_sort
* @param string $var_sortorder
* @param string $sorthash
* @return string Returns the code for a sort arrow <IMG> tag.
*/
function getSortArrow($sort, $sortorder, $name, $longname, $var_sort = 'sort', $var_sortorder =
'sortorder', $sorthash = '', $ajax = false)
{
global $g_options;
if ($sortorder == 'asc')
{
$sortimg = 'sort-ascending.gif';
$othersortorder = 'desc';
}
else
{
$sortimg = 'sort-descending.gif';
$othersortorder = 'asc';
}
$arrowstring = '<a href="' . $g_options['scripturl'] . '?' . makeQueryString($var_sort, $name,
array($var_sortorder));
if ($sort == $name)
{
$arrowstring .= "&amp;$var_sortorder=$othersortorder";
$jsarrow = "'" . $var_sortorder . "': '" . $othersortorder . "'";
}
else
{
$arrowstring .= "&amp;$var_sortorder=$sortorder";
$jsarrow = "'" . $var_sortorder . "': '" . $sortorder . "'";
}
if ($sorthash)
{
$arrowstring .= "#$sorthash";
}
$arrowstring .= '" class="head"';
if ( $ajax )
{
$arrowstring .= " onclick=\"Tabs.refreshTab({'$var_sort': '$name', $jsarrow}); return false;\"";
}
$arrowstring .= ' title="Change sorting order">' . "$longname</a>";
if ($sort == $name)
{
$arrowstring .= '&nbsp;<img src="' . IMAGE_PATH . "/$sortimg\"" .
" style=\"padding-left:4px;padding-right:4px;\" alt=\"$sortimg\" />";
}
return $arrowstring;
}
/**
* getSelect()
* Returns the HTML for a SELECT box, generated using the 'values' array.
* Each key in the array should be a OPTION VALUE, while each value in the
* array should be a corresponding descriptive name for the OPTION.
*
* @param mixed $name
* @param mixed $values
* @param string $currentvalue
* @return The 'currentvalue' will be given the SELECTED attribute.
*/
function getSelect($name, $values, $currentvalue = '')
{
$select = "<select name=\"$name\" style=\"width:300px;\">\n";
$gotcval = false;
foreach ($values as $k => $v)
{
$select .= "\t<option value=\"$k\"";
if ($k == $currentvalue)
{
$select .= ' selected="selected"';
$gotcval = true;
}
$select .= ">$v</option>\n";
}
if ($currentvalue && !$gotcval)
{
$select .= "\t<option value=\"$currentvalue\" selected=\"selected\">$currentvalue</option>\n";
}
$select .= '</select>';
return $select;
}
/**
* getLink()
*
* @param mixed $url
* @param integer $maxlength
* @param string $type
* @param string $target
* @return
*/
function getLink($url, $type = 'http://', $target = '_blank')
{
$urld=parse_url($url);
if(!isset($urld['scheme']) && (!isset($urld['host']) && isset($urld['path'])))
{
$urld['scheme']=str_replace('://', '', $type);
$urld['host']=$urld['path'];
unset($urld['path']);
}
if($urld['scheme']!='http' && $urld['scheme']!='https')
{
return 'Invalid Url :(';
}
if(!isset($urld['path']))
{
$urld['path']='';
}
if(!isset($urld['query']))
{
$urld['query']='';
}
else
{
$urld['query']='?' . urlencode($urld['query']);
}
if(!isset($urld['fragment']))
{
$urld['fragment']='';
}
else
{
$urld['fragment']='#' . urlencode($urld['fragment']);
}
$uri=sprintf("%s%s%s", $urld['path'], $urld['query'], $urld['fragment']);
$host_uri=$urld['host'] . $uri;
return sprintf('<a href="%s://%s%s" target="%s">%s</a>',$urld['scheme'], $urld['host'], $uri, $target, htmlspecialchars($host_uri, ENT_COMPAT));
}
/**
* getEmailLink()
*
* @param string $email
* @param integer $maxlength
* @return string Formatted email tag
*/
function getEmailLink($email, $maxlength = 40)
{
if (preg_match('/(.+)@(.+)/', $email, $regs))
{
if (strlen($email) > $maxlength)
{
$email_title = substr($email, 0, $maxlength - 3) . '...';
}
else
{
$email_title = $email;
}
$email = str_replace('"', urlencode('"'), $email);
$email = str_replace('<', urlencode('<'), $email);
$email = str_replace('>', urlencode('>'), $email);
return "<a href=\"mailto:$email\">" . htmlspecialchars($email_title, ENT_COMPAT) . '</a>';
}
else
{
return '';
}
}
/**
* getImage()
*
* @param string $filename
* @return mixed Either the image if exists, or false otherwise
*/
function getImage($filename)
{
preg_match('/^(.*\/)(.+)$/', $filename, $matches);
$relpath = $matches[1];
$realfilename = $matches[2];
$path = IMAGE_PATH . $filename;
$url = IMAGE_PATH . $relpath . rawurlencode($realfilename);
// check if image exists
if (file_exists($path . '.png'))
{
$ext = 'png';
} elseif (file_exists($path . '.gif'))
{
$ext = 'gif';
} elseif (file_exists($path . '.jpg'))
{
$ext = 'jpg';
}
else
{
$ext = '';
}
if ($ext)
{
$size = getImageSize("$path.$ext");
return array('url' => "$url.$ext", 'path' => "$path.$ext", 'width' => $size[0], 'height' => $size[1],
'size' => $size[3]);
}
else
{
return false;
}
}
function mystripslashes($text)
{
return get_magic_quotes_gpc() ? stripslashes($text) : $text;
}
function getRealGame($game)
{
global $db;
$result = $db->query("SELECT realgame from hlstats_Games WHERE code='$game'");
list($realgame) = $db->fetch_row($result);
return $realgame;
}
function printSectionTitle($title)
{
echo '<span class="fHeading">&nbsp;<img src="'.IMAGE_PATH."/downarrow.gif\" alt=\"\" />&nbsp;$title</span><br /><br />\n";
}
function getStyleText($style)
{
return "\t<link rel=\"stylesheet\" type=\"text/css\" href=\"./css/$style.css\" />\n";
}
function getJSText($js)
{
return "\t<script type=\"text/javascript\" src=\"".INCLUDE_PATH."/js/$js.js\"></script> \n";
}
function get_player_rank($playerdata) {
global $db, $g_options;
$rank = 0;
$tempdeaths = $playerdata['deaths'];
if ($tempdeaths == 0)
$tempdeaths = 1;
$query = "
SELECT
COUNT(*)
FROM
hlstats_Players
WHERE
game='".$playerdata['game']."'
AND hideranking = 0
AND kills >= 1
AND (
(".$g_options['rankingtype']." > '".$playerdata[$g_options['rankingtype']]."') OR (
(".$g_options['rankingtype']." = '".$playerdata[$g_options['rankingtype']]."') AND (kills/IF(deaths=0,1,deaths) > ".($playerdata['kills']/$tempdeaths).")
)
)
";
$db->query($query);
list($rank) = $db->fetch_row();
$rank++;
return $rank;
}
if (!function_exists('file_get_contents')) {
function file_get_contents($filename, $incpath = false, $resource_context = null)
{
if (false === $fh = fopen($filename, 'rb', $incpath)) {
trigger_error('file_get_contents() failed to open stream: No such file or directory', E_USER_WARNING);
return false;
}
clearstatcache();
if ($fsize = @filesize($filename)) {
$data = fread($fh, $fsize);
} else {
$data = '';
while (!feof($fh)) {
$data .= fread($fh, 8192);
}
}
fclose($fh);
return $data;
}
}
/**
* Convert colors Usage: color::hex2rgb("FFFFFF")
*
* @author Tim Johannessen <root@it.dk>
* @version 1.0.1
*/
function hex2rgb($hexVal = '')
{
$hexVal = preg_replace('[^a-fA-F0-9]', '', $hexVal);
if (strlen($hexVal) != 6)
{
return 'ERR: Incorrect colorcode, expecting 6 chars (a-f, 0-9)';
}
$arrTmp = explode(' ', chunk_split($hexVal, 2, ' '));
$arrTmp = array_map('hexdec', $arrTmp);
return array('red' => $arrTmp[0], 'green' => $arrTmp[1], 'blue' => $arrTmp[2]);
}
?>

View File

@ -0,0 +1,443 @@
<?php
/*
HLstatsX Community Edition - Real-time player and clan rankings and statistics
Copyleft (L) 2008-20XX Nicholas Hastings (nshastings@gmail.com)
http://www.hlxcommunity.com
HLstatsX Community Edition is a continuation of
ELstatsNEO - Real-time player and clan rankings and statistics
Copyleft (L) 2008-20XX Malte Bayer (steam@neo-soft.org)
http://ovrsized.neo-soft.org/
ELstatsNEO is an very improved & enhanced - so called Ultra-Humongus Edition of HLstatsX
HLstatsX - Real-time player and clan rankings and statistics for Half-Life 2
http://www.hlstatsx.com/
Copyright (C) 2005-2007 Tobias Oetzel (Tobi@hlstatsx.com)
HLstatsX is an enhanced version of HLstats made by Simon Garner
HLstats - Real-time player and clan rankings and statistics for Half-Life
http://sourceforge.net/projects/hlstats/
Copyright (C) 2001 Simon Garner
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
For support and installation notes visit http://www.hlxcommunity.com
*/
function image_dashed_line($image, $x1, $y1, $x2, $y2, $style)
{
if (count($style)>0) {
$temp_x1 = $x1;
$temp_y1 = $y1;
$count = 0;
while (($temp_x1<$x2) || ($temp_y1<$y2)) {
$my_style = $style[$count % count($style)];
$step = 0;
while ($my_style != $style[(($count+$step) % count($style))]) {
$step++;
}
if ($step==0)
$step++;
if ($x1 != $x2) {
if ($my_style != -1)
imageline($image, $temp_x1, $y1, $temp_x1+$step, $y2, $my_style);
$temp_x1 = $temp_x1 + $step;
}
if ($y1!=$y2) {
if ($my_style != -1)
imageline($image, $x1, $temp_y1, $x2, $temp_y1+$step, $my_style);
$temp_y1 = $temp_y1 + $step;
}
$count = $count + $step;
}
} else {
imageline($image, $x1, $y1, $x2, $y2, $style[0]);
}
}
//TSGK
$first_entry = 0;
//TSGK
function drawItems($image, $bounds, $data_array, $max_index, $name, $dot, $make_grid, $write_timestamp, $write_legend, $color)
{
global $max_pos_y;
global $legend_x;
global $bar_type;
global $deletedays;
global $server_load_type;
//TSGK
global $first_entry;
$first_entry++;
//TSGK
if (!isset($max_pos_y[$max_index])) {
$max_pos_y[$max_index] = 0;
}
foreach ($data_array as $entry) {
if ($entry[$name] >= $max_pos_y[$max_index]) {
if ($entry[$name] < 100)
$max_pos_y[$max_index] = $entry[$name] + 2;
else if ($entry[$name] < 200)
$max_pos_y[$max_index] = $entry[$name] + 10;
else if ($entry[$name] < 10000)
$max_pos_y[$max_index] = $entry[$name] + ($entry[$name] * 0.3);
else
$max_pos_y[$max_index] = $entry[$name] - ($entry[$name] % 50000) + 100000;
if ($make_grid > 0) {
if ($max_pos_y[$max_index] % 2 != 0)
$max_pos_y[$max_index]++;
$i = 0;
while (($i < 10) && ($max_pos_y[$max_index] % 4 != 0)) {
$max_pos_y[$max_index]++;
$i++;
}
}
if ($max_pos_y[$max_index] == 0)
$max_pos_y[$max_index] = 1;
}
}
if ($write_legend > 0) {
if ($legend_x == 0)
$legend_x += $bounds['indent_x'][0] + 10;
imagesetpixel($image, $legend_x, $bounds['indent_y'][0]-7, $color[0]);
imagesetpixel($image, $legend_x+1, $bounds['indent_y'][0]-7, $color[0]);
imagesetpixel($image, $legend_x+2, $bounds['indent_y'][0]-7, $color[0]);
imagesetpixel($image, $legend_x, $bounds['indent_y'][0]-8, $color[0]);
imagesetpixel($image, $legend_x+1, $bounds['indent_y'][0]-8, $color[0]);
imagesetpixel($image, $legend_x+2, $bounds['indent_y'][0]-8, $color[0]);
imagesetpixel($image, $legend_x, $bounds['indent_y'][0]-9, $color[0]);
imagesetpixel($image, $legend_x+1, $bounds['indent_y'][0]-9, $color[0]);
imagesetpixel($image, $legend_x+2, $bounds['indent_y'][0]-9, $color[0]);
$legend_x += 7;
imagestring($image, 1, $legend_x, $bounds['indent_y'][0]-11, $name , $color[2]);
$legend_x += (imagefontwidth(1) * strlen($name)) + 7;
}
$start_pos = array("x" => $bounds['width']-$bounds['indent_x'][1], "y" => $bounds['indent_y'][1]);
$pos = $start_pos;
$cache = array("x" => 0, "y" => 0);
$step_y = ($bounds['height']-$bounds['indent_y'][0]-$bounds['indent_y'][1]) / 10;
if ($step_y < 15)
$step_y = 15;
// TSGK MAP TEXT
$last_map = "";
$last_map_posx = 0;
$bk_color = 0;
global $gray_border;
if (($first_entry == 1) && ($make_grid > 0) && ($server_load_type == 1)) {
foreach ($data_array as $key => $entry) {
if (($entry['map'] !== $last_map) || ($pos['x'] <= ($bounds['indent_x'][0]+1) )) {
if ($last_map == "") {
$last_map = $entry['map'];
$last_map_posx = $pos['x'];
} else {
$last_map = $entry['map'];
while ($last_map_posx > $pos['x']) {
if (($bk_color % 2) == 0) {
imageline($image, $last_map_posx, $bounds['indent_y'][0]+1, $last_map_posx, $bounds['height']-$bounds['indent_y'][1]-1, $color[4]);
}
$last_map_posx--;
}
$bk_color++;
imageline($image, $pos['x']+1, $bounds['indent_y'][0]+1, $pos['x']+1, $bounds['height']-$bounds['indent_y'][1]-1, $gray_border);
$last_map_posx = $pos['x'];
}
}
$pos['x'] -= 3;
if ($pos['x'] < $bounds['indent_x'][0])
break;
}
}
// END TSGK MAP TEXT
if ($make_grid > 0) {
$step_diff = 0;
$step_width = 0;
while ($step_diff < 15) {
$step_width++;
if ($max_pos_y[$max_index] % $step_width == 0) {
$steps = $max_pos_y[$max_index] / $step_width;
if ($steps > 0)
$step_diff = ($bounds['height']-$bounds['indent_y'][0]-$bounds['indent_y'][1]) / $steps;
else
$step_diff = 15;
} else {
$step_diff = 0;
}
}
for ($i=1; $i<$steps; $i++) {
$temp_y = (($bounds['height']-$bounds['indent_y'][0]-$bounds['indent_y'][1]) - ((($bounds['height']-$bounds['indent_y'][0]-$bounds['indent_y'][1]) / $max_pos_y[$max_index]) * ($i*$step_width))) + $bounds['indent_y'][0];
if ($temp_y > $bounds['indent_y'][0]+5)
image_dashed_line($image, $bounds['indent_x'][0]+1,
$temp_y,
($bounds['width']-$bounds['indent_x'][1]-1),
$temp_y,
array($color[4], $color[4], $color[4], -1, -1, -1));
imageline($image, $bounds['indent_x'][0]+1, $temp_y, $bounds['indent_x'][0]+4, $temp_y, $color[3]);
if ($max_pos_y[$max_index] > 10000) {
$str = sprintf("%.0fk", ($i*$step_width) / 1000);
} else {
$str = sprintf("%.0f", $i*$step_width);
}
$str_pos = $bounds['indent_x'][0] - (imagefontwidth(1) * strlen($str)) - 2;
imagestring($image, 1, $str_pos, $temp_y-3, $str, $color[2]);
}
if ($max_pos_y[$max_index] > 10000)
$str = sprintf("%.0fk", $max_pos_y[$max_index] / 1000);
else
$str = sprintf("%.0f", $max_pos_y[$max_index]);
$str_pos = $bounds['indent_x'][0] - (imagefontwidth(1) * strlen($str)) - 2;
imagestring($image, 1, $str_pos, $bounds['indent_y'][0]-3, $str, $color[2]);
}
$last_month = 0;
$last_month_timestamp = 0;
$last_day = 0;
$last_day_timestamp = 0;
$first_timestamp = 0;
$first_day = 0;
switch ($server_load_type) {
case 1 : $mov_avg_precision = 5;
break;
case 2 : $mov_avg_precision = 5;
break;
case 3 : $mov_avg_precision = 10;
break;
case 4 : $mov_avg_precision = 10;
break;
default: $mov_avg_precision = 1;
break;
}
$mov_avg_array = array();
$mov_avg_value = 0;
$mov_avg_display_value = array();
$i = 0;
while (($i < count($data_array)) && ($i < $mov_avg_precision / 2)) {
$entry = $data_array[$i];
$mov_avg_array[] = (($bounds['height']-$bounds['indent_y'][0]-$bounds['indent_y'][1]) - ((($bounds['height']-$bounds['indent_y'][0]-$bounds['indent_y'][1]) / $max_pos_y[$max_index]) * $entry[$name])) + $bounds['indent_y'][0];
$mov_avg_display_value[] = $entry[$name];
$i++;
}
// TSGK
$last_map = "";
$last_map_posx = 0;
$bk_color = 0;
// TSGK
foreach ($data_array as $key => $entry) {
$pos['y'] = (($bounds['height']-$bounds['indent_y'][0]-$bounds['indent_y'][1]) - ((($bounds['height']-$bounds['indent_y'][0]-$bounds['indent_y'][1]) / $max_pos_y[$max_index]) * $entry[$name])) + $bounds['indent_y'][0];
// TSGK
$maptext = imagecolorallocate($image, 96, 96, 96);
if(!isset($entry['map']))
$entry['map']="";
if (($first_entry == 2) && ($server_load_type == 1)) {
if ($entry['map'] !== $last_map) {
if ($last_map == "") {
$last_map = $entry['map'];
$last_map_posx = $pos['x'];
if ($entry['map'] != "") {
$str_height = $bounds['indent_y'][0] + (imagefontwidth(1) * strlen($entry['map'])) + 2;
imagestringup($image, 1, $pos['x']-8, $str_height, $entry['map'], $maptext);
}
} else {
$last_map = $entry['map'];
$str_height = $bounds['indent_y'][0] + (imagefontwidth(1) * strlen($entry['map'])) + 2;
imagestringup($image, 1, $pos['x']-8, $str_height, $entry['map'], $maptext);
$last_map_posx = $pos['x'];
}
}
}
// TSGK
$mov_avg_array[] = $pos['y'];
$mov_avg_value = $pos['y'];
if (count($mov_avg_array) > $mov_avg_precision)
array_shift($mov_avg_array);
$mov_avg_sum = 0;
$mov_avg_display_sum = 0;
foreach ($mov_avg_array as $mov_avg_entry)
$mov_avg_sum += $mov_avg_entry;
$mov_avg_value = sprintf("%d", ($mov_avg_sum / count($mov_avg_array)));
$pos['y'] = $mov_avg_value;
if ($key > 0) {
imageline($image, $cache['x'], $cache['y'], $pos['x'], $pos['y'], $color[0]);
}
if ($key == 0) {
foreach ($mov_avg_display_value as $mov_avg_display_entry)
$mov_avg_display_sum += $mov_avg_display_entry;
$display_value = sprintf("%d", ($mov_avg_display_sum / count($mov_avg_display_value)));
if ($display_value > 10000)
$str = sprintf("%.1fk", $display_value / 1000);
else
if ($name !== "act_players")
$str = sprintf("%.0f", $display_value);
else
$str = sprintf("%.1f", $display_value);
imagestring($image, 1, $pos['x']+2, $pos['y']-4, $str, $color[2]);
}
if ($first_timestamp == 0)
$first_timestamp = $entry['timestamp'];
$this_month = date("m", $entry['timestamp']);
if ($this_month > $last_month+1)
$last_month = $this_month+1;
if ($last_month == 0) {
$last_month = $this_month;
$last_month_timestamp = $entry['timestamp'];
}
if ($last_month == $this_month)
$last_month_timestamp = $entry['timestamp'];
$this_day = date("d", $entry['timestamp']);
if ($this_day > $last_day+1)
$last_day = $this_day+1;
if ($last_day == 0) {
$last_day = $this_day;
$last_day_timestamp = $entry['timestamp'];
}
if ($last_day == $this_day)
$last_day_timestamp = $entry['timestamp'];
switch ($server_load_type) {
case 1:
if (($write_timestamp > 0) && ($key > 0 && $key % 12 == 0)) {
image_dashed_line($image, $pos['x'], $pos['y'], $pos['x'], $bounds['height']-$bounds['indent_y'][1], array($color[1], $color[1], $color[1], -1, -1, -1));
$str = date("H:i", $entry['timestamp']);
imagestring($image, 1, $pos['x']-10, $bounds['height']-$bounds['indent_y'][1]+3, $str, $color[2]);
}
break;
case 2:
if (($write_timestamp > 0) && ($last_day > $this_day)) {
$last_day = $this_day;
if ($bounds['width']-$bounds['indent_x'][1]-$pos['x'] > 120)
$first_day++;
if ($first_day > 0) {
image_dashed_line($image, $pos['x'], $pos['y'], $pos['x'], $bounds['height']-$bounds['indent_y'][1], array($color[1], $color[1], $color[1], -1, -1, -1));
$first_day++;
if ($last_day_timestamp == 0)
$last_day_timestamp = $first_timestamp;
$str = date("l", $last_day_timestamp);
imagestring($image, 1, $pos['x']-15, $bounds['height']-$bounds['indent_y'][1]+3, $str, $color[2]);
}
$first_day++;
}
break;
case 3:
if (($write_timestamp > 0) && ($last_day > $this_day)) {
$last_day = $this_day;
if ($bounds['width']-$bounds['indent_x'][1]-$pos['x'] > 0)
$first_day++;
if ($first_day > 0) {
image_dashed_line($image, $pos['x'], $pos['y'], $pos['x'], $bounds['height']-$bounds['indent_y'][1], array($color[1], $color[1], $color[1], -1, -1, -1));
if ($last_day_timestamp == 0)
$last_day_timestamp = $first_timestamp;
$str = date("d", $last_day_timestamp);
imagestring($image, 1, $pos['x']-5, $bounds['height']-$bounds['indent_y'][1]+3, $str, $color[2]);
}
}
break;
case 4:
if (($write_timestamp > 0) && ($last_month > $this_month)) {
$last_month = $this_month;
if ($bounds['width']-$bounds['indent_x'][1]-$pos['x'] > 30)
$first_day++;
if ($first_day > 0) {
image_dashed_line($image, $pos['x'], $pos['y'], $pos['x'], $bounds['height']-$bounds['indent_y'][1], array($color[1], $color[1], $color[1], -1, -1, -1));
$first_day++;
if ($last_month_timestamp == 0)
$last_month_timestamp = $first_timestamp;
$str = date("M", $last_month_timestamp);
imagestring($image, 1, $pos['x']-5, $bounds['height']-$bounds['indent_y'][1]+3, $str, $color[2]);
}
$first_day++;
}
break;
default:
if (($write_timestamp > 0) && ($key > 0 && $key % 12 == 0)) {
image_dashed_line($image, $pos['x'], $pos['y'], $pos['x'], $bounds['height']-$bounds['indent_y'][1], array($color[1], $color[1], $color[1], -1, -1, -1));
$str = date("H:i", $entry['timestamp']);
imagestring($image, 1, $pos['x']-10, $bounds['height']-$bounds['indent_y'][1]+3, $str, $color[2]);
}
break;
}
if ($dot > 0) {
imagesetpixel($image, $pos['x'], $pos['y'], $color[0]);
imagesetpixel($image, $pos['x']-1, $pos['y'], $color[0]);
imagesetpixel($image, $pos['x']-1, $pos['y']-1, $color[0]);
imagesetpixel($image, $pos['x']-1, $pos['y']+1, $color[0]);
imagesetpixel($image, $pos['x']+1, $pos['y'], $color[0]);
imagesetpixel($image, $pos['x']+1, $pos['y']-1, $color[0]);
imagesetpixel($image, $pos['x']+1, $pos['y']+1, $color[0]);
imagesetpixel($image, $pos['x'], $pos['y']-1, $color[0]);
imagesetpixel($image, $pos['x'], $pos['y']+1, $color[0]);
} else {
imagesetpixel($image, $pos['x'], $pos['y'], $color[0]);
}
$cache['x'] = $pos['x'];
$cache['y'] = $pos['y'];
$step_x = 3;
if ($bar_type==2) {
// skalieren auf anzahl Tage
$step_x = round( ($bounds['width']-$bounds['indent_x'][1]-$bounds['indent_x'][0]) / $deletedays );
}
if ($bar_type==3 || $bar_type==4) {
// skalieren
$step_x = 5;
}
$pos['x'] -= $step_x;
if ($pos['x'] < $bounds['indent_x'][0])
break;
}
}
?>

View File

@ -0,0 +1,418 @@
<?php
/*
HLstatsX Community Edition - Real-time player and clan rankings and statistics
Copyleft (L) 2008-20XX Nicholas Hastings (nshastings@gmail.com)
http://www.hlxcommunity.com
HLstatsX Community Edition is a continuation of
ELstatsNEO - Real-time player and clan rankings and statistics
Copyleft (L) 2008-20XX Malte Bayer (steam@neo-soft.org)
http://ovrsized.neo-soft.org/
ELstatsNEO is an very improved & enhanced - so called Ultra-Humongus Edition of HLstatsX
HLstatsX - Real-time player and clan rankings and statistics for Half-Life 2
http://www.hlstatsx.com/
Copyright (C) 2005-2007 Tobias Oetzel (Tobi@hlstatsx.com)
HLstatsX is an enhanced version of HLstats made by Simon Garner
HLstats - Real-time player and clan rankings and statistics for Half-Life
http://sourceforge.net/projects/hlstats/
Copyright (C) 2001 Simon Garner
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
For support and installation notes visit http://www.hlxcommunity.com
*/
function printMap($type = 'main')
{
global $db, $game, $g_options, $clandata, $clan;
if ($type == 'main')
{
echo ('<script src="http://maps.google.com/maps/api/js?sensor=false" type="text/javascript"></script>');
}
?>
<script type="text/javascript">
/* <![CDATA[ */
//Add the preloads here...so that they don't get load
//after the graphs load
function preloadImages() {
var d=document; if(d.images){ if(!d.p) d.p=new Array();
var i,j=d.p.length,a=preloadImages.arguments; for(i=0; i<a.length; i++)
if (a[i].indexOf("#")!=0){ d.p[j]=new Image; d.p[j++].src=a[i];}}
}
<?php echo "preloadImages('".IMAGE_PATH."/mm_20_blue.png', ".(($type == 'main')?"'".IMAGE_PATH."/mm_20_red.png', ":'')."'".IMAGE_PATH."/mm_20_shadow.png');"; ?>
var point_icon = "<?php echo IMAGE_PATH; ?>/mm_20_blue.png";
var point_icon_red = "<?php echo IMAGE_PATH; ?>/mm_20_red.png";
<?php
if ($type == 'main') {
}
// this create mapLatLng
printMapCenter(($type == 'clan' && $clandata['mapregion'] != '') ? $clandata['mapregion'] : $g_options['google_map_region']);
// this creates mapType
printMapType($g_options['google_map_type']);
?>
var myOptions = {
center: mapLatLng,
mapTypeId: mapType,
zoom: mapZoom,
scrollwheel: false,
mapTypeControl: true,
mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU},
navigationControl: true,
navigationControlOptions: {style: google.maps.NavigationControlStyle.ZOOM_PAN}
};
var map = new google.maps.Map(document.getElementById("map"), myOptions);
function createMarker(point, city, country, player_info) {
var html_text = '<table class="gmapstab"><tr><td colspan="2" class="gmapstabtitle" style="border-bottom:1px solid black;">'+city+', '+country+'</td></tr>';
for ( i=0; i<player_info.length; i++) {
html_text += '<tr><td><a href="hlstats.php?mode=playerinfo&amp;player='+player_info[i][0]+'">'+player_info[i][1]+'</a></td></tr>';
html_text += '<tr><td>Kills/Deaths</td><td>'+player_info[i][2]+':'+player_info[i][3]+'</td></tr>';
<?php
if ($type == 'main') {
echo "html_text += '<tr><td>Time</td><td>'+player_info[i][4]+'</td></tr>';";
}
?>
}
html_text += '</table>';
var infowindow = new google.maps.InfoWindow({
content: html_text
})
var marker = new google.maps.Marker({
position: point,
map: map,
icon: point_icon
});
google.maps.event.addListener(marker, "click", function() {infowindow.open(map, marker);});
}
<?php
if ($type == 'main') {
?>
function createMarkerS(point, servers, city, country, kills) {
var html_text = '<table class="gmapstab"><tr><td colspan="2" class="gmapstabtitle" style="border-bottom:1px solid black;">'+city+', '+country+'</td></tr>';
for ( i=0; i<servers.length; i++) {
html_text += '<tr><td><a href=\"hlstats.php?mode=servers&server_id=' + servers[i][0] + '&amp;game=<?php echo $game; ?>\">' + servers[i][2] + '</a></td></tr>';
html_text += '<tr><td>' + servers[i][1] + ' (<a href=\"steam://connect/' + servers[i][1] + '\">connect</a>)</td></tr>';
}
html_text += '<tr><td>'+kills+' kills</td></tr></table>';
var infowindow = new google.maps.InfoWindow({
content: html_text
})
var marker = new google.maps.Marker({
position: point,
map: map,
icon: point_icon_red
});
google.maps.event.addListener(marker, "click", function() {infowindow.open(map, marker);});
}
<?php
$db->query("SELECT serverId, IF(publicaddress != '', publicaddress, CONCAT(address, ':', port)) AS addr, name, kills, lat, lng, city, country FROM hlstats_Servers WHERE game='$game' AND lat IS NOT NULL AND lng IS NOT NULL");
$servers = array();
while ($row = $db->fetch_array())
{
//Skip this part, if we already have the location info (should be the same)
if (!isset($servers[$row['lat'] . ',' . $row['lng']]))
{
$servers[$row['lat'] . ',' . $row['lng']] = array('lat' => $row['lat'], 'lng' => $row['lng'], 'publicaddress' => $row['public_address'], 'city' => $row['city'], 'country' => $row['country']);
}
$servers[$row['lat'] . ',' . $row['lng']]['servers'][] = array('serverId' => $row['serverId'], 'addr' => $row['addr'], 'name' => $row['name'], 'kills' => $row['kills']);
}
foreach ($servers as $map_location)
{
$kills = 0;
$servers_js = array();
foreach ($map_location['servers'] as $server)
{
$search_pattern = array("/[^A-Za-z0-9\[\]*.,=()!\"$%&^`<60>':;߲<>#+~_\-|<>\/@{}<7D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ]/");
$replace_pattern = array("");
$server['name'] = preg_replace($search_pattern, $replace_pattern, $server['name']);
$temp = "[" . $server['serverId'] . ',';
$temp .= "'" . htmlspecialchars(urldecode(preg_replace($search_pattern, $replace_pattern, $server['addr'])), ENT_QUOTES) . '\',';
$temp .= "'" . htmlspecialchars(urldecode(preg_replace($search_pattern, $replace_pattern, $server['name'])), ENT_QUOTES) . '\']';
$servers_js[] = $temp;
$kills += $server['kills'];
}
echo 'createMarkerS(new google.maps.LatLng(' . $map_location['lat'] . ', ' . $map_location['lng'] . '), [' . implode(',', $servers_js) . '], "' . htmlspecialchars(urldecode($map_location['city']), ENT_QUOTES) . '", "' . htmlspecialchars(urldecode($map_location['country']), ENT_QUOTES) . '", ' . $kills . ");\n";
}
$data = array();
$db->query("SELECT
hlstats_Livestats.*
FROM
hlstats_Livestats
INNER JOIN
hlstats_Servers
ON (hlstats_Servers.serverId=hlstats_Livestats.server_id)
WHERE
hlstats_Livestats.cli_lat IS NOT NULL
AND hlstats_Livestats.cli_lng IS NOT NULL
AND hlstats_Servers.game='$game'
");
$players = array();
while ($row = $db->fetch_array())
{
//Skip this part, if we already have the location info (should be the same)
if (!isset($players[$row['cli_lat'] . ',' . $row['cli_lng']]))
{
$players[$row['cli_lat'] . ',' . $row['cli_lng']] = array('cli_lat' => $row['cli_lat'], 'cli_lng' => $row['cli_lng'], 'cli_city' => $row['cli_city'], 'cli_country' => $row['cli_country']);
}
$search_pattern = array("/[^A-Za-z0-9\[\]*.,=()!\"$%&^`<60>':;߲<>#+~_\-|<>\/@{}<7D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ]/");
$replace_pattern = array("");
$row['name'] = preg_replace($search_pattern, $replace_pattern, $row['name']);
$players[$row['cli_lat'] . ',' . $row['cli_lng']]['players'][] = array('playerId' => $row['player_id'], 'name' => $row['name'], 'kills' => $row['kills'], 'deaths' => $row['deaths'], 'connected' => $row['connected']);
}
foreach ($players as $map_location)
{
$kills = 0;
$players_js = array();
foreach ($map_location['players'] as $player)
{
$stamp = time() - $player['connected'];
$hours = sprintf("%02d", floor($stamp / 3600));
$min = sprintf("%02d", floor(($stamp % 3600) / 60));
$sec = sprintf("%02d", floor($stamp % 60));
$time_str = $hours . ":" . $min . ":" . $sec;
$temp = "[" . $player['playerId'] . ',';
$temp .= "'" . htmlspecialchars(urldecode(preg_replace($search_pattern, $replace_pattern, $player['name'])), ENT_QUOTES) . "',";
$temp .= $player['kills'] . ',';
$temp .= $player['deaths'] . ',';
$temp .= "'" . $time_str . "']";
$players_js[] = $temp;
}
echo "createMarker(new google.maps.LatLng(" . $map_location['cli_lat'] . ", " . $map_location['cli_lng'] . "), \"" . htmlspecialchars(urldecode($map_location['cli_city']), ENT_QUOTES) . "\", \"" . htmlspecialchars(urldecode($map_location['cli_country']), ENT_QUOTES) . '", [' . implode(',', $players_js) . "]);\n";
}
} else if ($type == 'clan') {
$db->query("
SELECT
playerId,
lastName,
country,
skill,
kills,
deaths,
lat,
lng,
city,
country
FROM
hlstats_Players
WHERE
clan=$clan
AND hlstats_Players.hideranking = 0
GROUP BY
hlstats_Players.playerId
");
$players = array();
while ( $row = $db->fetch_array() )
{
//Skip this part, if we already have the location info (should be the same)
if ( !isset($players[ $row['lat'] . ',' . $row['lng'] ]) )
{
$players[ $row['lat'] . ',' . $row['lng'] ] = array(
'lat' => $row['lat'],
'lng' => $row['lng'],
'city' => $row['city'],
'country' => $row['country']
);
}
$search_pattern = array("/[^A-Za-z0-9\[\]*.,=()!\"$%&^`<60>':;߲<>#+~_\-|<>\/@{}<7D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ]/");
$replace_pattern = array("");
$row['name'] = preg_replace($search_pattern, $replace_pattern, $row['name']);
$players[ $row['lat'] . ',' . $row['lng'] ]['players'][] = array(
'playerId' => $row['playerId'],
'name' => $row['lastName'],
'kills' => $row['kills'],
'deaths' => $row['deaths'],
'connected' => $row['connected']
);
}
foreach ( $players as $location )
{
$kills = 0;
$players_js = array();
foreach ( $location['players'] as $player )
{
$temp = "[" . $player['playerId'] . ',';
$temp .= "'" . htmlspecialchars(urldecode(preg_replace($search_pattern, $replace_pattern, $player['name'])), ENT_QUOTES) . "',";
$temp .= $player['kills'] . ',';
$temp .= $player['deaths'] . ']';
$players_js[] = $temp;
}
echo "createMarker(new google.maps.LatLng(" . $location['lat'] . ", " . $location['lng'] . "), \"" . htmlspecialchars(urldecode($location['city']), ENT_QUOTES) . "\", \"" . htmlspecialchars(urldecode($location['country']), ENT_QUOTES) . "\", [" . implode(",", $players_js) . "]);\n";
}
}
?>
/* ]]> */
</script>
<?php
}
function printMapCenter($country)
{
switch (strtoupper($country))
{
case 'EUROPE':
echo "var mapLatLng = new google.maps.LatLng(48.8, 8.5);\nvar mapZoom = 3;";
break;
case 'NORTH AMERICA':
echo "var mapLatLng = new google.maps.LatLng(45.0, -97.0);\nvar mapZoom = 3;";
break;
case 'SOUTH AMERICA':
echo "var mapLatLng = new google.maps.LatLng(-14.8, -61.2);\nvar mapZoom = 3;";
break;
case 'NORTH AFRICA':
echo "var mapLatLng = new google.maps.LatLng(25.4, 8.4);\nvar mapZoom = 4;";
break;
case 'SOUTH AFRICA':
echo "var mapLatLng = new google.maps.LatLng(-29.0, 23.7);\nvar mapZoom = 5;";
break;
case 'NORTH EUROPE':
echo "var mapLatLng = new google.maps.LatLng(62.6, 15.4);\nvar mapZoom = 4;";
break;
case 'EAST EUROPE':
echo "var mapLatLng = new google.maps.LatLng(51.9, 31.8);\nvar mapZoom = 4;";
break;
case 'GERMANY':
echo "var mapLatLng = new google.maps.LatLng(51.1, 10.1);\nvar mapZoom = 5;";
break;
case 'FRANCE':
echo "var mapLatLng = new google.maps.LatLng(47.2, 2.4);\nvar mapZoom = 5;";
break;
case 'SPAIN':
echo "var mapLatLng = new google.maps.LatLng(40.3, -4.0);\nvar mapZoom = 5;";
break;
case 'UNITED KINGDOM':
echo "var mapLatLng = new google.maps.LatLng(54.0, -4.3);\nvar mapZoom = 5;";
break;
case 'DENMARK':
echo "var mapLatLng = new google.maps.LatLng(56.1, 9.2);\nvar mapZoom = 6;";
break;
case 'SWEDEN':
echo "var mapLatLng = new google.maps.LatLng(63.2, 16.3);\nvar mapZoom = 4;";
break;
case 'NORWAY':
echo "var mapLatLng = new google.maps.LatLng(65.6, 13.1);\nvar mapZoom = 4;";
break;
case 'FINLAND':
echo "var mapLatLng = new google.maps.LatLng(65.1, 26.6);\nvar mapZoom = 4;";
break;
case 'NETHERLANDS':
echo "var mapLatLng = new google.maps.LatLng(52.3, 5.4);\nvar mapZoom = 7;";
break;
case 'BELGIUM':
echo "var mapLatLng = new google.maps.LatLng(50.7, 4.5);\nvar mapZoom = 7;";
break;
case 'SUISSE':
echo "var mapLatLng = new google.maps.LatLng(46.8, 8.2);\nvar mapZoom = 7;";
break;
case 'AUSTRIA':
echo "var mapLatLng = new google.maps.LatLng(47.7, 14.1);\nvar mapZoom = 7;";
break;
case 'POLAND':
echo "var mapLatLng = new google.maps.LatLng(52.1, 19.3);\nvar mapZoom = 6;";
break;
case 'ITALY':
echo "var mapLatLng = new google.maps.LatLng(42.6, 12.7);\nvar mapZoom = 5;";
break;
case 'TURKEY':
echo "var mapLatLng = new google.maps.LatLng(39.0, 34.9);\nvar mapZoom = 6;";
break;
case 'ROMANIA':
echo "var mapLatLng = new google.maps.LatLng(45.94, 24.96);\nvar mapZoom = 6;";
break;
case 'BRAZIL':
echo "var mapLatLng = new google.maps.LatLng(-12.0, -53.1);\nvar mapZoom = 4;";
break;
case 'ARGENTINA':
echo "var mapLatLng = new google.maps.LatLng(-34.3, -65.7);\nvar mapZoom = 3;";
break;
case 'RUSSIA':
echo "var mapLatLng = new google.maps.LatLng(65.7, 98.8);\nvar mapZoom = 3;";
break;
case 'ASIA':
echo "var mapLatLng = new google.maps.LatLng(20.4, 95.6);\nvar mapZoom = 3;";
break;
case 'CHINA':
echo "var mapLatLng = new google.maps.LatLng(36.2, 104.0);\nvar mapZoom = 4;";
break;
case 'JAPAN':
echo "var mapLatLng = new google.maps.LatLng(36.2, 136.8);\nvar mapZoom = 5;";
break;
case 'SOUTH KOREA':
echo "var mapLatLng = new google.maps.LatLng(36.6, 127.8);\nvar mapZoom = 6;";
break;
case 'TAIWAN':
echo "var mapLatLng = new google.maps.LatLng(23.6, 121);\nvar mapZoom = 7;";
break;
case 'AUSTRALIA':
echo "var mapLatLng = new google.maps.LatLng(-26.1, 134.8);\nvar mapZoom = 4;";
break;
case 'CANADA':
echo "var mapLatLng = new google.maps.LatLng(60.0, -97.0);\nvar mapZoom = 3;";
break;
case 'WORLD':
echo "var mapLatLng = new google.maps.LatLng(25.0, 8.5);\nvar mapZoom = 2;";
break;
default:
echo "var mapLatLng = new google.maps.LatLng(48.8, 8.5);\nvar mapZoom = 3;";
break;
}
echo "\n";
}
function printMapType($maptype)
{
switch (strtoupper($maptype))
{
case 'SATELLITE':
echo 'var mapType = google.maps.MapTypeId.SATELLITE;';
break;
case 'MAP':
echo 'var mapType = google.maps.MapTypeId.ROADMAP;';
break;
case 'HYBRID':
echo 'var mapType = google.maps.MapTypeId.HYBRID;';
break;
case 'PHYSICAL':
echo 'var mapType = google.maps.MapTypeId.TERRAIN;';
break;
default:
break;
}
echo "\n";
}
?>

View File

@ -0,0 +1,109 @@
/**
* Autocompleter.Request
*
* http://digitarald.de/project/autocompleter/
*
* @version 1.1.2
*
* @license MIT-style license
* @author Harald Kirschner <mail [at] digitarald.de>
* @copyright Author
*/
Autocompleter.Request = new Class({
Extends: Autocompleter,
options: {/*
indicator: null,
indicatorClass: null,
onRequest: $empty,
onComplete: $empty,*/
postData: {},
ajaxOptions: {},
postVar: 'value'
},
query: function(){
var data = $unlink(this.options.postData) || {};
data[this.options.postVar] = this.queryValue;
var indicator = $(this.options.indicator);
if (indicator) indicator.setStyle('display', '');
var cls = this.options.indicatorClass;
if (cls) this.element.addClass(cls);
this.fireEvent('onRequest', [this.element, this.request, data, this.queryValue]);
this.request.send({'data': data});
},
/**
* queryResponse - abstract
*
* Inherated classes have to extend this function and use this.parent()
*/
queryResponse: function() {
var indicator = $(this.options.indicator);
if (indicator) indicator.setStyle('display', 'none');
var cls = this.options.indicatorClass;
if (cls) this.element.removeClass(cls);
return this.fireEvent('onComplete', [this.element, this.request]);
}
});
Autocompleter.Request.JSON = new Class({
Extends: Autocompleter.Request,
initialize: function(el, url, options) {
this.parent(el, options);
this.request = new Request.JSON($merge({
'url': url,
'link': 'cancel'
}, this.options.ajaxOptions)).addEvent('onComplete', this.queryResponse.bind(this));
},
queryResponse: function(response) {
this.parent();
this.update(response);
}
});
Autocompleter.Request.HTML = new Class({
Extends: Autocompleter.Request,
initialize: function(el, url, options) {
this.parent(el, options);
this.request = new Request.HTML($merge({
'url': url,
'link': 'cancel',
'update': this.choices
}, this.options.ajaxOptions)).addEvent('onComplete', this.queryResponse.bind(this));
},
queryResponse: function(tree, elements) {
this.parent();
if (!elements || !elements.length) {
this.hideChoices();
} else {
this.choices.getChildren(this.options.choicesMatch).each(this.options.injectChoice || function(choice) {
var value = choice.innerHTML;
choice.inputValue = value;
this.addChoiceEvents(choice.set('html', this.markQueryValue(value)));
}, this);
this.showChoices();
}
}
});
/* compatibility */
Autocompleter.Ajax = {
Base: Autocompleter.Request,
Json: Autocompleter.Request.JSON,
Xhtml: Autocompleter.Request.HTML
};

View File

@ -0,0 +1,442 @@
/**
* Autocompleter
*
* http://digitarald.de/project/autocompleter/
*
* @version 1.1.2
*
* @license MIT-style license
* @author Harald Kirschner <mail [at] digitarald.de>
* @copyright Author
*/
var Autocompleter = new Class({
Implements: [Options, Events],
options: {/*
onOver: $empty,
onSelect: $empty,
onSelection: $empty,
onShow: $empty,
onHide: $empty,
onBlur: $empty,
onFocus: $empty,*/
minLength: 1,
markQuery: true,
width: 'inherit',
maxChoices: 10,
injectChoice: null,
customChoices: null,
emptyChoices: null,
visibleChoices: true,
className: 'autocompleter-choices',
zIndex: 42,
delay: 400,
observerOptions: {},
fxOptions: {},
autoSubmit: false,
overflow: false,
overflowMargin: 25,
selectFirst: false,
filter: null,
filterCase: false,
filterSubset: false,
forceSelect: false,
selectMode: true,
choicesMatch: null,
multiple: false,
separator: ', ',
separatorSplit: /\s*[,;]\s*/,
autoTrim: false,
allowDupes: false,
cache: true,
relative: false
},
initialize: function(element, options) {
this.element = $(element);
this.setOptions(options);
this.build();
this.observer = new Observer(this.element, this.prefetch.bind(this), $merge({
'delay': this.options.delay
}, this.options.observerOptions));
this.queryValue = null;
if (this.options.filter) this.filter = this.options.filter.bind(this);
var mode = this.options.selectMode;
this.typeAhead = (mode == 'type-ahead');
this.selectMode = (mode === true) ? 'selection' : mode;
this.cached = [];
},
/**
* build - Initialize DOM
*
* Builds the html structure for choices and appends the events to the element.
* Override this function to modify the html generation.
*/
build: function() {
if ($(this.options.customChoices)) {
this.choices = this.options.customChoices;
} else {
this.choices = new Element('ul', {
'class': this.options.className,
'styles': {
'zIndex': this.options.zIndex
}
}).inject(document.body);
this.relative = false;
if (this.options.relative) {
this.choices.inject(this.element, 'after');
this.relative = this.element.getOffsetParent();
}
this.fix = new OverlayFix(this.choices);
}
if (!this.options.separator.test(this.options.separatorSplit)) {
this.options.separatorSplit = this.options.separator;
}
this.fx = (!this.options.fxOptions) ? null : new Fx.Tween(this.choices, $merge({
'property': 'opacity',
'link': 'cancel',
'duration': 200
}, this.options.fxOptions)).addEvent('onStart', Chain.prototype.clearChain).set(0);
this.element.setProperty('autocomplete', 'off')
.addEvent((Browser.Engine.trident || Browser.Engine.webkit) ? 'keydown' : 'keypress', this.onCommand.bind(this))
.addEvent('click', this.onCommand.bind(this, [false]))
.addEvent('focus', this.toggleFocus.create({bind: this, arguments: true, delay: 100}))
.addEvent('blur', this.toggleFocus.create({bind: this, arguments: false, delay: 100}));
},
destroy: function() {
if (this.fix) this.fix.destroy();
this.choices = this.selected = this.choices.destroy();
},
toggleFocus: function(state) {
this.focussed = state;
if (!state) this.hideChoices(true);
this.fireEvent((state) ? 'onFocus' : 'onBlur', [this.element]);
},
onCommand: function(e) {
if (!e && this.focussed) return this.prefetch();
if (e && e.key && !e.shift) {
switch (e.key) {
case 'enter':
if (this.element.value != this.opted) return true;
if (this.selected && this.visible) {
this.choiceSelect(this.selected);
return !!(this.options.autoSubmit);
}
break;
case 'up': case 'down':
if (!this.prefetch() && this.queryValue !== null) {
var up = (e.key == 'up');
this.choiceOver((this.selected || this.choices)[
(this.selected) ? ((up) ? 'getPrevious' : 'getNext') : ((up) ? 'getLast' : 'getFirst')
](this.options.choicesMatch), true);
}
return false;
case 'esc': case 'tab':
this.hideChoices(true);
break;
}
}
return true;
},
setSelection: function(finish) {
var input = this.selected.inputValue, value = input;
var start = this.queryValue.length, end = input.length;
if (input.substr(0, start).toLowerCase() != this.queryValue.toLowerCase()) start = 0;
if (this.options.multiple) {
var split = this.options.separatorSplit;
value = this.element.value;
start += this.queryIndex;
end += this.queryIndex;
var old = value.substr(this.queryIndex).split(split, 1)[0];
value = value.substr(0, this.queryIndex) + input + value.substr(this.queryIndex + old.length);
if (finish) {
var tokens = value.split(this.options.separatorSplit).filter(function(entry) {
return this.test(entry);
}, /[^\s,]+/);
if (!this.options.allowDupes) tokens = [].combine(tokens);
var sep = this.options.separator;
value = tokens.join(sep) + sep;
end = value.length;
}
}
this.observer.setValue(value);
this.opted = value;
if (finish || this.selectMode == 'pick') start = end;
this.element.selectRange(start, end);
this.fireEvent('onSelection', [this.element, this.selected, value, input]);
},
showChoices: function() {
var match = this.options.choicesMatch, first = this.choices.getFirst(match);
this.selected = this.selectedValue = null;
if (this.fix) {
var pos = this.element.getCoordinates(this.relative), width = this.options.width || 'auto';
this.choices.setStyles({
'left': pos.left,
'top': pos.bottom,
'width': (width === true || width == 'inherit') ? pos.width : width
});
}
if (!first) return;
if (!this.visible) {
this.visible = true;
this.choices.setStyle('display', '');
if (this.fx) this.fx.start(1);
this.fireEvent('onShow', [this.element, this.choices]);
}
if (this.options.selectFirst || this.typeAhead || first.inputValue == this.queryValue) this.choiceOver(first, this.typeAhead);
var items = this.choices.getChildren(match), max = this.options.maxChoices;
var styles = {'overflowY': 'hidden', 'height': ''};
this.overflown = false;
if (items.length > max) {
var item = items[max - 1];
styles.overflowY = 'scroll';
styles.height = item.getCoordinates(this.choices).bottom;
this.overflown = true;
};
this.choices.setStyles(styles);
this.fix.show();
if (this.options.visibleChoices) {
var scroll = document.getScroll(),
size = document.getSize(),
coords = this.choices.getCoordinates();
if (coords.right > scroll.x + size.x) scroll.x = coords.right - size.x;
if (coords.bottom > scroll.y + size.y) scroll.y = coords.bottom - size.y;
window.scrollTo(Math.min(scroll.x, coords.left), Math.min(scroll.y, coords.top));
}
},
hideChoices: function(clear) {
if (clear) {
var value = this.element.value;
if (this.options.forceSelect) value = this.opted;
if (this.options.autoTrim) {
value = value.split(this.options.separatorSplit).filter($arguments(0)).join(this.options.separator);
}
this.observer.setValue(value);
}
if (!this.visible) return;
this.visible = false;
if (this.selected) this.selected.removeClass('autocompleter-selected');
this.observer.clear();
var hide = function(){
this.choices.setStyle('display', 'none');
this.fix.hide();
}.bind(this);
if (this.fx) this.fx.start(0).chain(hide);
else hide();
this.fireEvent('onHide', [this.element, this.choices]);
},
prefetch: function() {
var value = this.element.value, query = value;
if (this.options.multiple) {
var split = this.options.separatorSplit;
var values = value.split(split);
var index = this.element.getSelectedRange().start;
var toIndex = value.substr(0, index).split(split);
var last = toIndex.length - 1;
index -= toIndex[last].length;
query = values[last];
}
if (query.length < this.options.minLength) {
this.hideChoices();
} else {
if (query === this.queryValue || (this.visible && query == this.selectedValue)) {
if (this.visible) return false;
this.showChoices();
} else {
this.queryValue = query;
this.queryIndex = index;
if (!this.fetchCached()) this.query();
}
}
return true;
},
fetchCached: function() {
return false;
if (!this.options.cache
|| !this.cached
|| !this.cached.length
|| this.cached.length >= this.options.maxChoices
|| this.queryValue) return false;
this.update(this.filter(this.cached));
return true;
},
update: function(tokens) {
this.choices.empty();
this.cached = tokens;
var type = tokens && $type(tokens);
if (!type || (type == 'array' && !tokens.length) || (type == 'hash' && !tokens.getLength())) {
(this.options.emptyChoices || this.hideChoices).call(this);
} else {
if (this.options.maxChoices < tokens.length && !this.options.overflow) tokens.length = this.options.maxChoices;
tokens.each(this.options.injectChoice || function(token){
var choice = new Element('li', {'html': this.markQueryValue(token)});
choice.inputValue = token;
this.addChoiceEvents(choice).inject(this.choices);
}, this);
this.showChoices();
}
},
choiceOver: function(choice, selection) {
if (!choice || choice == this.selected) return;
if (this.selected) this.selected.removeClass('autocompleter-selected');
this.selected = choice.addClass('autocompleter-selected');
this.fireEvent('onSelect', [this.element, this.selected, selection]);
if (!this.selectMode) this.opted = this.element.value;
if (!selection) return;
this.selectedValue = this.selected.inputValue;
if (this.overflown) {
var coords = this.selected.getCoordinates(this.choices), margin = this.options.overflowMargin,
top = this.choices.scrollTop, height = this.choices.offsetHeight, bottom = top + height;
if (coords.top - margin < top && top) this.choices.scrollTop = Math.max(coords.top - margin, 0);
else if (coords.bottom + margin > bottom) this.choices.scrollTop = Math.min(coords.bottom - height + margin, bottom);
}
if (this.selectMode) this.setSelection();
},
choiceSelect: function(choice) {
if (choice) this.choiceOver(choice);
this.setSelection(true);
this.queryValue = false;
this.hideChoices();
},
filter: function(tokens) {
return (tokens || this.tokens).filter(function(token) {
return this.test(token);
}, new RegExp(((this.options.filterSubset) ? '' : '^') + this.queryValue.escapeRegExp(), (this.options.filterCase) ? '' : 'i'));
},
/**
* markQueryValue
*
* Marks the queried word in the given string with <span class="autocompleter-queried">*</span>
* Call this i.e. from your custom parseChoices, same for addChoiceEvents
*
* @param {String} Text
* @return {String} Text
*/
markQueryValue: function(str) {
return (!this.options.markQuery || !this.queryValue) ? str
: str.replace(new RegExp('(' + ((this.options.filterSubset) ? '' : '^') + this.queryValue.escapeRegExp() + ')', (this.options.filterCase) ? '' : 'i'), '<span class="autocompleter-queried">$1</span>');
},
/**
* addChoiceEvents
*
* Appends the needed event handlers for a choice-entry to the given element.
*
* @param {Element} Choice entry
* @return {Element} Choice entry
*/
addChoiceEvents: function(el) {
return el.addEvents({
'mouseover': this.choiceOver.bind(this, [el]),
'click': this.choiceSelect.bind(this, [el])
});
}
});
var OverlayFix = new Class({
initialize: function(el) {
if (Browser.Engine.trident) {
this.element = $(el);
this.relative = this.element.getOffsetParent();
this.fix = new Element('iframe', {
'frameborder': '0',
'scrolling': 'no',
'src': 'javascript:false;',
'styles': {
'position': 'absolute',
'border': 'none',
'display': 'none',
'filter': 'progid:DXImageTransform.Microsoft.Alpha(opacity=0)'
}
}).inject(this.element, 'after');
}
},
show: function() {
if (this.fix) {
var coords = this.element.getCoordinates(this.relative);
delete coords.right;
delete coords.bottom;
this.fix.setStyles($extend(coords, {
'display': '',
'zIndex': (this.element.getStyle('zIndex') || 1) - 1
}));
}
return this;
},
hide: function() {
if (this.fix) this.fix.setStyle('display', 'none');
return this;
},
destroy: function() {
if (this.fix) this.fix = this.fix.destroy();
}
});
Element.implement({
getSelectedRange: function() {
if (!Browser.Engine.trident) return {start: this.selectionStart, end: this.selectionEnd};
var pos = {start: 0, end: 0};
var range = this.getDocument().selection.createRange();
if (!range || range.parentElement() != this) return pos;
var dup = range.duplicate();
if (this.type == 'text') {
pos.start = 0 - dup.moveStart('character', -100000);
pos.end = pos.start + range.text.length;
} else {
var value = this.value;
var offset = value.length - value.match(/[\n\r]*$/)[0].length;
dup.moveToElementText(this);
dup.setEndPoint('StartToEnd', range);
pos.end = offset - dup.text.length;
dup.setEndPoint('StartToStart', range);
pos.start = offset - dup.text.length;
}
return pos;
},
selectRange: function(start, end) {
if (Browser.Engine.trident) {
var diff = this.value.substr(start, end - start).replace(/\r/g, '').length;
start = this.value.substr(0, start).replace(/\r/g, '').length;
var range = this.createTextRange();
range.collapse(true);
range.moveEnd('character', start + diff);
range.moveStart('character', start);
range.select();
} else {
this.focus();
this.setSelectionRange(start, end);
}
return this;
}
});
/* compatibility */
Autocompleter.Base = Autocompleter;

View File

@ -0,0 +1,69 @@
/**
* Observer - Observe formelements for changes
*
* - Additional code from clientside.cnet.com
*
* @version 1.1
*
* @license MIT-style license
* @author Harald Kirschner <mail [at] digitarald.de>
* @copyright Author
*/
var Observer = new Class({
Implements: [Options, Events],
options: {
periodical: false,
delay: 1000
},
initialize: function(el, onFired, options){
this.element = $(el) || $$(el);
this.addEvent('onFired', onFired);
this.setOptions(options);
this.bound = this.changed.bind(this);
this.resume();
},
changed: function() {
var value = this.element.get('value');
if ($equals(this.value, value)) return;
this.clear();
this.value = value;
this.timeout = this.onFired.delay(this.options.delay, this);
},
setValue: function(value) {
this.value = value;
this.element.set('value', value);
return this.clear();
},
onFired: function() {
this.fireEvent('onFired', [this.value, this.element]);
},
clear: function() {
$clear(this.timeout || null);
return this;
},
pause: function(){
if (this.timer) $clear(this.timer);
else this.element.removeEvent('keyup', this.bound);
return this.clear();
},
resume: function(){
this.value = this.element.get('value');
if (this.options.periodical) this.timer = this.changed.periodical(this.options.periodical, this);
else this.element.addEvent('keyup', this.bound);
return this;
}
});
var $equals = function(obj1, obj2) {
return (obj1 == obj2 || JSON.encode(obj1) == JSON.encode(obj2));
};

View File

@ -0,0 +1,435 @@
/**
* SqueezeBox - Expandable Lightbox
*
* Allows to open various content as modal,
* centered and animated box.
*
* Dependencies: MooTools 1.2
*
* Inspired by
* ... Lokesh Dhakar - The original Lightbox v2
*
* @version 1.1 rc4
*
* @license MIT-style license
* @author Harald Kirschner <mail [at] digitarald.de>
* @copyright Author
*/
var SqueezeBox = {
presets: {
onOpen: $empty,
onClose: $empty,
onUpdate: $empty,
onResize: $empty,
onMove: $empty,
onShow: $empty,
onHide: $empty,
size: {x: 600, y: 450},
sizeLoading: {x: 200, y: 150},
marginInner: {x: 20, y: 20},
marginImage: {x: 50, y: 75},
handler: false,
target: null,
closable: true,
closeBtn: true,
zIndex: 65555,
overlayOpacity: 0.7,
classWindow: '',
classOverlay: '',
overlayFx: {},
resizeFx: {},
contentFx: {},
parse: false, // 'rel'
parseSecure: false,
shadow: true,
document: null,
ajaxOptions: {}
},
initialize: function(presets) {
if (this.options) return this;
this.presets = $merge(this.presets, presets);
this.doc = this.presets.document || document;
this.options = {};
this.setOptions(this.presets).build();
this.bound = {
window: this.reposition.bind(this, [null]),
scroll: this.checkTarget.bind(this),
close: this.close.bind(this),
key: this.onKey.bind(this)
};
this.isOpen = this.isLoading = false;
return this;
},
build: function() {
this.overlay = new Element('div', {
id: 'sbox-overlay',
styles: {display: 'none', zIndex: this.options.zIndex}
});
this.win = new Element('div', {
id: 'sbox-window',
styles: {display: 'none', zIndex: this.options.zIndex + 2}
});
if (this.options.shadow) {
if (Browser.Engine.webkit420) {
this.win.setStyle('-webkit-box-shadow', '0 0 10px rgba(0, 0, 0, 0.7)');
} else if (!Browser.Engine.trident4) {
var shadow = new Element('div', {'class': 'sbox-bg-wrap'}).inject(this.win);
var relay = function(e) {
this.overlay.fireEvent('click', [e]);
}.bind(this);
['n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw'].each(function(dir) {
new Element('div', {'class': 'sbox-bg sbox-bg-' + dir}).inject(shadow).addEvent('click', relay);
});
}
}
this.content = new Element('div', {id: 'sbox-content'}).inject(this.win);
this.closeBtn = new Element('a', {id: 'sbox-btn-close', href: '#'}).inject(this.win);
this.fx = {
overlay: new Fx.Tween(this.overlay, $merge({
property: 'opacity',
onStart: Events.prototype.clearChain,
duration: 250,
link: 'cancel'
}, this.options.overlayFx)).set(0),
win: new Fx.Morph(this.win, $merge({
onStart: Events.prototype.clearChain,
unit: 'px',
duration: 750,
transition: Fx.Transitions.Quint.easeOut,
link: 'cancel',
unit: 'px'
}, this.options.resizeFx)),
content: new Fx.Tween(this.content, $merge({
property: 'opacity',
duration: 250,
link: 'cancel'
}, this.options.contentFx)).set(0)
};
$(this.doc.body).adopt(this.overlay, this.win);
},
assign: function(to, options) {
return ($(to) || $$(to)).addEvent('click', function() {
return !SqueezeBox.fromElement(this, options);
});
},
open: function(subject, options) {
this.initialize();
if (this.element != null) this.trash();
this.element = $(subject) || false;
this.setOptions($merge(this.presets, options || {}));
if (this.element && this.options.parse) {
var obj = this.element.getProperty(this.options.parse);
if (obj && (obj = JSON.decode(obj, this.options.parseSecure))) this.setOptions(obj);
}
this.url = ((this.element) ? (this.element.get('href')) : subject) || this.options.url || '';
this.assignOptions();
var handler = handler || this.options.handler;
if (handler) return this.setContent(handler, this.parsers[handler].call(this, true));
var ret = false;
return this.parsers.some(function(parser, key) {
var content = parser.call(this);
if (content) {
ret = this.setContent(key, content);
return true;
}
return false;
}, this);
},
fromElement: function(from, options) {
return this.open(from, options);
},
assignOptions: function() {
this.overlay.set('class', this.options.classOverlay);
this.win.set('class', this.options.classWindow);
if (Browser.Engine.trident4) this.win.addClass('sbox-window-ie6');
},
close: function(e) {
var stoppable = ($type(e) == 'event');
if (stoppable) e.stop();
if (!this.isOpen || (stoppable && !$lambda(this.options.closable).call(this, e))) return this;
this.fx.overlay.start(0).chain(this.toggleOverlay.bind(this));
this.win.setStyle('display', 'none');
this.fireEvent('onClose', [this.content]);
this.trash();
this.toggleListeners();
this.isOpen = false;
return this;
},
trash: function() {
this.element = this.asset = null;
this.content.empty();
this.options = {};
this.removeEvents().setOptions(this.presets).callChain();
},
onError: function() {
this.asset = null;
this.setContent('string', this.options.errorMsg || 'An error occurred');
},
setContent: function(handler, content) {
if (!this.handlers[handler]) return false;
this.content.className = 'sbox-content-' + handler;
this.applyTimer = this.applyContent.delay(this.fx.overlay.options.duration, this, this.handlers[handler].call(this, content));
if (this.overlay.retrieve('opacity')) return this;
this.toggleOverlay(true);
this.fx.overlay.start(this.options.overlayOpacity);
return this.reposition();
},
applyContent: function(content, size) {
if (!this.isOpen && !this.applyTimer) return;
this.applyTimer = $clear(this.applyTimer);
this.hideContent();
if (!content) {
this.toggleLoading(true);
} else {
if (this.isLoading) this.toggleLoading(false);
this.fireEvent('onUpdate', [this.content], 20);
}
if (content) {
if (['string', 'array'].contains($type(content))) this.content.set('html', content);
else if (!this.content.hasChild(content)) this.content.adopt(content);
}
this.callChain();
if (!this.isOpen) {
this.toggleListeners(true);
this.resize(size, true);
this.isOpen = true;
this.fireEvent('onOpen', [this.content]);
} else {
this.resize(size);
}
},
resize: function(size, instantly) {
this.showTimer = $clear(this.showTimer || null);
var box = this.doc.getSize(), scroll = this.doc.getScroll();
this.size = $merge((this.isLoading) ? this.options.sizeLoading : this.options.size, size);
var to = {
width: this.size.x,
height: this.size.y,
left: (scroll.x + (box.x - this.size.x - this.options.marginInner.x) / 2).toInt(),
top: (scroll.y + (box.y - this.size.y - this.options.marginInner.y) / 2).toInt()
};
this.hideContent();
if (!instantly) {
this.fx.win.start(to).chain(this.showContent.bind(this));
} else {
this.win.setStyles(to).setStyle('display', '');
this.showTimer = this.showContent.delay(50, this);
}
return this.reposition();
},
toggleListeners: function(state) {
var fn = (state) ? 'addEvent' : 'removeEvent';
this.closeBtn[fn]('click', this.bound.close);
this.overlay[fn]('click', this.bound.close);
this.doc[fn]('keydown', this.bound.key)[fn]('mousewheel', this.bound.scroll);
this.doc.getWindow()[fn]('resize', this.bound.window)[fn]('scroll', this.bound.window);
},
toggleLoading: function(state) {
this.isLoading = state;
this.win[(state) ? 'addClass' : 'removeClass']('sbox-loading');
if (state) this.fireEvent('onLoading', [this.win]);
},
toggleOverlay: function(state) {
var full = this.doc.getSize().x;
this.overlay.setStyle('display', (state) ? '' : 'none');
this.doc.body[(state) ? 'addClass' : 'removeClass']('body-overlayed');
if (state) {
this.scrollOffset = this.doc.getWindow().getSize().x - full;
this.doc.body.setStyle('margin-right', this.scrollOffset);
} else {
this.doc.body.setStyle('margin-right', '');
}
},
showContent: function() {
if (this.content.get('opacity')) this.fireEvent('onShow', [this.win]);
this.fx.content.start(1);
},
hideContent: function() {
if (!this.content.get('opacity')) this.fireEvent('onHide', [this.win]);
this.fx.content.cancel().set(0);
},
onKey: function(e) {
switch (e.key) {
case 'esc': this.close(e);
case 'up': case 'down': return false;
}
},
checkTarget: function(e) {
return this.content.hasChild(e.target);
},
reposition: function() {
var size = this.doc.getSize(), scroll = this.doc.getScroll(), ssize = this.doc.getScrollSize();
this.overlay.setStyles({
width: ssize.x + 'px',
height: ssize.y + 'px'
});
this.win.setStyles({
left: (scroll.x + (size.x - this.win.offsetWidth) / 2 - this.scrollOffset).toInt() + 'px',
top: (scroll.y + (size.y - this.win.offsetHeight) / 2).toInt() + 'px'
});
return this.fireEvent('onMove', [this.overlay, this.win]);
},
removeEvents: function(type){
if (!this.$events) return this;
if (!type) this.$events = null;
else if (this.$events[type]) this.$events[type] = null;
return this;
},
extend: function(properties) {
return $extend(this, properties);
},
handlers: new Hash(),
parsers: new Hash()
};
SqueezeBox.extend(new Events($empty)).extend(new Options($empty)).extend(new Chain($empty));
SqueezeBox.parsers.extend({
image: function(preset) {
return (preset || (/\.(?:jpg|png|gif)$/i).test(this.url)) ? this.url : false;
},
clone: function(preset) {
if ($(this.options.target)) return $(this.options.target);
if (this.element && !this.element.parentNode) return this.element;
var bits = this.url.match(/#([\w-]+)$/);
return (bits) ? $(bits[1]) : (preset ? this.element : false);
},
ajax: function(preset) {
return (preset || (this.url && !(/^(?:javascript|#)/i).test(this.url))) ? this.url : false;
},
iframe: function(preset) {
return (preset || this.url) ? this.url : false;
},
string: function(preset) {
return true;
}
});
SqueezeBox.handlers.extend({
image: function(url) {
var size, tmp = new Image();
this.asset = null;
tmp.onload = tmp.onabort = tmp.onerror = (function() {
tmp.onload = tmp.onabort = tmp.onerror = null;
if (!tmp.width) {
this.onError.delay(10, this);
return;
}
var box = this.doc.getSize();
box.x -= this.options.marginImage.x;
box.y -= this.options.marginImage.y;
size = {x: tmp.width, y: tmp.height};
for (var i = 2; i--;) {
if (size.x > box.x) {
size.y *= box.x / size.x;
size.x = box.x;
} else if (size.y > box.y) {
size.x *= box.y / size.y;
size.y = box.y;
}
}
size.x = size.x.toInt();
size.y = size.y.toInt();
this.asset = $(tmp);
tmp = null;
this.asset.width = size.x;
this.asset.height = size.y;
this.applyContent(this.asset, size);
}).bind(this);
tmp.src = url;
if (tmp && tmp.onload && tmp.complete) tmp.onload();
return (this.asset) ? [this.asset, size] : null;
},
clone: function(el) {
if (el) return el.clone();
return this.onError();
},
adopt: function(el) {
if (el) return el;
return this.onError();
},
ajax: function(url) {
var options = this.options.ajaxOptions || {};
this.asset = new Request.HTML($merge({
method: 'get',
evalScripts: false
}, this.options.ajaxOptions)).addEvents({
onSuccess: function(resp) {
this.applyContent(resp);
if (options.evalScripts !== null && !options.evalScripts) $exec(this.asset.response.javascript);
this.fireEvent('onAjax', [resp, this.asset]);
this.asset = null;
}.bind(this),
onFailure: this.onError.bind(this)
});
this.asset.send.delay(10, this.asset, [{url: url}]);
},
iframe: function(url) {
this.asset = new Element('iframe', $merge({
src: url,
frameBorder: 0,
width: this.options.size.x,
height: this.options.size.y
}, this.options.iframeOptions));
if (this.options.iframePreload) {
this.asset.addEvent('load', function() {
this.applyContent(this.asset.setStyle('display', ''));
}.bind(this));
this.asset.setStyle('display', 'none').inject(this.content);
return false;
}
return this.asset;
},
string: function(str) {
return str;
}
});
SqueezeBox.handlers.url = SqueezeBox.handlers.ajax;
SqueezeBox.parsers.url = SqueezeBox.parsers.ajax;
SqueezeBox.parsers.adopt = SqueezeBox.parsers.clone;

View File

@ -0,0 +1,10 @@
window.addEvent('domready', function() {
/**
* You can run this code as first code to set default options
* SqueezeBox.initialize({ ... });
*/
SqueezeBox.assign($$('a[rel=boxed]'));
});

File diff suppressed because one or more lines are too long

835
web/includes/js/syntax.js Normal file
View File

@ -0,0 +1,835 @@
//modified for LivePipe.net, changes also released under the LGPL
/**
* Code Syntax Highlighter.
* Version 1.5
* Copyright (C) 2004-2007 Alex Gorbatchev.
* http://www.dreamprojections.com/syntaxhighlighter/
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
* Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
//
// create namespaces
//
var dp = {
sh :
{
Toolbar : {},
Utils : {},
RegexLib: {},
Brushes : {},
Strings : {
AboutDialog : '<html><head><title>About...</title></head><body class="dp-about"><table cellspacing="0"><tr><td class="copy"><p class="title">dp.SyntaxHighlighter</div><div class="para">Version: {V}</p><p><a href="http://www.dreamprojections.com/syntaxhighlighter/?ref=about" target="_blank">http://www.dreamprojections.com/syntaxhighlighter</a></p>&copy;2004-2007 Alex Gorbatchev.</td></tr><tr><td class="footer"><input type="button" class="close" value="OK" onClick="window.close()"/></td></tr></table></body></html>'
},
ClipboardSwf : null,
Version : '1.5'
}
};
// make an alias
dp.SyntaxHighlighter = dp.sh;
//
// Toolbar functions
//
dp.sh.Toolbar.Commands = {
ExpandSource: {
label: '+ expand source',
check: function(highlighter) { return highlighter.collapse; },
func: function(sender, highlighter)
{
sender.parentNode.removeChild(sender);
highlighter.div.className = highlighter.div.className.replace('collapsed', '');
}
},
// opens a new windows and puts the original unformatted source code inside.
ViewSource: {
label: 'view plain',
func: function(sender, highlighter)
{
var code = highlighter.originalCode.replace(/</g, '&lt;');
var wnd = window.open('', '_blank', 'width=750, height=400, location=0, resizable=1, menubar=0, scrollbars=0');
wnd.document.write('<textarea style="width:99%;height:99%">' + code + '</textarea>');
wnd.document.close();
}
},
// Copies the original source code in to the clipboard. Uses either IE only method or Flash object if ClipboardSwf is set
CopyToClipboard: {
label: 'copy to clipboard',
check: function() { return window.clipboardData != null || dp.sh.ClipboardSwf != null; },
func: function(sender, highlighter)
{
var code = highlighter.originalCode;
if(window.clipboardData)
{
window.clipboardData.setData('text', code);
}
else if(dp.sh.ClipboardSwf != null)
{
var flashcopier = highlighter.flashCopier;
if(flashcopier == null)
{
flashcopier = document.createElement('div');
highlighter.flashCopier = flashcopier;
highlighter.div.appendChild(flashcopier);
}
flashcopier.innerHTML = '<embed src="' + dp.sh.ClipboardSwf + '" FlashVars="clipboard='+encodeURIComponent(code)+'" width="0" height="0" type="application/x-shockwave-flash"></embed>';
}
alert('The code is in your clipboard now');
}
},
// creates an invisible iframe, puts the original source code inside and prints it
PrintSource: {
label: 'print',
func: function(sender, highlighter)
{
var iframe = document.createElement('IFRAME');
var doc = null;
// this hides the iframe
iframe.style.cssText = 'position:absolute;width:0px;height:0px;left:-500px;top:-500px;';
document.body.appendChild(iframe);
doc = iframe.contentWindow.document;
dp.sh.Utils.CopyStyles(doc, window.document);
doc.write('<div class="' + highlighter.div.className.replace('collapsed', '') + ' printing">' + highlighter.div.innerHTML + '</div>');
doc.close();
iframe.contentWindow.focus();
iframe.contentWindow.print();
alert('Printing...');
document.body.removeChild(iframe);
}
},
About: {
label: '?',
func: function(highlighter)
{
var wnd = window.open('', '_blank', 'dialog,width=300,height=150,scrollbars=0');
var doc = wnd.document;
dp.sh.Utils.CopyStyles(doc, window.document);
doc.write(dp.sh.Strings.AboutDialog.replace('{V}', dp.sh.Version));
doc.close();
wnd.focus();
}
}
};
// creates a <div /> with all toolbar links
dp.sh.Toolbar.Create = function(highlighter)
{
var div = document.createElement('DIV');
div.className = 'tools';
for(var name in dp.sh.Toolbar.Commands)
{
var cmd = dp.sh.Toolbar.Commands[name];
if(cmd.check != null && !cmd.check(highlighter))
continue;
div.innerHTML += '<a href="#" onclick="dp.sh.Toolbar.Command(\'' + name + '\',this);return false;">' + cmd.label + '</a>';
}
return div;
}
// executes toolbar command by name
dp.sh.Toolbar.Command = function(name, sender)
{
var n = sender;
while(n != null && n.className.indexOf('dp-highlighter') == -1)
n = n.parentNode;
if(n != null)
dp.sh.Toolbar.Commands[name].func(sender, n.highlighter);
}
// copies all <link rel="stylesheet" /> from 'target' window to 'dest'
dp.sh.Utils.CopyStyles = function(destDoc, sourceDoc)
{
var links = sourceDoc.getElementsByTagName('link');
for(var i = 0; i < links.length; i++)
if(links[i].rel.toLowerCase() == 'stylesheet')
destDoc.write('<link type="text/css" rel="stylesheet" href="' + links[i].href + '"></link>');
}
//
// Common reusable regular expressions
//
dp.sh.RegexLib = {
MultiLineCComments : new RegExp('/\\*[\\s\\S]*?\\*/', 'gm'),
SingleLineCComments : new RegExp('//.*$', 'gm'),
SingleLinePerlComments : new RegExp('#.*$', 'gm'),
DoubleQuotedString : new RegExp('"(?:\\.|(\\\\\\")|[^\\""])*"','g'),
SingleQuotedString : new RegExp("'(?:\\.|(\\\\\\')|[^\\''])*'", 'g')
};
//
// Match object
//
dp.sh.Match = function(value, index, css)
{
this.value = value;
this.index = index;
this.length = value.length;
this.css = css;
}
//
// Highlighter object
//
dp.sh.Highlighter = function()
{
this.noGutter = false;
this.addControls = true;
this.collapse = false;
this.tabsToSpaces = true;
this.wrapColumn = 80;
this.showColumns = true;
}
// static callback for the match sorting
dp.sh.Highlighter.SortCallback = function(m1, m2)
{
// sort matches by index first
if(m1.index < m2.index)
return -1;
else if(m1.index > m2.index)
return 1;
else
{
// if index is the same, sort by length
if(m1.length < m2.length)
return -1;
else if(m1.length > m2.length)
return 1;
}
return 0;
}
dp.sh.Highlighter.prototype.CreateElement = function(name)
{
var result = document.createElement(name);
result.highlighter = this;
return result;
}
// gets a list of all matches for a given regular expression
dp.sh.Highlighter.prototype.GetMatches = function(regex, css)
{
var index = 0;
var match = null;
while((match = regex.exec(this.code)) != null)
this.matches[this.matches.length] = new dp.sh.Match(match[0], match.index, css);
}
dp.sh.Highlighter.prototype.AddBit = function(str, css)
{
if(str == null || str.length == 0)
return;
var span = this.CreateElement('SPAN');
// str = str.replace(/&/g, '&amp;');
str = str.replace(/ /g, '&nbsp;');
str = str.replace(/</g, '&lt;');
// str = str.replace(/&lt;/g, '<');
// str = str.replace(/>/g, '&gt;');
str = str.replace(/\n/gm, '&nbsp;<br>');
// when adding a piece of code, check to see if it has line breaks in it
// and if it does, wrap individual line breaks with span tags
if(css != null)
{
if((/br/gi).test(str))
{
var lines = str.split('&nbsp;<br>');
for(var i = 0; i < lines.length; i++)
{
span = this.CreateElement('SPAN');
span.className = css;
span.innerHTML = lines[i];
this.div.appendChild(span);
// don't add a <BR> for the last line
if(i + 1 < lines.length)
this.div.appendChild(this.CreateElement('BR'));
}
}
else
{
span.className = css;
span.innerHTML = str;
this.div.appendChild(span);
}
}
else
{
span.innerHTML = str;
this.div.appendChild(span);
}
}
// checks if one match is inside any other match
dp.sh.Highlighter.prototype.IsInside = function(match)
{
if(match == null || match.length == 0)
return false;
for(var i = 0; i < this.matches.length; i++)
{
var c = this.matches[i];
if(c == null)
continue;
if((match.index > c.index) && (match.index < c.index + c.length))
return true;
}
return false;
}
dp.sh.Highlighter.prototype.ProcessRegexList = function()
{
for(var i = 0; i < this.regexList.length; i++)
this.GetMatches(this.regexList[i].regex, this.regexList[i].css);
}
dp.sh.Highlighter.prototype.ProcessSmartTabs = function(code)
{
var lines = code.split('\n');
var result = '';
var tabSize = 4;
var tab = '\t';
// This function inserts specified amount of spaces in the string
// where a tab is while removing that given tab.
function InsertSpaces(line, pos, count)
{
var left = line.substr(0, pos);
var right = line.substr(pos + 1, line.length); // pos + 1 will get rid of the tab
var spaces = '';
for(var i = 0; i < count; i++)
spaces += ' ';
return left + spaces + right;
}
// This function process one line for 'smart tabs'
function ProcessLine(line, tabSize)
{
if(line.indexOf(tab) == -1)
return line;
var pos = 0;
while((pos = line.indexOf(tab)) != -1)
{
// This is pretty much all there is to the 'smart tabs' logic.
// Based on the position within the line and size of a tab,
// calculate the amount of spaces we need to insert.
var spaces = tabSize - pos % tabSize;
line = InsertSpaces(line, pos, spaces);
}
return line;
}
// Go through all the lines and do the 'smart tabs' magic.
for(var i = 0; i < lines.length; i++)
result += ProcessLine(lines[i], tabSize) + '\n';
return result;
}
dp.sh.Highlighter.prototype.SwitchToList = function()
{
// thanks to Lachlan Donald from SitePoint.com for this <br/> tag fix.
var html = this.div.innerHTML.replace(/<(br)\/?>/gi, '\n');
var lines = html.split('\n');
if(this.addControls == true)
this.bar.appendChild(dp.sh.Toolbar.Create(this));
// add columns ruler
if(this.showColumns)
{
var div = this.CreateElement('div');
var columns = this.CreateElement('div');
var showEvery = 10;
var i = 1;
while(i <= 150)
{
if(i % showEvery == 0)
{
div.innerHTML += i;
i += (i + '').length;
}
else
{
div.innerHTML += '&middot;';
i++;
}
}
columns.className = 'columns';
columns.appendChild(div);
this.bar.appendChild(columns);
}
for(var i = 0, lineIndex = this.firstLine; i < lines.length - 1; i++, lineIndex++)
{
var li = this.CreateElement('LI');
var span = this.CreateElement('SPAN');
// uses .line1 and .line2 css styles for alternating lines
li.className = (i % 2 == 0) ? 'alt' : '';
span.innerHTML = lines[i] + '&nbsp;';
li.appendChild(span);
this.ol.appendChild(li);
}
this.div.innerHTML = '';
}
dp.sh.Highlighter.prototype.Highlight = function(code)
{
function Trim(str)
{
return str.replace(/^\s*(.*?)[\s\n]*$/g, '$1');
}
function Chop(str)
{
return str.replace(/\n*$/, '').replace(/^\n*/, '');
}
function Unindent(str)
{
var lines = str.split('\n');
var indents = new Array();
var regex = new RegExp('^\\s*', 'g');
var min = 1000;
// go through every line and check for common number of indents
for(var i = 0; i < lines.length && min > 0; i++)
{
if(Trim(lines[i]).length == 0)
continue;
var matches = regex.exec(lines[i]);
if(matches != null && matches.length > 0)
min = Math.min(matches[0].length, min);
}
// trim minimum common number of white space from the begining of every line
if(min > 0)
for(var i = 0; i < lines.length; i++)
lines[i] = lines[i].substr(min);
return lines.join('\n');
}
// This function returns a portions of the string from pos1 to pos2 inclusive
function Copy(string, pos1, pos2)
{
return string.substr(pos1, pos2 - pos1);
}
var pos = 0;
if(code == null)
code = '';
this.originalCode = code;
this.code = Chop(Unindent(code));
this.div = this.CreateElement('DIV');
this.bar = this.CreateElement('DIV');
this.ol = this.CreateElement('OL');
this.matches = new Array();
this.div.className = 'dp-highlighter';
this.div.highlighter = this;
this.bar.className = 'bar';
// set the first line
this.ol.start = this.firstLine;
if(this.CssClass != null)
this.ol.className = this.CssClass;
if(this.collapse)
this.div.className += ' collapsed';
if(this.noGutter)
this.div.className += ' nogutter';
// replace tabs with spaces
if(this.tabsToSpaces == true)
this.code = this.ProcessSmartTabs(this.code);
this.ProcessRegexList();
// if no matches found, add entire code as plain text
if(this.matches.length == 0)
{
this.AddBit(this.code, null);
this.SwitchToList();
this.div.appendChild(this.ol);
return;
}
// sort the matches
this.matches = this.matches.sort(dp.sh.Highlighter.SortCallback);
// The following loop checks to see if any of the matches are inside
// of other matches. This process would get rid of highligted strings
// inside comments, keywords inside strings and so on.
for(var i = 0; i < this.matches.length; i++)
if(this.IsInside(this.matches[i]))
this.matches[i] = null;
// Finally, go through the final list of matches and pull the all
// together adding everything in between that isn't a match.
for(var i = 0; i < this.matches.length; i++)
{
var match = this.matches[i];
if(match == null || match.length == 0)
continue;
this.AddBit(Copy(this.code, pos, match.index), null);
this.AddBit(match.value, match.css);
pos = match.index + match.length;
}
this.AddBit(this.code.substr(pos), null);
this.SwitchToList();
this.div.appendChild(this.bar);
this.div.appendChild(this.ol);
}
dp.sh.Highlighter.prototype.GetKeywords = function(str)
{
return '\\b' + str.replace(/ /g, '\\b|\\b') + '\\b';
}
// highlightes all elements identified by name and gets source code from specified property
dp.sh.HighlightAll = function(name, showGutter /* optional */, showControls /* optional */, collapseAll /* optional */, firstLine /* optional */, showColumns /* optional */)
{
function FindValue()
{
var a = arguments;
for(var i = 0; i < a.length; i++)
{
if(a[i] == null)
continue;
if(typeof(a[i]) == 'string' && a[i] != '')
return a[i] + '';
if(typeof(a[i]) == 'object' && a[i].value != '')
return a[i].value + '';
}
return null;
}
function IsOptionSet(value, list)
{
for(var i = 0; i < list.length; i++)
if(list[i] == value)
return true;
return false;
}
function GetOptionValue(name, list, defaultValue)
{
var regex = new RegExp('^' + name + '\\[(\\w+)\\]$', 'gi');
var matches = null;
for(var i = 0; i < list.length; i++)
if((matches = regex.exec(list[i])) != null)
return matches[1];
return defaultValue;
}
function FindTagsByName(list, name, tagName)
{
var tags = document.getElementsByTagName(tagName);
for(var i = 0; i < tags.length; i++)
if(tags[i].getAttribute('class') == name)
list.push(tags[i]);
}
var elements = [];
var highlighter = null;
var registered = {};
var propertyName = 'innerHTML';
// for some reason IE doesn't find <pre/> by name, however it does see them just fine by tag name...
FindTagsByName(elements, name, 'code');
if(elements.length == 0)
return;
// register all brushes
for(var brush in dp.sh.Brushes)
{
var aliases = dp.sh.Brushes[brush].Aliases;
if(aliases == null)
continue;
for(var i = 0; i < aliases.length; i++)
registered[aliases[i]] = brush;
}
for(var i = 0; i < elements.length; i++)
{
var element = elements[i];
var options = FindValue(
element.attributes['class'], element.className,
element.attributes['language'], element.language
);
var language = '';
if(options == null)
continue;
options = options.split(':');
language = options[0].toLowerCase();
if(registered[language] == null)
continue;
// instantiate a brush
highlighter = new dp.sh.Brushes[registered[language]]();
// hide the original element
element.style.display = 'none';
highlighter.noGutter = (showGutter == null) ? IsOptionSet('nogutter', options) : !showGutter;
highlighter.addControls = (showControls == null) ? !IsOptionSet('nocontrols', options) : showControls;
highlighter.collapse = (collapseAll == null) ? IsOptionSet('collapse', options) : collapseAll;
highlighter.showColumns = (showColumns == null) ? IsOptionSet('showcolumns', options) : showColumns;
// write out custom brush style
//if(highlighter.Style)
// document.write('<style>' + highlighter.Style + '</style>');
// first line idea comes from Andrew Collington, thanks!
highlighter.firstLine = (firstLine == null) ? parseInt(GetOptionValue('firstline', options, 1)) : firstLine;
highlighter.Highlight(element[propertyName]);
highlighter.source = element;
element.parentNode.insertBefore(highlighter.div, element);
}
}
dp.sh.Brushes.Php = function()
{
var funcs = 'abs acos acosh addcslashes addslashes ' +
'array_change_key_case array_chunk array_combine array_count_values array_diff '+
'array_diff_assoc array_diff_key array_diff_uassoc array_diff_ukey array_fill '+
'array_filter array_flip array_intersect array_intersect_assoc array_intersect_key '+
'array_intersect_uassoc array_intersect_ukey array_key_exists array_keys array_map '+
'array_merge array_merge_recursive array_multisort array_pad array_pop array_product '+
'array_push array_rand array_reduce array_reverse array_search array_shift '+
'array_slice array_splice array_sum array_udiff array_udiff_assoc '+
'array_udiff_uassoc array_uintersect array_uintersect_assoc '+
'array_uintersect_uassoc array_unique array_unshift array_values array_walk '+
'array_walk_recursive atan atan2 atanh base64_decode base64_encode base_convert '+
'basename bcadd bccomp bcdiv bcmod bcmul bindec bindtextdomain bzclose bzcompress '+
'bzdecompress bzerrno bzerror bzerrstr bzflush bzopen bzread bzwrite ceil chdir '+
'checkdate checkdnsrr chgrp chmod chop chown chr chroot chunk_split class_exists '+
'closedir closelog copy cos cosh count count_chars date decbin dechex decoct '+
'deg2rad delete ebcdic2ascii echo empty end ereg ereg_replace eregi eregi_replace error_log '+
'error_reporting escapeshellarg escapeshellcmd eval exec exp explode extension_loaded '+
'feof fflush fgetc fgetcsv fgets fgetss file_exists file_get_contents file_put_contents '+
'fileatime filectime filegroup fileinode filemtime fileowner fileperms filesize filetype '+
'floatval flock floor flush fmod fnmatch fopen fpassthru fprintf fputcsv fputs fread fscanf '+
'fseek fsockopen fstat ftell ftok getallheaders getcwd getdate getenv gethostbyaddr gethostbyname '+
'gethostbynamel getimagesize getlastmod getmxrr getmygid getmyinode getmypid getmyuid getopt '+
'getprotobyname getprotobynumber getrandmax getrusage getservbyname getservbyport gettext '+
'gettimeofday gettype glob gmdate gmmktime ini_alter ini_get ini_get_all ini_restore ini_set '+
'interface_exists intval ip2long is_a is_array is_bool is_callable is_dir is_double '+
'is_executable is_file is_finite is_float is_infinite is_int is_integer is_link is_long '+
'is_nan is_null is_numeric is_object is_readable is_real is_resource is_scalar is_soap_fault '+
'is_string is_subclass_of is_uploaded_file is_writable is_writeable mkdir mktime nl2br '+
'parse_ini_file parse_str parse_url passthru pathinfo readlink realpath rewind rewinddir rmdir '+
'round str_ireplace str_pad str_repeat str_replace str_rot13 str_shuffle str_split '+
'str_word_count strcasecmp strchr strcmp strcoll strcspn strftime strip_tags stripcslashes '+
'stripos stripslashes stristr strlen strnatcasecmp strnatcmp strncasecmp strncmp strpbrk '+
'strpos strptime strrchr strrev strripos strrpos strspn strstr strtok strtolower strtotime '+
'strtoupper strtr strval substr substr_compare isset header html_entity_decode trim fclose fwrite urldecode preg_match preg_match_all preg_replace sleep constant defined func_get_args call_user_func call_user_func_array list';
var visibility = 'self final abstract interface public protected private implements extends static const';
var keywords = 'parent and or xor __FILE__ __LINE__ array as break case ' +
'cfunction class continue declare default die do else ' +
'elseif empty enddeclare endfor endforeach endif endswitch endwhile ' +
'for foreach include include_once global if ' +
'new old_function return switch use require require_once ' +
'var while __FUNCTION__ __CLASS__ ' +
'__METHOD__ throw print exit';
this.regexList = [
{ regex: dp.sh.RegexLib.SingleLineCComments, css: 'comment' }, // one line comments
{ regex: dp.sh.RegexLib.MultiLineCComments, css: 'comment' }, // multiline comments
{ regex: dp.sh.RegexLib.DoubleQuotedString, css: 'string' }, // double quoted strings
{ regex: dp.sh.RegexLib.SingleQuotedString, css: 'string' }, // single quoted strings
{ regex: new RegExp('\\$\\w+', 'g'), css: 'vars' }, // variables
{ regex: new RegExp(this.GetKeywords(funcs), 'gmi'), css: 'func' }, // functions
{ regex: new RegExp(this.GetKeywords(visibility), 'gm'), css: 'visibility' }, // visibility
{ regex: new RegExp(this.GetKeywords(keywords), 'gm'), css: 'keyword' }, // keyword
{ regex: new RegExp('function\\s?([a-zA-Z0-9_]+)(?=\\()','g'), css: 'func_dec' }, // function declarations,
{ regex: new RegExp('([0-9]+|true|false|null|TRUE|FALSE|NULL)(?=(;|\\)|\\s|\\,))','g'), css: 'const'} //constants
];
this.CssClass = 'php';
}
dp.sh.Brushes.Php.prototype = new dp.sh.Highlighter();
dp.sh.Brushes.Php.Aliases = ['php'];
dp.sh.Brushes.JScript = function()
{
var keywords = 'abstract boolean break byte case catch char class const continue debugger ' +
'default delete do double else enum export extends final finally float ' +
'for function goto if implements import in instanceof int interface long native ' +
'new package private protected public return short static super switch ' +
'synchronized throw throws transient try typeof var void volatile while with';
var constants = 'true false null TRUE FALSE NULL [0-9]+';
var builtin = 'window document event Object Function Math Array Hash String Date RegExp';
this.regexList = [
{ regex: dp.sh.RegexLib.SingleLineCComments, css: 'comment' }, // one line comments
{ regex: dp.sh.RegexLib.MultiLineCComments, css: 'comment' }, // multiline comments
{ regex: dp.sh.RegexLib.DoubleQuotedString, css: 'string' }, // double quoted strings
{ regex: dp.sh.RegexLib.SingleQuotedString, css: 'string' }, // single quoted strings
{ regex: new RegExp('^\\s*#.*', 'gm'), css: 'preprocessor' }, // preprocessor tags like #region and #endregion
{ regex: new RegExp(this.GetKeywords(keywords), 'gm'), css: 'keyword' }, // keywords
{ regex: new RegExp(this.GetKeywords(builtin), 'gm'), css: 'builtin' }, // builtin
{ regex: new RegExp(this.GetKeywords(constants), 'g'), css: 'constants' }, // constants
{ regex: new RegExp('this(?=(\\.|\\,|\\)))', 'g'), css: '_this' }, // _this,
{ regex: new RegExp('(\\s|\\{|\\,)[a-zA-Z0-9_]+(?=\\s?:\\s?function)', 'gm'), css: 'func_dec' }, // function declaration,
{ regex: new RegExp('on(R(ow(s(inserted|delete)|e(nter|xit))|e(s(ize(start|end)?|et)|adystatechange))|Mouse(o(ut|ver)|down|up|move)|B(efore(cut|deactivate|u(nload|pdate)|p(aste|rint)|editfocus|activate)|lur)|S(croll|top|ubmit|elect(start|ionchange)?)|H(over|elp)|C(hange|ont(extmenu|rolselect)|ut|ellchange|l(ick|ose))|D(eactivate|ata(setc(hanged|omplete)|available)|r(op|ag(start|over|drop|en(ter|d)|leave)?)|blclick)|Unload|P(aste|ropertychange)|Error(update)?|Key(down|up|press)|Focus|Load|A(ctivate|fter(update|print)|bort))','g'),css:'support_property'},
{ regex: new RegExp('(s(h(ift|ow(Mod(elessDialog|alDialog)|Help))|croll(X|By(Pages|Lines)?|Y|To)?|t(op|rike)|i(n|zeToContent|debar|gnText)|ort|u(p|b(str(ing)?)?)|pli(ce|t)|e(nd|t(Re(sizable|questHeader)|M(i(nutes|lliseconds)|onth)|Seconds|Ho(tKeys|urs)|Year|Cursor|Time(out)?|Interval|ZOptions|Date|UTC(M(i(nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(ome|andleEvent)|navigate|c(har(CodeAt|At)|o(s|n(cat|textual|firm)|mpile)|eil|lear(Timeout|Interval)?|a(ptureEvents|ll)|reate(StyleSheet|Popup|EventObject))|t(o(GMTString|S(tring|ource)|U(TCString|pperCase)|Lo(caleString|werCase))|est|a(n|int(Enabled)?))|i(s(NaN|Finite)|ndexOf|talics)|d(isableExternalCapture|ump|etachEvent)|u(n(shift|taint|escape|watch)|pdateCommands)|j(oin|avaEnabled)|p(o(p|w)|ush|lugins.refresh|a(ddings|rse(Int|Float)?)|r(int|ompt|eference))|e(scape|nableExternalCapture|val|lementFromPoint|x(p|ec(Script|Command)?))|valueOf|UTC|queryCommand(State|Indeterm|Enabled|Value)|f(i(nd|le(ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(nt(size|color)|rward)|loor|romCharCode)|watch|l(ink|o(ad|g)|astIndexOf)|a(sin|nchor|cos|t(tachEvent|ob|an(2)?)|pply|lert|b(s|ort))|r(ou(nd|teEvents)|e(size(By|To)|calc|turnValue|place|verse|l(oad|ease(Capture|Events)))|andom)|g(o|et(ResponseHeader|M(i(nutes|lliseconds)|onth)|Se(conds|lection)|Hours|Year|Time(zoneOffset)?|Da(y|te)|UTC(M(i(nutes|lliseconds)|onth)|Seconds|Hours|Da(y|te)|FullYear)|FullYear|A(ttention|llResponseHeaders)))|m(in|ove(B(y|elow)|To(Absolute)?|Above)|ergeAttributes|a(tch|rgins|x))|b(toa|ig|o(ld|rderWidths)|link|ack))(?=\\()','g'),css:'support_method'},
{ regex: new RegExp('(s(ub(stringData|mit)|plitText|e(t(NamedItem|Attribute(Node)?)|lect))|has(ChildNodes|Feature)|namedItem|c(l(ick|o(se|neNode))|reate(C(omment|DATASection|aption)|T(Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(ntityReference|lement)|Attribute))|tabIndex|i(nsert(Row|Before|Cell|Data)|tem)|open|delete(Row|C(ell|aption)|T(Head|Foot)|Data)|focus|write(ln)?|a(dd|ppend(Child|Data))|re(set|place(Child|Data)|move(NamedItem|Child|Attribute(Node)?)?)|get(NamedItem|Element(sBy(Name|TagName)|ById)|Attribute(Node)?)|blur)(?=\\()','g'),css:'support_method'},
{ regex: new RegExp('on(R(ow(s(inserted|delete)|e(nter|xit))|e(s(ize(start|end)?|et)|adystatechange))|Mouse(o(ut|ver)|down|up|move)|B(efore(cut|deactivate|u(nload|pdate)|p(aste|rint)|editfocus|activate)|lur)|S(croll|top|ubmit|elect(start|ionchange)?)|H(over|elp)|C(hange|ont(extmenu|rolselect)|ut|ellchange|l(ick|ose))|D(eactivate|ata(setc(hanged|omplete)|available)|r(op|ag(start|over|drop|en(ter|d)|leave)?)|blclick)|Unload|P(aste|ropertychange)|Error(update)?|Key(down|up|press)|Focus|Load|A(ctivate|fter(update|print)|bort))','g'),css:'support_property'},
{ regex: new RegExp('\\.(s(ystemLanguage|cr(ipts|ollbars|een(X|Y|Top|Left))|t(yle(Sheets)?|atus(Text|bar)?)|ibling(Below|Above)|ource|uffixes|e(curity(Policy)?|l(ection|f)))|h(istory|ost(name)?|as(h|Focus))|y|X(MLDocument|SLDocument)|n(ext|ame(space(s|URI)|Prop))|M(IN_VALUE|AX_VALUE)|c(haracterSet|o(n(structor|trollers)|okieEnabled|lorDepth|mp(onents|lete))|urrent|puClass|l(i(p(boardData)?|entInformation)|osed|asses)|alle(e|r)|rypto)|t(o(olbar|p)|ext(Transform|Indent|Decoration|Align)|ags)|SQRT(1_2|2)|i(n(ner(Height|Width)|put)|ds|gnoreCase)|zIndex|o(scpu|n(readystatechange|Line)|uter(Height|Width)|p(sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(i(splay|alog(Height|Top|Width|Left|Arguments)|rectories)|e(scription|fault(Status|Ch(ecked|arset)|View)))|u(ser(Profile|Language|Agent)|n(iqueID|defined)|pdateInterval)|_content|p(ixelDepth|ort|ersonalbar|kcs11|l(ugins|atform)|a(thname|dding(Right|Bottom|Top|Left)|rent(Window|Layer)?|ge(X(Offset)?|Y(Offset)?))|r(o(to(col|type)|duct(Sub)?|mpter)|e(vious|fix)))|e(n(coding|abledPlugin)|x(ternal|pando)|mbeds)|v(isibility|endor(Sub)?|Linkcolor)|URLUnencoded|P(I|OSITIVE_INFINITY)|f(ilename|o(nt(Size|Family|Weight)|rmName)|rame(s|Element)|gColor)|E|whiteSpace|l(i(stStyleType|n(eHeight|kColor))|o(ca(tion(bar)?|lName)|wsrc)|e(ngth|ft(Context)?)|a(st(M(odified|atch)|Index|Paren)|yer(s|X)|nguage))|a(pp(MinorVersion|Name|Co(deName|re)|Version)|vail(Height|Top|Width|Left)|ll|r(ity|guments)|Linkcolor|bove)|r(ight(Context)?|e(sponse(XML|Text)|adyState))|global|x|m(imeTypes|ultiline|enubar|argin(Right|Bottom|Top|Left))|L(N(10|2)|OG(10E|2E))|b(o(ttom|rder(RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(Color|Image)))','g'),css:'support_property'}
];
this.CssClass = 'javascript';
}
dp.sh.Brushes.JScript.prototype = new dp.sh.Highlighter();
dp.sh.Brushes.JScript.Aliases = ['js', 'jscript', 'javascript'];
dp.sh.Brushes.CSS = function()
{
var keywords = 'ascent azimuth background-attachment background-color background-image background-position ' +
'background-repeat background baseline bbox border-collapse border-color border-spacing border-style border-top ' +
'border-right border-bottom border-left border-top-color border-right-color border-bottom-color border-left-color ' +
'border-top-style border-right-style border-bottom-style border-left-style border-top-width border-right-width ' +
'border-bottom-width border-left-width border-width border bottom cap-height caption-side centerline clear clip color ' +
'content counter-increment counter-reset cue-after cue-before cue cursor definition-src descent direction display ' +
'elevation empty-cells float font-size-adjust font-family font-size font-stretch font-style font-variant font-weight font ' +
'height letter-spacing line-height list-style-image list-style-position list-style-type list-style margin-top ' +
'margin-right margin-bottom margin-left margin marker-offset marks mathline max-height max-width min-height min-width orphans ' +
'outline-color outline-style outline-width outline overflow padding-top padding-right padding-bottom padding-left padding page ' +
'page-break-after page-break-before page-break-inside pause pause-after pause-before pitch pitch-range play-during position ' +
'quotes richness right size slope src speak-header speak-numeral speak-punctuation speak speech-rate stemh stemv stress ' +
'table-layout text-align text-decoration text-indent text-shadow text-transform unicode-bidi unicode-range units-per-em ' +
'vertical-align visibility voice-family volume white-space widows width widths word-spacing x-height z-index important';
var values = 'above absolute all always aqua armenian attr aural auto avoid baseline behind below bidi-override black blink block blue bold bolder '+
'both bottom braille capitalize caption center center-left center-right circle close-quote code collapse compact condensed '+
'continuous counter counters crop cross crosshair cursive dashed decimal decimal-leading-zero default digits disc dotted double '+
'embed embossed e-resize expanded extra-condensed extra-expanded fantasy far-left far-right fast faster fixed format fuchsia '+
'gray green groove handheld hebrew help hidden hide high higher icon inline-table inline inset inside invert italic '+
'justify landscape large larger left-side left leftwards level lighter lime line-through list-item local loud lower-alpha '+
'lowercase lower-greek lower-latin lower-roman lower low ltr marker maroon medium message-box middle mix move narrower '+
'navy ne-resize no-close-quote none no-open-quote no-repeat normal nowrap n-resize nw-resize oblique olive once open-quote outset '+
'outside overline pointer portrait pre print projection purple red relative repeat repeat-x repeat-y rgb ridge right right-side '+
'rightwards rtl run-in screen scroll semi-condensed semi-expanded separate se-resize show silent silver slower slow '+
'small small-caps small-caption smaller soft solid speech spell-out square s-resize static status-bar sub super sw-resize '+
'table-caption table-cell table-column table-column-group table-footer-group table-header-group table-row table-row-group teal '+
'text-bottom text-top thick thin top transparent tty tv ultra-condensed ultra-expanded underline upper-alpha uppercase upper-latin '+
'upper-roman url visible wait white wider w-resize x-fast x-high x-large x-loud x-low x-slow x-small x-soft xx-large xx-small yellow';
var fonts = '[mM]onospace [tT]ahoma [vV]erdana [aA]rial [hH]elvetica [sS]ans-serif [sS]erif';
this.regexList = [
{ regex: dp.sh.RegexLib.MultiLineCComments, css: 'comment' }, // multiline comments
{ regex: dp.sh.RegexLib.DoubleQuotedString, css: 'string' }, // double quoted strings
{ regex: dp.sh.RegexLib.SingleQuotedString, css: 'string' }, // single quoted strings
{ regex: new RegExp('\\#[a-fA-F0-9]{3,6}', 'g'), css: 'color' }, // html colors
{ regex: new RegExp('-?(\\d+)(px|pt|\:|\\s)?', 'g'), css: 'size' }, // size specifications
{ regex: new RegExp(this.GetKeywords(keywords), 'gm'), css: 'keyword' }, // keywords
{ regex: new RegExp(this.GetKeywords(values), 'g'), css: 'value' }, // values
{ regex: new RegExp(this.GetKeywords(fonts), 'g'), css: 'fonts' }, // fonts
{ regex: new RegExp('(^|\n)[\\s\\#\\._\\-a-zA-Z0-9\\,\\*]+[\\s\\n]*(?=\\{)','gm'),css:'rule'}
];
this.CssClass = 'css';
}
dp.sh.Brushes.CSS.prototype = new dp.sh.Highlighter();
dp.sh.Brushes.CSS.Aliases = ['css'];
Event.observe(window,'load',function(){
dp.sh.HighlightAll('javascript',false,false,false,true,false);
dp.sh.HighlightAll('css',false,false,false,true,false);
dp.sh.HighlightAll('php',false,false,false,true,false);
//dp.sh.HighlightAll = function(name, showGutter /* optional */, showControls /* optional */, collapseAll /* optional */, firstLine /* optional */, showColumns /* optional */)
});

93
web/includes/js/tabs.js Normal file
View File

@ -0,0 +1,93 @@
var Tabs = new Class({
Implements: Options,
togglers: [],
elements: [],
currentRequest: false,
options: {
'defaultTab': false,
'loadingImage': false,
'game': null,
'mode': null,
'extra': []
},
initialize: function(container, togglers, options) {
this.setOptions(options);
this.container = $(container);
$splat(togglers).map(this.addTab, this);
},
addTab: function(toggler) {
this.togglers.include(toggler);
toggler.addEvent('click', this.loadTab.bind(this, [toggler, this.togglers.indexOf(toggler)]));
if ( toggler.id.replace(/^tab_/, '') == this.options.defaultTab )
{
this.loadTab(toggler, this.togglers.indexOf(toggler));
}
},
updateTab: function(txt) {
$(this.loading).destroy();
this.elements[this.currentRequest.options.currentTab] = new Element('div').set('html', txt).injectInside(this.container);
//Evaluate the response AFTER it's been created
txt.stripScripts(true);
this.currentRequest = false;
},
refreshTab: function(change) {
this.options.extra = $merge(this.options.extra, change);
for ( i=0; i<this.togglers.length; i++)
{
if ( this.togglers[i].id.replace(/^tab_/, '') == this.currentTab )
{
this.elements[i].destroy();
this.loadTab(this.togglers[i], i);
return;
}
}
},
loadTab: function(toggler, idx) {
// chrome has its own version of .bind() which passes the values as an array rather than arguments
// so we only want to do this if we don't have normal looking parameters
if(typeof toggler == 'object' && typeof idx != 'number') {
idx = toggler[1];
toggler = toggler[0];
}
var tab = toggler.id.replace(/^tab_/, '');
//Current tab? Just return
if ( this.currentTab == tab && this.container.hasChild(this.elements[idx]) )
return;
//Set the current tab
for ( i=0; i<this.togglers.length; i++) this.togglers[i].set('class', '');
toggler.set('class', 'active');
this.currentTab = tab;
//Current Request? Lets cancel it
if ( $chk(this.currentRequest) )
{
if ( $chk(this.loading) )
this.loading.destroy();
this.currentRequest.cancel();
}
//Hide the current Tabs
$(this.container).getChildren().each(function(el){
el.setStyle('display', 'none');
});
//Have we already cached this tab?
if ( this.container.hasChild(this.elements[idx]) )
{
this.elements[idx].setStyle('display', 'block');
return;
}
//Create the loading image (May change in the future)
this.loading = new Element('div').set('html', '<br /><br /><center><b>Loading...</b><br /><img src="' + this.options.loadingImage + '" alt="Loading..." /></center>').injectInside($(this.container));
//AJAX FTW
this.currentRequest = new Request({
url: 'hlstats.php?mode=' + this.options.mode + '&type=ajax&game=' + this.options.game + '&tab=' + tab + '&' + Hash.toQueryString(this.options.extra),
currentTab: idx,
onSuccess: this.updateTab.bind(this)
}).send();
}
});

View File

@ -0,0 +1,119 @@
<?php
/*
pCache - Faster renderding using data cache
Copyright (C) 2008 Jean-Damien POGOLOTTI
Version 1.1.2 last updated on 06/17/08
http://pchart.sourceforge.net
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 1,2,3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Class initialisation :
pCache($CacheFolder="Cache/")
Cache management :
IsInCache($Data)
GetFromCache($ID,$Data)
WriteToCache($ID,$Data,$Picture)
DeleteFromCache($ID,$Data)
ClearCache()
Inner functions :
GetHash($ID,$Data)
*/
/* pCache class definition */
class pCache
{
var $HashKey = "";
var $CacheFolder = "Cache/";
/* Create the pCache object */
function pCache($CacheFolder="Cache/")
{
$this->CacheFolder = $CacheFolder;
}
/* This function is clearing the cache folder */
function ClearCache()
{
if ($handle = opendir($this->CacheFolder))
{
while (false !== ($file = readdir($handle)))
{
if ( $file != "." && $file != ".." )
unlink($this->CacheFolder.$file);
}
closedir($handle);
}
}
/* This function is checking if we have an offline version of this chart */
function IsInCache($ID,$Data,$Hash="")
{
if ( $Hash == "" )
$Hash = $this->GetHash($ID,$Data);
if ( file_exists($this->CacheFolder.$Hash) )
return(TRUE);
else
return(FALSE);
}
/* This function is making a copy of drawn chart in the cache folder */
function WriteToCache($ID,$Data,$Picture)
{
$Hash = $this->GetHash($ID,$Data);
$FileName = $this->CacheFolder.$Hash;
imagepng($Picture->Picture,$FileName);
}
/* This function is removing any cached copy of this chart */
function DeleteFromCache($ID,$Data)
{
$Hash = $this->GetHash($ID,$Data);
$FileName = $this->CacheFolder.$Hash;
if ( file_exists($FileName ) )
unlink($FileName);
}
/* This function is retrieving the cached picture if applicable */
function GetFromCache($ID,$Data)
{
$Hash = $this->GetHash($ID,$Data);
if ( $this->IsInCache("","",$Hash ) )
{
$FileName = $this->CacheFolder.$Hash;
header('Content-type: image/png');
@readfile($FileName);
exit();
}
}
/* This function is building the graph unique hash key */
function GetHash($ID,$Data)
{
$mKey = "$ID";
foreach($Data as $key => $Values)
{
$tKey = "";
foreach($Values as $Serie => $Value)
$tKey = $tKey.$Serie.$Value;
$mKey = $mKey.md5($tKey);
}
return(md5($mKey));
}
}
?>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,260 @@
<?php
/*
pData - Simplifying data population for pChart
Copyright (C) 2008 Jean-Damien POGOLOTTI
Version 1.13 last updated on 08/17/08
http://pchart.sourceforge.net
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 1,2,3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Class initialisation :
pData()
Data populating methods :
ImportFromCSV($FileName,$Delimiter=",",$DataColumns=-1,$HasHeader=FALSE,$DataName=-1)
AddPoint($Value,$Serie="Serie1",$Description="")
Series manipulation methods :
AddSerie($SerieName="Serie1")
AddAllSeries()
RemoveSerie($SerieName="Serie1")
SetAbsciseLabelSerie($SerieName = "Name")
SetSerieName($Name,$SerieName="Serie1")
+ SetSerieSymbol($Name,$Symbol)
SetXAxisName($Name="X Axis")
SetYAxisName($Name="Y Axis")
SetXAxisFormat($Format="number")
SetYAxisFormat($Format="number")
SetXAxisUnit($Unit="")
SetYAxisUnit($Unit="")
removeSerieName($SerieName)
removeAllSeries()
Data retrieval methods :
GetData()
GetDataDescription()
*/
/* pData class definition */
class pData
{
var $Data;
var $DataDescription;
function pData()
{
$this->Data = "";
$this->DataDescription = "";
$this->DataDescription["Position"] = "Name";
$this->DataDescription["Format"]["X"] = "number";
$this->DataDescription["Format"]["Y"] = "number";
$this->DataDescription["Unit"]["X"] = NULL;
$this->DataDescription["Unit"]["Y"] = NULL;
}
function ImportFromCSV($FileName,$Delimiter=",",$DataColumns=-1,$HasHeader=FALSE,$DataName=-1)
{
$handle = @fopen($FileName,"r");
if ($handle)
{
$HeaderParsed = FALSE;
while (!feof($handle))
{
$buffer = fgets($handle, 4096);
$buffer = str_replace(chr(10),"",$buffer);
$buffer = str_replace(chr(13),"",$buffer);
$Values = split($Delimiter,$buffer);
if ( $buffer != "" )
{
if ( $HasHeader == TRUE && $HeaderParsed == FALSE )
{
if ( $DataColumns == -1 )
{
$ID = 1;
foreach($Values as $key => $Value)
{ $this->SetSerieName($Value,"Serie".$ID); $ID++; }
}
else
{
$SerieName = "";
foreach($DataColumns as $key => $Value)
$this->SetSerieName($Values[$Value],"Serie".$Value);
}
$HeaderParsed = TRUE;
}
else
{
if ( $DataColumns == -1 )
{
$ID = 1;
foreach($Values as $key => $Value)
{ $this->AddPoint(intval($Value),"Serie".$ID); $ID++; }
}
else
{
$SerieName = "";
if ( $DataName != -1 )
$SerieName = $Values[$DataName];
foreach($DataColumns as $key => $Value)
$this->AddPoint($Values[$Value],"Serie".$Value,$SerieName);
}
}
}
}
fclose($handle);
}
}
function AddPoint($Value,$Serie="Serie1",$Description="")
{
if (is_array($Value) && count($Value) == 1)
$Value = $Value[0];
$ID = 0;
for($i=0;$i<=count($this->Data);$i++)
{ if(isset($this->data[$i][$Serie])) { $ID = $i+1; } }
if ( count($Value) == 1 )
{
$this->Data[$ID][$Serie] = $Value;
if ( $Description != "" )
$this->Data[$ID]["Name"] = $Description;
elseif (!isset($this->Data[$ID]["Name"]))
$this->Data[$ID]["Name"] = $ID;
}
else
{
foreach($Value as $key => $Val)
{
$this->Data[$ID][$Serie] = $Val;
if (!isset($this->Data[$ID]["Name"]))
$this->Data[$ID]["Name"] = $ID;
$ID++;
}
}
}
function AddSerie($SerieName="Serie1")
{
if ( !isset($this->DataDescription["Values"]) )
{
$this->DataDescription["Values"][] = $SerieName;
}
else
{
$Found = FALSE;
foreach($this->DataDescription["Values"] as $key => $Value )
if ( $Value == $SerieName ) { $Found = TRUE; }
if ( !$Found )
$this->DataDescription["Values"][] = $SerieName;
}
}
function AddAllSeries()
{
unset($this->DataDescription["Values"]);
if ( isset($this->Data[0]) )
{
foreach($this->Data[0] as $Key => $Value)
{
if ( $Key != "Name" )
$this->DataDescription["Values"][] = $Key;
}
}
}
function RemoveSerie($SerieName="Serie1")
{
if ( !isset($this->DataDescription["Values"]) )
return(0);
$Found = FALSE;
foreach($this->DataDescription["Values"] as $key => $Value )
{
if ( $Value == $SerieName )
unset($this->DataDescription["Values"][$key]);
}
}
function SetAbsciseLabelSerie($SerieName = "Name")
{
$this->DataDescription["Position"] = $SerieName;
}
function SetSerieName($Name,$SerieName="Serie1")
{
$this->DataDescription["Description"][$SerieName] = $Name;
}
function SetXAxisName($Name="X Axis")
{
$this->DataDescription["Axis"]["X"] = $Name;
}
function SetYAxisName($Name="Y Axis")
{
$this->DataDescription["Axis"]["Y"] = $Name;
}
function SetXAxisFormat($Format="number")
{
$this->DataDescription["Format"]["X"] = $Format;
}
function SetYAxisFormat($Format="number")
{
$this->DataDescription["Format"]["Y"] = $Format;
}
function SetXAxisUnit($Unit="")
{
$this->DataDescription["Unit"]["X"] = $Unit;
}
function SetYAxisUnit($Unit="")
{
$this->DataDescription["Unit"]["Y"] = $Unit;
}
function SetSerieSymbol($Name,$Symbol)
{
$this->DataDescription["Symbol"][$Name] = $Symbol;
}
function removeSerieName($SerieName)
{
if ( isset($this->DataDescription["Description"][$SerieName]) )
unset($this->DataDescription["Description"][$SerieName]);
}
function removeAllSeries()
{
foreach($this->DataDescription["Values"] as $Key => $Value)
unset($this->DataDescription["Values"][$Key]);
}
function GetData()
{
return($this->Data);
}
function GetDataDescription()
{
return($this->DataDescription);
}
}
?>