Turnierverwaltung
am 15.08.2008 - 17:29 Uhr in
Ich versuche eine Turnierverwaltung von offline (access) und kopieren in den Nodecontent auf online in Drupal 6.x umzustellen.
Ziel soll sein, dass die berechtigten Vereinsmitglieder die Ergebnisse ihrer Partien der Vereinsmeisterschaften melden können und aus den Ergebnissen automatisch eine Tabelle generiert wird.
Das Schach-Turnier besteht aus 9 Runden. Ein Sieg (1 oder +) gibt einen Punkt, Remis (½) gibt 0,5 Punkte). Die Paarungen werden per Hand eingegeben.
In MS Access sah das ganze so aus.
Tabelle Paarungen mit folgenden Feldern:
PaarNr (1-xx)
Runde (1-9)
SpNr_weiss (Beziehung zu Tabelle Spieler Feld Spieler_Nr)
ErgNr_weiss (Beziehung zu Tabelle Ergebnisse Feld Ergebnis_Nr)
SpNr_schwarz (Beziehung zu Tabelle Spieler Feld Spieler_Nr, 2. Instanz)
ErgNr_schwarz (Beziehung zu Tabelle Ergebnisse Feld Ergebnis_Nr, 2. Instanz)
Tabelle Spieler mit folgenden Feldern
SpNr (1-20)
Name (Text)
Tabelle Ergebnisse mit folgenden Feldern
Ergebnis_Nr (1,2,3,4,5)
Erg_Text (1;0;½;+;-)
Erg_Wert (1,0;0,0;0,5;1,0;0,0)
Tabelle Runden mit folgenden Feldern
RNr (1-9)
Datum (xx.yy.zz)
In einer ersten Abfrage (paarungen_erg) werden dann die Paarungen und Ergebnisse im Klartext dargestellt, also
Paar_Nr,SpNr_w, Name_w, Ergw_Zeichen, Ergw_Wert, SpNr_s, Name_s, Ergs_Zeichen, Ergs_Wert
Um daraus eine Kreuztabelle mit den erzielten Punkten einschließlich Sortierung herstellen zu können, muss zunächst eine UNION-Abfrage ausgeführt werden (hier der Original sql-Text:
SELECT r as Runde,spw AS SpNr,spieler.spname AS weiss,ergebnisse.ergwert AS punktew,sps AS sNr,spieler_1.spname AS schwarz,ergebnisse_1.ergwert AS punktes, [ergebnisse.ergtext] & " : " & [ergebnisse_1.ergtext] AS erg
FROM paarungen_erg
UNION ALL SELECT r as Runde,sps AS SpNr,spieler_1.spname AS weiss,ergebnisse_1.ergwert AS punktew,spw AS sNr, spieler.spname AS schwarz,ergebnisse.ergwert AS punktes, [ergebnisse_1.ergtext] & " : " & [ergebnisse.ergtext] AS erg
FROM paarungen_erg;),
die unter Umbenennung der Felder doppelte aber umgekehrte (die Datenfelder zu weiss und schwarz werden vertauscht) Datensätze erzeugt und diese an die Original-Werte anhängt
Anschließend erzeugt man eine Kreuztabelle, in deren Abfrage nur noch auf den SpielerA als Zeilenwert , auf die Runden als Spaltenwert und ErgwertA als Summenwert zugegriffen wird. Dabei wird auch eine Spalte Gesamtsumme je Spieler erzeugt. Anschließend kann dann sortiert werden.
In Drupal (aktuell 6.4) bin ich bisher wie folgt vorgegangen:
einen neuen Inhaltstyp „VMSpieler“ erstellt
und die CCK-Felder
Name (daraus wird auch der Node-Titel per Module „Autonodetitles“ und „Token“ generiert
SpielerNr (Integer)
erstellt und 20 Spieler eingegeben
einen neuen Inhaltstyp „VMPaarungen“ erstellt
und die CCK-Felder
Runde (Integer)
PaarNr (Integer)
Spieler_weiss (Nodereference auf den Inhaltstyp „VMSpieler“ als Select-List)
Ergebnis_weiss (Textfeld als Select-List mit allowed Values 1,0,½,+,-
Spieler_schwarz (Nodereference auf den Inhaltstyp „VMSpieler“ als Select-List)
Ergebnis_schwarz (Textfeld als Select-List mit allowed Values 1,0,½,+,-
erstellt sowie Paarungen mit Ergebnissen eingegeben
der Nodetitel der Paarungen wird wieder per „Autonodetitles“ und „Token“ aus den Namen der beiden Spieler generiert (d.h. zusammengesetzt, wichtig für einen exposed Filter in Views, der es ermöglicht nach allen Paarungen eines Spielers zu suchen)
Bis dahin geht alles wunderbar,
die Paarungen werden in Views angezeigt,
von dort kommt man per Link ins Eingabeformular der einzelnen Paarung, usw.
Nur die automatische Erstellung der Tabelle geht natürlich nicht von alleine, obwohl eigentlich die Voraussetzungen dafür da sind.
Die Daten der CCK-Felder der Paarungen werden nämlich in einer eigenen Tabelle der Datenbank gespeichert (content_type_vmpaarungen), ich habe nur keine Ahnung wie man sie ausliest und verarbeitet.
Kann man in Drupal (wohl mit php) ebenfalls eine solche UNION- und Kreuztabellen-Abfrage ausführen ?
Wenn ja wo ?, eigenes Modul, template-Datei ?
Oder alternativ für jeden Spieler einzeln die Nodes abfragen, ggf. weiss und schwarz nacheinander in Schleifen ?
Wie gibt man dann das Ergebnis der Abfrage aus ?
Vielleicht hat das schon jemand von Euch gemacht und eine Lösung parat.
Ansonsten bin ich auch schon für Lösungsansätze dankbar
Trotz intensiver Suche habe ich keine Turnierverwaltung oder ähnliches für Drupal gefunden (Es gibt wohl nur Joomleague früher LMO für Joomla)
- Anmelden oder Registrieren um Kommentare zu schreiben
Ob es etwas gibt, weiß ich
am 15.08.2008 - 17:45 Uhr
Ob es etwas gibt, weiß ich nicht. Aber Du kannst es natürlich in Drupal tun.
Du wirst wahrscheinlich eine neue Seite anzeigen wollen, die die Ergebnisse anzeigt.
Dann ist es sinnvoll ein Modul zu schreiben. Auf die Datenbank kannst Du per SQL zugreifen.
Soweit ein paar Tipps. Da Dir niemand das Modul schreiben wird, ist es angebracht die Handbücher zu lesen, das Modul zu beginnen und dann weiter zu fragen, wo Du hängenbleibst (aber das weißt Du ja alles).
Viele Grüße
Edmund
------
Drupal Migrationen, Modul- und Themeentwicklung, Drupal Hosting - http://www.katp.de
Na gut, dann versuche ich
am 16.08.2008 - 19:17 Uhr
Na gut, dann versuche ich mal einen Anfang.
Ich bitte um Nachsicht hinsichtlich meiner gegen Null tendierenden PHP-Kenntnisse. Den einen oder anderen Lacher muss ich wohl riskieren, um vorwärts zu kommen.
Als Anfang will ich nur die Punktesumme eines einzelnen Spielers ermitteln und in einer Seite ausgeben.
Folgendes habe ich mir ohne Rücksicht auf Syntax überlegt:
<?php
$spnummer=1; //Die Spielernummer setzen
$sppunkte=0; //Die Punkte des Spielers auf 0 setzen
$ergebnis=db_query("select * from {content_type_vmpaarungen}"); //alle Datensätze und Felder der Tabelle auslesen
while($row=db_fetch_array($ergebnis)) { // Schleife für alle gefundenen Zeilen
If $spnummer = field_spweiss_nid { // wenn die Spielernummer für Weiss übereinstimmt
case field_ergw_value=1,+
$pktwert = 1,0 // den Text des Textfeldes in einen Zahlenwert umwandeln
case field_ergw_value=½
$pktwert=0,5
case field_ergw_value=0,-
$pktwert=0,0
end case
§sppunkte=$sppunkte+$pktwert; //die Punkte entsprechend erhöhen
}
If $spnummer = field_spschwarz_nid { //wenn die Spielernummer für Schwarz übereinstimmt
case field_ergs_value=1,+
$pktwert = 1
case field_ergs_value=½ //wie oben
$pktwert=0
case field_ergs_value=0,-
$pktwert=0
end case
§sppunkte=$sppunkte+$pktwert;
}
} //Ende der Schleife
vmspieler[$spnummer][nr]=$spnummer; //die Spielernummer und die Endpunktzahl
vmspieler[$spnummer][punkte]=$sppunkte; //in einem neuen array für die Ausgabe speichern
?>
Vielleicht hat ja jemand Lust und Zeit, dass in einen lauffähigen Code zu verwandeln.
Ich werde es sonst vermutlich erst in Jahren schaffen.
Außerdem stellen sich mir noch folgende Fragen
Wie gebe ich diesen neuen array aus ?
Wo muss ich diesen php-Code reinschreiben ?
Wie kann ich das testen ?
Auf jeden Fall schon mal Dank im voraus !!
Zu folgendem Teil benötige
am 21.08.2008 - 11:27 Uhr
Zu folgendem Teil benötige ich mal Hilfe:
switch ($erg) {
case '1':
$pktwert = 1.0;
break;
case '+':
$pktwert = 1.0;
break;
case '½':
$pktwert = 0.5;
break;
default:
$pktwert = 0.0;
break;
}
Case '½' : ... wird immer ignoriert, d.h. es wird 0 ausgegeben.
Ich vermute, dass es am Sonderzeichen ½ liegt.
Wie kann ich den Fehler beseitigen ?
Außerdem werden 1.0 und 0.0 als 1 und 0 dargestellt, also ohne Punkt und Dezimalstelle.
Wie erreiche die andre Darstellung ?
Lass Dir mit ord($erg)
am 21.08.2008 - 12:12 Uhr
Lass Dir mit ord($erg) (http://de2.php.net/manual/de/function.ord.php) mal den Wert ausgeben. Wenn Du in Drupal bist, funktioniert z.B.
<?php
drupal_set_messsage(ord($erg));
?>
Und Stringformatierungen bekommst Du z.B. mit sprintf (http://de2.php.net/manual/de/function.sprintf.php)
<?php
$formatted = sprintf("%01.1f", $pktwert);
?>
Viele Grüße
Edmund
------
Drupal Migrationen, Modul- und Themeentwicklung, Drupal Hosting - http://www.katp.de
Schau dir doch mal das Video
am 21.08.2008 - 15:02 Uhr
Schau dir doch mal das Video von karens von der Drupalcon 2008 an - sie hat eine Seite, wo Anglerturniere getrackt werden und die Erstellung einer solchen Seite so ziemlich von Anfang bis Ende erklärt.
Das Video und Details gibts hier:
http://www.archive.org/details/DrupalconBoston2008-TrackingEventResultsW...
Vielleicht hilft es dir bei deinem Projekt.
Viele Grüße
Anja
Zunächst vielen Dank für
am 21.08.2008 - 22:14 Uhr
Zunächst vielen Dank für die Antworten
Die Funktion ord() klappt wunderbar, auch wenn ich den Unterschied nicht verstehe.
Das Video will leider nicht bei mir laufen (Fehler von quicktime), schade !!
Auch wenn die Hilfe bisher bescheiden ausgefallen ist, will ich die Gemeinde mal an meinen Fortschritten teilhaben lassen, natürlich in der Hoffnung weiter Hilfestellung zu erhalten:
Den folgenden Code eines Modulversuchs habe ich etwas kommentiert, ich hoffe verständlich genug.
<?php
// $Id: vmtabelle.module,v 6.1-dev 2008/08/19 12:00:00 Micha1111 Exp $
function vmtabelle_all() {
$spielergebnisse = array();
$k = 0;
$pktwert = 0;
$einzelergebnisse = array();
$z = 0;
$sp_alt = 0;
$einzelergebnissepkt = array();
$zpkt = 0;
$sp_altpkt = 0;
$tabelle = array();
$ergebnis=db_query("SELECT field_runde_value AS runde,field_spweiss_nid AS spnr,field_ergw_value AS erg FROM {content_type_vmpaarungen} UNION ALL SELECT field_runde_value AS runde,field_spschwarz_nid AS spnr,field_ergs_value AS erg FROM {content_type_vmpaarungen} ORDER BY spnr ASC, runde ASC");
//damit werden per sql-Abfrage die Ergebnisse je Spieler dargestellt
//vorsortiert nach Spieler und Runde
//Es fehlt noch die Verbindung zum Spielernamen aus der Tabelle content_type_vmspieler (Verbindung über cck-Nodereference-Feld)
while($row=db_fetch_array($ergebnis)) {
//Spielergebnisse je Spieler aus Paarungen
$r = $row['runde'];
$k++;
$sp = $row['spnr'];
$erg = $row['erg'];
switch (ord($erg)) { // erforderlich, weil der Text "½" (für Remis) sich sonst nicht verarbeiten lässt
case '49': //1=49
$pktwert = 1;
break;
case '43': //+=43
$pktwert = 1;
break;
case '194': //½=194 //warum auch immer ??
$pktwert = 0.5;
break;
default:
$pktwert = 0; //0=48, -=45
break;
}
$spielergebnisse[$k][1]= $sp; //nur zur
$spielergebnisse[$k][2]= $r; //Anzeige der Ergebisse
$spielergebnisse[$k][3]= $erg; //und damit die Variablennamen
$spielergebnisse[$k][4]= $pktwert; //kürzer werden
//Ende Spielergebnisse je Spieler aus Paarungen
//Tabelle Einzelergebnisse Text je Spieler nach Runden
if ($sp != $sp_altpkt) { //ermitteln, ob es sich um einen neuen Spieler handelt
$s = 0;
$z++;
$sp_altpkt = $sp;
$einzelergebnisse[$z][$s] = $sp; //neuer Spieler in eine neue Zeile der Spalte 0
if ($r == 1) { //wenn es sich um die 1. Runde handelt
$s = $r;
$einzelergebnisse[$z][$s] = $erg; //kommt das Ergebnis in Spalte 1
}
else {
for ($s = 1;$s<$r;$s++) { //sonst für jede fehlende Runde ein Platzhalter
$einzelergebnisse[$z][$s] = 'X'; //da auch Spieler nachträglich, z.B. ab Runde 2
} //einsteigen können
$s = $r;
$einzelergebnisse[$z][$s] = $erg; //Ergebnis in Spalte des Einstiegs
}
}
else {
$einzelergebnisse[$z][$r] = $erg; //sonst kommt das Ergebnis in die Spalte der Runde
}
//Ende Tabelle Einzelergebnisse Text je Spieler nach Runden
//Tabelle Einzelergebnisse Punkte je Spieler nach Runden //da das Ergebnis in Textform gespeichert ist
if ($sp != $sp_alt) { //muss ein gesondertes array mit Zahlenwerten
$summe = 0; //erzeugt werden
$summe_alt = 0;
$spkt = 0;
$zpkt++;
$sp_alt = $sp;
$einzelergebnissepkt[$zpkt][$spkt] = $sp;
$tabelle[$zpkt][0]= $sp;
if ($r == 1) {
$spkt = $r;
$einzelergebnissepkt[$zpkt][$spkt] = $pktwert; //wie oben mit den Zahlenwerten
}
else {
for ($spkt = 1;$spkt<$r;$spkt++) {
$einzelergebnissepkt[$zpkt][$spkt] = 'X';
}
$spkt = $r;
$einzelergebnissepkt[$zpkt][$spkt] = $pktwert; //wie oben mit den Zahlenwerten
}
$summe = $summe_alt + $pktwert; //die Punktesumme wird jede Runde erhöht
$summe_alt = $summe;
$tabelle[$zpkt][1]= $summe; //eigentlich gehört die Punktesumme in Spalte 10 des arrays $einzelergebnissepkt bzw. $einzelergebnisse
} //des arrays $einzelergebnissepkt (siehe aber unten)
else {
$einzelergebnissepkt[$zpkt][$r] = $pktwert;
$summe = $summe_alt + $pktwert; //wie oben
$summe_alt = $summe;
$tabelle[$zpkt][1]= $summe;
}
//Ende Tabelle Einzelergebnisse Punkte je Spieler nach Runden
}
//$header = array(SpielerNr,Runde,Ergebnis,Punkte); //für die Kontrollausgabe der Einzelergebnisse
//$header = array(SpNr,R1,R2,R3,R4,R5,R6,R7,R8,R9,Se); //für die Kontrollausgabe der Textwerte der einzelnen Runde
$header = array(SpielerNr,Punkte); //für die Kontrollausgabe der Tabelle
//return theme('table',$header,$einzelergebnissepkt);
return theme('table',$header,$tabelle); //Rückgabe der Tabelle an das Theme, aber mit Problemen
}
function vmtabelle_menu() {
$items = array();
$items['vmtabelle'] = array(
'title' => 'VM Tabelle',
'page callback' => 'vmtabelle_all',
'access arguments' => array('access vmtabelle content'),
'type' => MENU_CALLBACK
);
return $items;
}
Was mir noch fehlt bzw. unklar ist:
1. Die Verbindung zum Spieler in der Tabelle content_type_vmspieler (über cck-nodereference) fehlt noch
vermutlich über eine Änderung der sql-Abfrage herbeiführbar
2. Der Platzhalter für spätere Turniereinsteiger (ich meine X ist nötig, weil sonst die Tabellendarstellung zerrissen wird. Eigentlich müsste auch die Punktesumme in Spalte 10 dargestellt werden, was aber das gleiche Problem hervorruft, wenn Spieler vorzeitig aussteigen, oder noch nicht alle 9 Runden gespielt wurden.
3. Irgendwie muss es doch möglich sein, verschiedene arrays mit einem Modul darzustellen (return-Funktion) und die Tabelle in ein Gerüst mit fester Breite für jede Spalte, egal ob ein Spaltenfeld schon einen Wert besitzt oder nicht, auszugeben
4. Wie kann man ein array (hier besonders das array $tabelle) nach der Punktesumme (also die 2. Spalte) sortiert auszugeben.
Danke im Voraus !!
Gratulation zu den
am 22.08.2008 - 06:09 Uhr
Gratulation zu den Fortschritten! Geht doch!
Du bekommst mehr Antworten, wenn Du "einfachere" Fragen stellst. Mache z.B. für die erste Frage einen neuen Thread auf, zeige nur das SQL-Statement und frag, wie Du da ein CCK Feld vmspieler hinzubekommst. Nur so ein Tipp ;)
zu 1.: benutze jeweils einen LEFT JOIN in den SELECTs, um den Spielernamen hinzuzufügen.
zu 2.: ich (und alle, die dies vielleicht lesen, aber nicht an einer Tunierverwaltung arbeiten), werden nicht tief in Deine Logik einsteigen. Erkläre bitte deutlicher, was Du brauchst, ohne dass man den Code bis ins letzte Verstehen muss.
zu 3.: Du kannst einfach die Teile zusammenhängen (die theme Funktion erzeugt einen String), also
<?php
$table1 = theme(...);
$table2 = theme(...);
return $table1 . $table2;
?>
Dazwischen kannst Du auch noch anderes HTML hängen, etc.
Formatierungen von Spaltenbreiten etc. machst Du mit CSS. Das ist Teil Deines Themes, nicht des Moduls (Du kannst natürlich auch ein CSS-File zu Deinem Modul anlegen, damit ein guter Default besteht).
4.: probiers mal mit usort: http://de.php.net/manual/de/function.usort.php
Viele Grüße
Edmund
------
Drupal Migrationen, Modul- und Themeentwicklung, Drupal Hosting - http://www.katp.de
Also die verschiedenen
am 22.08.2008 - 15:48 Uhr
Also die verschiedenen php-array-Sortierfunktionen erfordern alle eine Tabelle (bzw.) ein array, das Spaltenbezeichnungen hat. So weit ich aber meinen oben dargestellten Code durchblicke, habe ich die arrays durch Angabe der Zeilennummer und Spaltennummer z.B. $tabelle[$zpkt][1]= $summe erzeugt. Damit hat das array noch gar keine Spaltenüberschriften; deshalb wird wohl auch in der return theme() funktion der header als Parameter gesondert hinzugefügt.
Was muss ich ändern ?
Oder geht es auch so ? Wenn ja wie ?
Usort braucht kein
am 22.08.2008 - 16:24 Uhr
Usort braucht kein key/value-Array. Du mußt dafür eine Funktion schreiben, die pro Element (also bei Dir ein Datensatz) entscheidet, was "größer" bedeutet (bei Dir also der Inhalt von Spalte 2).
Viele Grüße
Edmund
------
Drupal Migrationen, Modul- und Themeentwicklung, Drupal Hosting - http://www.katp.de