<?
/**
* ----------------------------------------------------------------
* PHP Lenex 2
*
* Developer : Erwin Kooi
* released at : not yet (testing stage)
* last modified by : Erwin Kooi
* date modified : May 2006
*
* Send me all the bugs you find please
* Copyright (c) 2006 Cyane Dynamic Web Solutions
* Info? Mail to info@cyane.nl
*
* --------------------------------------------------------------
*** Why?
In the Netherlands, until now all swimming events were digitalized using software called "WAS".
For a number of reasons, the Dutch Federation (KNZB) decided that this had to change.
By the beginning of the new season in 2006, all clubs should use "Splash" instead. This Splash
outputs data in the Lenex format.
Ref : http://www.swimrankings.net
To be precicely: Lenex version 2.0
It seems that this is a widely spread and accepted data format for storing info about swimming events.
I was therefore suprised that no one ever implemeted the class structure described in Lenex,
as PHP classes. As webmaster of a regional swimming site, I started this project and hope this
will help allot of people.
*** Status?
I converted the specs to php class files. That's done but not fully tested.
To use the classes, I wrote a file parser that reads a lenex file and constructs the objects for it.
Last of all, I write this file AS AN EXAMPLE how to display some of the data that comes available.
*** Todo
- fix bugs (if any)
- make nice HTML output scripts (I need some help with that too)
*** Usage
- Place this file, together with the parser file (Lenex.reader.php) in a web hosted directory.
- Place all the class files in a subdir of former called "LenexClasses".
- Either locate a lenex file on the internet or put a file in a dir on your own host
- Call the script in your browser with GET or POST args, when using GET, this looks something like
http://www.xxx.yyy/meet_viewer.php?lenex_file=example.lef
The lenex_file argument has to be either a path at the local filesystem, or a URL like
http://www.xxx.yyy/meet_viewer.php?lenex_file=http://www.zzz.xxx/somedir/example.lef
- The script stores the object tree in a session. That's because parsing a file takes some time so
why do this over and over, while storing it in PHP format is much faster. When you don't want this,
use a second agument "session_reset" and give this any value other than 0. For example
http://www.xxx.yyy/meet_viewer.php?lenex_file=example.lef&session_reset=1
This call with parse the lenex file at every request.
*** Download
Download the latest version of this package, including an example file at
http://www.cyane.nl/phplenex2/phplenex2.zip
**/
$outputLanguage="EN";
session_start();
@include_once("dUnzip2.inc.php"); ////http://www.phpclasses.org/browse/package/2495.html
require_once("LenexClasses/LenexDocument.class.php");
if (@$_REQUEST["session_reset"]) {
unset($_SESSION["lenex_data"]);
}
if (@$_SESSION["lenex_data"]) {
$lenexTree =& unserialize($_SESSION["lenex_data"]);
} else {
$filename = @$_REQUEST["lenex_file"];
if (!$filename) {
trigger_error("no lenex data specified");
return;
}
require "Lenex.reader.php";
$reader =& new LenexReader($filename);
$reader->parse();
if ($reader->error>"") return;
$lenexTree =& $reader->result;
$_SESSION["lenex_data"] =& serialize($lenexTree);
}
$tableRow = "<tr><td valign='top'>%s</td><td valign='top'>%s</td></tr>\n";
$tableRow2 = "<tr><td valign='top' colspan='2'>%s</td></tr>\n";
$eventRow = "<tr><td>%s.</td><td>%s m</td><td>%s</td><td>%s</td></tr>\n";
$resultRow = "<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>\n";
$resultTitleRow = "<tr><td colspan='6'>%s</td></tr>\n";
$translation["EN"]["Strokes"]["BACK"]="Backstroke";
$translation["EN"]["Strokes"]["BREAST"]="Breaststyle";
$translation["EN"]["Strokes"]["FLY"]="Fly";
$translation["EN"]["Strokes"]["FREE"]="Freestyle";
$translation["EN"]["Strokes"]["MEDLEY"]="Medley";
$translation["EN"]["Strokes"]["UNKNOWN"]="";
$translation["EN"]["DocInfo"]="General Document Information";
$translation["EN"]["LenexVersion"]="Lenex Version";
$translation["EN"]["DocConstructor"]="Built with";
$translation["EN"]["Contact"]="Contact Information";
$translation["EN"]["Meet"]="Meet";
$translation["EN"]["AgeDate"]="Age Date";
$translation["EN"]["City"]="City";
$translation["EN"]["Nation"]="Nation";
$translation["EN"]["Deadline"]="Deadline";
$translation["EN"]["Organizer"]="Organizer";
$translation["EN"]["Promoter"]="Promoter";
$translation["EN"]["Timing"]="Timing";
$translation["EN"]["Pool"]="Pool";
$translation["EN"]["PointTable"]="Point Table";
$translation["EN"]["PoolNumberOfLanes"]="Number of Lanes";
$translation["EN"]["Name"]="Name";
$translation["EN"]["Email"]="E-mail";
$translation["EN"]["Fax"]="Fax";
$translation["EN"]["Internet"]="Internet";
$translation["EN"]["State"]="State/procvince";
$translation["NL"]["Country"]="Country";
$translation["EN"]["Street"]="Street";
$translation["EN"]["Street2"]="Street2";
$translation["EN"]["Zip"]="Zip";
$translation["EN"]["Phone"]="Phone";
$translation["EN"]["Mobile"]="Mobile";
$translation["EN"]["Session"]="Session";
$translation["EN"]["Date"]="Date";
$translation["EN"]["SessionDayTime"]="Time";
$translation["EN"]["SessionNumber"]="Number";
$translation["EN"]["Events"]="Events";
$translation["EN"]["Boys"]="Boys";
$translation["EN"]["Girls"]="Girls";
$translation["EN"]["Ladies"]="Ladies";
$translation["EN"]["Gentlemen"]="Men";
$translation["EN"]["GenderAll"]="All";
$translation["EN"]["GenderMixed"]="Mixed";
$translation["EN"]["YearAge"]="Years";
$translation["EN"]["Clubs"]="Clubs";
$translation["EN"]["TimeStandards"]="Time Standards";
$translation["EN"]["Course"]="Course";
$translation["EN"]["Results"]="Results";
$translation["EN"]["Club"]="Club";
$translation["EN"]["License"]="License";
$translation["EN"]["SwimTime"]="Swim Time";
$translation["EN"]["Courses"]["SCM"]="25 meter course";
$translation["EN"]["Courses"]["LCM"]="50 meter course";
$translation["NL"]["Strokes"]["BACK"]="Rug";
$translation["NL"]["Strokes"]["BREAST"]="School";
$translation["NL"]["Strokes"]["FLY"]="Vlinder";
$translation["NL"]["Strokes"]["FREE"]="Vrij";
$translation["NL"]["Strokes"]["MEDLEY"]="Wissel";
$translation["NL"]["Strokes"]["UNKNOWN"]="";
$translation["NL"]["DocInfo"]="Algemene documentinformatie";
$translation["NL"]["LenexVersion"]="Lenex Versie";
$translation["NL"]["DocConstructor"]="Samengesteld met";
$translation["NL"]["Contact"]="Contactinformatie";
$translation["NL"]["Meet"]="Ontmoeting";
$translation["NL"]["AgeDate"]="Peildatum voor leeftijd";
$translation["NL"]["City"]="Plaats";
$translation["NL"]["Nation"]="Land";
$translation["NL"]["Deadline"]="Uiterste inschrijfdatum";
$translation["NL"]["Organizer"]="Organisatie";
$translation["NL"]["Promoter"]="Promotor";
$translation["NL"]["Timing"]="Timing";
$translation["NL"]["Pool"]="Zwembad";
$translation["NL"]["PointTable"]="Puntensysteem";
$translation["NL"]["PoolNumberOfLanes"]="Aantal banen";
$translation["NL"]["Name"]="Naam";
$translation["NL"]["Email"]="E-mail";
$translation["NL"]["Fax"]="Fax";
$translation["NL"]["Internet"]="Internet";
$translation["NL"]["State"]="Staat/provincie";
$translation["NL"]["Country"]="Land";
$translation["NL"]["Street"]="Adres";
$translation["NL"]["Street2"]="Adres2";
$translation["NL"]["Zip"]="Postcode";
$translation["NL"]["Phone"]="Telefoon";
$translation["NL"]["Mobile"]="Mobiel";
$translation["NL"]["Session"]="Programma";
$translation["NL"]["Date"]="Datum";
$translation["NL"]["SessionDayTime"]="Aanvang";
$translation["NL"]["SessionNumber"]="Volgnummer";
$translation["NL"]["Events"]="Programmanummers";
$translation["NL"]["Boys"]="Jongens";
$translation["NL"]["Girls"]="Meisjes";
$translation["NL"]["Ladies"]="Dames";
$translation["NL"]["Gentlemen"]="Heren";
$translation["NL"]["GenderAll"]="Allen";
$translation["NL"]["GenderMixed"]="Gemixt";
$translation["NL"]["YearAge"]="Jaar";
$translation["NL"]["Clubs"]="Deelnemende verenigingen";
$translation["NL"]["TimeStandards"]="Limieten";
$translation["NL"]["Course"]="Baanlengte";
$translation["NL"]["Results"]="Uitslagen";
$translation["NL"]["Club"]="Vereniging";
$translation["NL"]["License"]="St.nr.";
$translation["NL"]["SwimTime"]="Eindtijd";
$translation["NL"]["Courses"]["SCM"]="25 meter bad";
$translation["NL"]["Courses"]["LCM"]="50 meter bad";
$strokes_reverse = array(LENEX_SWIMSTYLE_STROKE_FLY=>1,LENEX_SWIMSTYLE_STROKE_BACK=>2,LENEX_SWIMSTYLE_STROKE_BREAST=>3,LENEX_SWIMSTYLE_STROKE_FREE=>4,LENEX_SWIMSTYLE_STROKE_MEDLEY=>5,LENEX_SWIMSTYLE_STROKE_UNKNOWN=>6);
function translate($key) {
global $outputLanguage,$translation;
return $outputLanguage?$translation[$outputLanguage][$key]:$translation["EN"][$key];
}
function boldHtml($s) {
return "<strong>{$s}</strong>";
}
function underlineHtml($s) {
return "<u>{$s}</u>";
}
function inTableHtml($s) {
return "<table>{$s}</table>";
}
function sprintDocumentInfo(&$data) {
global $tableRow,$tableRow2;
return
sprintf ($tableRow2,boldHtml(translate("DocInfo"))) .
sprintf ($tableRow,translate("LenexVersion"),@$data->version) .
sprintf ($tableRow,translate("DocConstructor"),@$data->constructor->toString()) .
sprintf ($tableRow,translate("Contact"),@$data->constructor->contact->toString());
}
function sprintContact(&$contact) {
global $tableRow,$tableRow2;
return
sprintf ($tableRow,translate("Name"),@$contact->name).
(@$contact->street?sprintf ($tableRow,translate("Street"),$contact->street):"").
(@$contact->street2?sprintf ($tableRow,translate("Street2"),$contact->street2):"").
(@$contact->zip?sprintf ($tableRow,translate("Zip"),$contact->zip):"").
(@$contact->city?sprintf ($tableRow,translate("City"),$contact->city):"").
(@$contact->state?sprintf ($tableRow,translate("State"),$contact->state):"").
(@$contact->country?sprintf ($tableRow,translate("Country"),$contact->country):"").
(@$contact->phone?sprintf ($tableRow,translate("Phone"),$contact->phone):"").
(@$contact->fax?sprintf ($tableRow,translate("Fax"),$contact->fax):"").
(@$contact->mobile?sprintf ($tableRow,translate("Mobile"),$contact->mobile):"").
(@$contact->internet?sprintf ($tableRow,translate("Internet"),$contact->internet):"").
(@$contact->email?sprintf ($tableRow,translate("Email"),$contact->email):"");
}
function getAgeGroupGender(&$ageGroup,$gender) {
$agegroupGender="";
if (($ageGroup->ageMin==-1) && ($ageGroup->ageMax==-1)) {
switch ($gender) {
case "M" : return translate("Gentlemen"); break;
case "F" : return translate("Ladies"); break;
case "A" : return translate("GenderAll"); break;
case "X" : return translate("GenderMixed"); break;
}
}
switch ($gender) {
case "M" : $agegroupGender .= translate("Boys"); break;
case "F" : $agegroupGender .= translate("Girls"); break;
case "A" : $agegroupGender .= translate("GenderAll"); break;
case "X" : $agegroupGender .= translate("GenderMixed"); break;
}
if ($ageGroup->name) $agegroupGender.=" ".$ageGroup->name;
if (($ageGroup->ageMin>-1) || ($ageGroup->ageMax>-1)) {
$agegroupGender.=" (";
if ($ageGroup->ageMin==$ageGroup->ageMax) $agegroupGender.=$ageGroup->ageMin; else
if ($ageGroup->ageMin>-1 && $ageGroup->ageMax==-1) $agegroupGender.= ">=".$ageGroup->ageMin; else
if ($ageGroup->ageMin==-1 && $ageGroup->ageMax>-1) $agegroupGender.= "<=".$ageGroup->ageMax; else
$agegroupGender.= $ageGroup->ageMin."-".$ageGroup->ageMax;
$agegroupGender.=" ".translate("YearAge").")";
}
return $agegroupGender;
}
function getEventRow(&$event) {
global $eventRow;
$agegroupGender = "";
if (count($event->ageGroups)>0) {
$sep="";
while (list($k2,$ageGroup) = each ($event->ageGroups)) {
$agegroupGender.=$sep.getAgeGroupGender($ageGroup,$event->gender);
$sep=", ";
}
} else {
switch ($event->gender) {
case "M" : $agegroupGender = translate("Gentlemen"); break;
case "F" : $agegroupGender = translate("Ladies"); break;
case "A" : $agegroupGender = translate("GenderAll"); break;
case "X" : $agegroupGender = translate("GenderMixed"); break;
}
}
$strokes = translate("Strokes");
return sprintf ($eventRow,
$event->eventid,
($event->swimStyle->relayCount>1?$event->swimStyle->relayCount." x ":"").$event->swimStyle->distance,
$strokes[$event->swimStyle->stroke],
$agegroupGender
);
}
function sprintEvents(&$events) {
$result="";
while (list($k,$event) = each ($events)) {
$result.=getEventRow($event);
}
return $result;
}
function sprintMeet(&$meet) {
global $tableRow,$tableRow2;
$courses = translate("Courses");
return
sprintf ($tableRow2,boldHtml(translate("Meet")." ".$meet->toString())) .
sprintf ($tableRow,translate("City"),@$meet->city." (".@$meet->nation.")").
sprintf ($tableRow,translate("Deadline"),@$meet->deadline).
sprintf ($tableRow,translate("Organizer"),@$meet->organizer).
(@$meet->contact?sprintf ($tableRow,translate("Contact"),inTableHtml(sprintContact($meet->contact))):"").
sprintf ($tableRow,translate("Promoter"),@$meet->promoter).
sprintf ($tableRow,translate("Timing"),ucfirst(strtolower(@$meet->timing))).
(@$meet->pool && @$meet->pool->name?sprintf ($tableRow,translate("Pool"),$meet->pool->name):"").
(@$meet->pool && ($l=@$meet->pool->getNumberOfLanes())?sprintf ($tableRow,translate("PoolNumberOfLanes"),$l):"").
sprintf ($tableRow,translate("Course"),@$courses[$meet->course]).
(@$meet->pointTable?sprintf ($tableRow,translate("PointTable"),$meet->pointTable->toString()):"").
(@$meet->agedate?sprintf ($tableRow,translate("AgeDate"),$meet->agedate->toString()):"");
}
function sprintSession(&$session) {
global $tableRow,$tableRow2;
return
sprintf ($tableRow2,boldHtml(translate("Session")." ".$session->toString())).
sprintf ($tableRow,translate("Date"),@$session->date).
sprintf ($tableRow,translate("SessionDayTime"),@$session->dayTime).
sprintf ($tableRow,translate("SessionNumber"),@$session->number).
(@$session->events?sprintf ($tableRow,translate("Events"),inTableHtml(sprintEvents($session->events))):"");
}
function sprintClubs(&$clubs) {
global $tableRow,$tableRow2;
$result=sprintf ($tableRow2,boldHtml(translate("Clubs")));
while (list($k,$club) = each ($clubs)) {
$result.=sprintf ($tableRow,$club->name,@$club->contact?$club->contact->toString():"");
}
return $result;
}
function usortTimestandards($a,$b) {
global $strokes_reverse;
$as = $strokes_reverse[$a->swimStyle->stroke];
$bs = $strokes_reverse[$b->swimStyle->stroke];
if ($as==$bs) {
$ad = $a->swimStyle->distance;
$bd = $b->swimStyle->distance;
return $ad>$bd?1:($ad<$bd?-1:0);
}
return $as>$bs?1:-1;
}
function sprintTSLs(&$tsls) {
global $tableRow,$tableRow2;
$tsRow = "<tr><td>%s m</td><td>%s</td><td>%s</td></tr>\n";
$strokes = translate("Strokes");
$courses = translate("Courses");
$result="";
while (list($k1,$tsl) = each ($tsls)) {
if (count($tsl->timeStandards)<1) continue;
$result.=sprintf ($tableRow2,underlineHtml($tsl->name.", ".$courses[$tsl->course].(@$tsl->ageGroup?", ".getAgeGroupGender($tsl->ageGroup,$tsl->gender):"")));
$temp = $tsl->timeStandards;
usort($temp,"usortTimestandards");
while (list($k2,$timeStandard) = each ($temp)) {
$result.=sprintf ($tsRow,
($timeStandard->swimStyle->relayCount>1?$timeStandard->swimStyle->relayCount." x ":"").$timeStandard->swimStyle->distance,
$strokes[$timeStandard->swimStyle->stroke],
$timeStandard->swimTime
);
}
}
return $result;
}
function usortEventResultData($a,$b) {
if ($a["place"]==-1 && $b["place"]>-1) return 1;
if ($b["place"]==-1 && $a["place"]>-1) return -1;
return $a["place"]>$b["place"]?1:($a["place"]<$b["place"]?-1:0);
}
function sprintEventResults(&$event,&$meet,&$eventResultData) {
global $resultTitleRow,$resultRow;
usort($eventResultData,"usortEventResultData");
$aResults = "";
$title = sprintf ($resultTitleRow,inTableHtml(getEventRow($event)));
$title.= sprintf($resultRow,"",translate("Name"),translate("Club"),translate("License"),translate("SwimTime"),"");
while (list($k,$a)=each($eventResultData)) {
$club=&$meet->clubs[$a["club"]];
$athlete=&$club->athletes[$a["athlete"]];
$result=&$athlete->results[$a["resultIndex"]];
$aResults.=sprintf($resultRow,
($result->place>0?$result->place:""),
$athlete->firstName." ".$athlete->middleName." ".$athlete->namePrefix." ".$athlete->lastName." ",
@$athlete->club?$athlete->club->toString():"",
$athlete->license,
$result->swimTime,
""
);
}
if (strlen($aResults)>0) return $title.$aResults.sprintf($resultTitleRow," "); else return "";
}
function sprintSessionResults(&$session,&$meet,&$resultData) {
global $resultTitleRow;
$result = sprintf($resultTitleRow," ").sprintf ($resultTitleRow,boldHtml(translate("Results")." ".$session->toString()));
reset($session->events);
while (list($k,$event)=each($session->events)) {
if (!@$resultData[$event->eventid] || count($resultData[$event->eventid])<1) continue;
$result.=sprintEventResults($event,$meet,$resultData[$event->eventid]);
}
return $result;
}
function gatherResultData(&$meet) {
$data = array();
reset($meet->clubs);
while (list($k1,$club)=each($meet->clubs)) {
reset($club->athletes);
while (list($k2,$athlete)=each($club->athletes)) {
reset($athlete->results);
while (list($k3,$result)=each($athlete->results)) {
$data[$result->eventid][] = array("club"=>$k1,"athlete"=>$k2,"resultIndex"=>$k3,"place"=>$result->place);
}
}
}
return $data;
}
echo "<table>\n";
echo sprintDocumentInfo($lenexTree);
while (list($key1,$meet)=each($lenexTree->meets)) {
printf($tableRow2," ");
echo sprintMeet($meet);
while (list($key2,$session)=each($meet->sessions)) {
printf($tableRow2," ");
echo sprintSession($session);
}
printf($tableRow2," ");
if (count($meet->clubs)>0) {
echo sprintClubs($meet->clubs);
}
$resultData = gatherResultData($meet);
if (count($resultData)>0) {
$rstring="";
reset($meet->sessions);
while (list($key2,$session)=each($meet->sessions)) {
if (count(@$session->events)<1) continue;
$rstring .= sprintSessionResults($session,$meet,$resultData);
}
printf($tableRow2,inTableHtml($rstring));
}
}
if (count($lenexTree->timeStandardLists)>0) {
printf($tableRow2," ");
printf($tableRow,boldHtml(translate("TimeStandards")),inTableHtml(sprintTSLs($lenexTree->timeStandardLists)));
echo sprintTSLs($lenexTree->timeStandardLists);
}
echo "</table>\n";
?> |