diff --git a/api/config_example.php b/api/config_example.php
index bcd2ceb..585ada0 100644
--- a/api/config_example.php
+++ b/api/config_example.php
@@ -27,13 +27,6 @@
define('DB_TABLE_NEWS', 'news');
define('DB_TABLE_UPDATETIMES', '_updatetimes');
- // PERMISSIONS
- define('PERM_ALL', 0);
- define('PERM_REGISTERED', 1);
- define('PERM_READ', 2);
- define('PERM_WRITE', 4);
- define('PERM_ADMIN', 8);
-
// OUTGOING MAILS - Credentials for outgoing mails
define('MAIL_SMTP_HOST', 'ssl://ostertun.net'); // SMTP Server address
define('MAIL_SMTP_PORT', 465); // port to use
diff --git a/api/functions.php b/api/functions.php
new file mode 100644
index 0000000..a5cc263
--- /dev/null
+++ b/api/functions.php
@@ -0,0 +1,450 @@
+= "' . date('Y-m-d', $from) . '") AND (`date` <= "' . date('Y-m-d', $to) . '") ORDER BY `date`');
+ }
+
+ function get_regatta_years($mysqli) {
+ $query = 'SELECT DISTINCT(YEAR(`date`)) as year FROM ' . BOATCLASS . DB_TABLE_SUFFIX_REGATTAS . ' ORDER BY `date`;';
+ $response = mysqli_query($mysqli, $query);
+
+ if ($response !== false) {
+ $result = array();
+ if ($response->num_rows > 0) {
+ while ($row = $response->fetch_assoc()) {
+ $result[] = $row['year'];
+ }
+ }
+ return $result;
+ } else {
+ logE("functions", "get_data\nInvalid request\n" . $query . "\n" . mysqli_error($mysqli));
+ return false;
+ }
+ }
+
+ function get_result_calculated($mysqli, $regatta_id) {
+ $regatta = get_regatta($mysqli, $regatta_id);
+ if ($regatta === false) {
+ return false;
+ }
+ $results = get_result($mysqli, $regatta_id);
+ if ($results !== false) {
+
+ // *** Replace , with .
+ foreach ($results as $key => $value) {
+ for ($i = 1; $i <= $regatta['races']; $i ++) {
+ $results[$key]['race' . $i] = str_replace(',', '.', $results[$key]['race' . $i]);
+ }
+ }
+
+ // *** Calculation ***
+ $gemeldet = count($results);
+
+ $sortarray = array();
+ foreach ($results as $key => $value) {
+ $results[$key]['finished'] = false;
+ $results[$key]['values'] = array();
+ $results[$key]['values_all'] = array();
+ $results[$key]['texts'] = array();
+ $copy = array();
+ for ($i = 1; $i <= $regatta['races']; $i ++) {
+ if (is_numeric($value['race' . $i])) {
+ $results[$key]['values'][$i] = $value['race' . $i];
+ $results[$key]['texts'][$i] = $value['race' . $i];
+ $copy[$i] = $value['race' . $i];
+ $results[$key]['finished'] = true;
+ } else {
+ switch ($value['race' . $i]) {
+ // Nicht gestartet
+ case 'DNC': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = $gemeldet + 1; break; // Did not come
+ case 'DNS': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = $gemeldet + 1; break; // Did not started
+ // Startfehler
+ case 'OCS': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = $gemeldet + 1; /*$results[$key]['finished'] = true;*/ break; // On course site
+// Muss v. Hand case 'ZFP': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = $gemeldet + 1; $results[$key]['finished'] = true; break; // Z-Flag penalty (20% nach 30.2)
+ case 'UFD': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = $gemeldet + 1; /*$results[$key]['finished'] = true;*/ break; // Uniform Flag Disqualified (disqu. nach 30.3)
+ case 'BFD': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = $gemeldet + 1; /*$results[$key]['finished'] = true;*/ break; // Black Flag Disqualified (disqu. nach 30.4)
+ // Nicht durch Ziel gegangen
+ case 'DNF': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = $gemeldet + 1; break; // Did not finish
+ case 'RET': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = $gemeldet + 1; break; // Retired (Aufgegeben)
+ case 'RAF': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = $gemeldet + 1; /*$results[$key]['finished'] = true;*/ break; // Retired after finish
+ // Disqualifizierun
+ case 'DSQ': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = $gemeldet + 1; /*$results[$key]['finished'] = true;*/ break; // Disqualified
+ case 'DNE': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = -1; /*$results[$key]['finished'] = true;*/ break; // Disqualified, not excludable (disqu. kann nach 90.3(b) nicht gestrichen werden)
+ case 'DGM': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = -2; /*$results[$key]['finished'] = true;*/ break; // Disqualification Gross Missconduct (kann nach 69.1(b)(2) nicht gestr. werden, grobes Fehlverhalten)
+ // Wiedergutmachung
+// Muss v. Hand case 'RDG': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = $gemeldet + 1; $results[$key]['finished'] = true; break; // Redress given (Wiedergutmachung gewährt)
+ // Strafen
+// Muss v. Hand case 'SCP': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = $gemeldet + 1; $results[$key]['finished'] = true; break; // Wertungsstrafe nach 44.3(a) (20%)
+// Muss v. Hand case 'DPI': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = $gemeldet + 1; $results[$key]['finished'] = true; break; // Punktstrafe nach Ermessen der Jury
+ // Unbekannt
+ default: $results[$key]['values'][$i] = 0; $copy[$i] = 0; break;
+ }
+
+ if ($results[$key]['values'][$i] != 0) {
+ $results[$key]['texts'][$i] = $value['race' . $i] . ' (' . $results[$key]['values'][$i] . ')';
+ } else {
+ $results[$key]['texts'][$i] = $value['race' . $i] . ' (Unknown - 0)';
+ }
+ }
+ }
+ $results[$key]['values_all'] = $results[$key]['values'];
+ for ($s = 0; $s < $regatta['streicher']; $s ++) {
+ $max = max($copy);
+ for ($i = 1; $i <= $regatta['races']; $i ++) {
+ if ($copy[$i] == $max) {
+ $copy[$i] = 0;
+ break;
+ }
+ }
+ }
+ $brutto = $netto = 0;
+ for ($i = 1; $i <= $regatta['races']; $i ++) {
+ $brutto += $results[$key]['values_all'][$i];
+ if ($copy[$i] == -1) { $results[$key]['values'][$i] = $gemeldet + 1; }
+ elseif ($copy[$i] == -2) { $results[$key]['values'][$i] = $gemeldet + 1; }
+ else { $results[$key]['values'][$i] = $copy[$i]; }
+ if ($results[$key]['values'][$i] == 0) {
+ $results[$key]['texts'][$i] = '[' . $results[$key]['texts'][$i] . ']';
+ }
+ $netto += $results[$key]['values'][$i];
+ }
+ $results[$key]['brutto'] = $brutto;
+ $results[$key]['netto'] = $netto;
+
+ if ($results[$key]['finished']) {
+ $sortarray[$key] = 0;
+ } else {
+ $sortarray[$key] = 1;
+ }
+ $sortarray[$key] /*.*/= sprintf("%08.2f", $netto);
+ $temp = $results[$key]['values'];
+ sort($temp);
+ $i = 0;
+ foreach ($temp as $val) {
+ if ($i < $regatta['races']) {
+ $sortarray[$key] .= sprintf("%07.2f", $val);
+ }
+ $i ++;
+ }
+ for ($i = $regatta['races']; $i > 0; $i --) {
+ $sortarray[$key] .= sprintf("%07.2f", $results[$key]['values_all'][$i]);
+ }
+ $results[$key]['sortvalue'] = $sortarray[$key];
+ }
+ array_multisort($sortarray, $results);
+ $i = 1;
+ foreach ($results as $key => $value) {
+ if (($i > 1) and ($sortarray[$key] == $sortarray[$lastkey])) {
+ $results[$key]['place'] = $results[$lastkey]['place'];
+ } else {
+ $results[$key]['place'] = $i;
+ }
+ $i ++;
+ $lastkey = $key;
+ }
+ unset ($sortarray);
+
+ return $results;
+ } else {
+ return false;
+ }
+ }
+
+ function update_result_cache($mysqli, $regatta_id) {
+ $regatta = get_regatta($mysqli, $regatta_id);
+ if ($regatta === false) return;
+ $results = get_result_calculated($mysqli, $regatta['id']);
+ if ($results === false) return;
+
+ // count finished boats
+ $fb = 0;
+ foreach ($results as $result) {
+ if ($result['finished']) {
+ $fb ++;
+ }
+ }
+
+ db_update_data($mysqli, BOATCLASS . DB_TABLE_SUFFIX_REGATTAS, ['finishedBoats' => $fb], '`id`="' . $regatta['id'] . '"', 1);
+
+ foreach ($results as $result) {
+ if ($fb == 0) {
+ $rlp = 0;
+ } else {
+ $rlp = 100 * $regatta['rlf'] * (($fb + 1 - $result['place']) / $fb);
+ }
+ db_update_data($mysqli, BOATCLASS . DB_TABLE_SUFFIX_RESULTS, ['place' => $result['place'], 'rlp' => $rlp], '`id`="' . $result['id'] . '"', 1);
+ }
+ }
+
+ function get_ranking($mysqli, $from, $to, $jugend = false, $jugstrict = false) {
+ global $rankNoResults, $_CLASSES;
+ $rankNoResults = array();
+
+ $sailors = get_sailor($mysqli);
+ $regattas = get_regattas_range($mysqli, $from, $to);
+
+ if (($sailors !== false) and ($regattas !== false)) {
+ foreach ($sailors as $key => $sailor) {
+ $sailors[$key]['regattas'] = array();
+ $sailors[$key]['tmp_rlp'] = array();
+ }
+
+ foreach ($regattas as $regatta) {
+ $date = strtotime($regatta['date']);
+
+ // regatta has to be min. 2 days to be ranking-regatta
+ if ($regatta['length'] < 2) {
+ continue;
+ }
+
+ $results = get_result($mysqli, $regatta['id']);
+ if ($results === false) {
+ continue;
+ }
+
+ if (count($results) <= 0) {
+ if (strtotime('+' . ($regatta['length']-1) . ' days', $date) <= time()) {
+ if (!$regatta['canceled']) {
+ $rankNoResults[] = $regatta;
+ }
+ }
+ continue;
+ }
+
+ // in one race there must be at least 10 boats started
+ $ok = false;
+ for ($i = 1; $i <= $regatta['races']; $i ++) {
+ $temp = 0;
+ foreach ($results as $result) {
+ if (($result['race' . $i] != 'DNC') and ($result['race' . $i] != 'DNS')) {
+ $temp ++;
+ }
+ }
+ if ($temp >= 10) {
+ $ok = true;
+ break;
+ }
+ }
+ if (!$ok) {
+ continue;
+ }
+
+ $fb = $regatta['finishedBoats'];
+
+ // add regatta to each sailor
+ foreach ($results as $result) {
+ if ($result['rlp'] == 0) {
+ continue;
+ }
+ // check if crew is youth
+ //if ($jugend) {
+ // $crew = explode(',', $result['crew']);
+ // $okay = true;
+ // foreach ($crew as $sailor) {
+ // if (($sailor == '') or !isset($sailors[$sailor])) continue;
+ // $sailor = $sailors[$sailor];
+ // if ((($sailor['year'] !== null) and ($sailor['year'] < (date('Y', $date) - $_CLASSES[BOATCLASS]['youth-age']))) or
+ // (($sailor['year'] === null) and ($jugstrict))) {
+ // $okay = false;
+ // break;
+ // }
+ // }
+ // if (!$okay) continue;
+ //}
+ // calc m
+ if ($regatta['m'] > 0) {
+ $m = $regatta['m'];
+ } elseif ($regatta['races'] <= 4) {
+ $m = $regatta['races'];
+ } else {
+ if (($regatta['length'] > 2) and ($regatta['races'] >= 6)) {
+ $m = 5;
+ } else {
+ $m = 4;
+ }
+ }
+ $rlp = $result['rlp'];
+ $sailors[$result['steuermann']]['regattas'][$regatta['id']] = array(
+ 'regatta' => $regatta['id'],
+ 'boat' => $result['boat'],
+ 'crew' => $result['crew'],
+ 'place' => $result['place'],
+ 'fb' => $fb,
+ 'rlp' => $rlp,
+ 'used' => 0,
+ 'm' => $m
+ );
+ for ($i = 0; $i < $m; $i ++) {
+ array_push($sailors[$result['steuermann']]['tmp_rlp'], array($regatta['id'], $rlp));
+ }
+ }
+ }
+
+ foreach ($sailors as $key => $sailor) {
+ if ($sailor['german'] == 0) {
+ unset($sailors[$key]);
+ } elseif ($jugend) {
+ if ((($sailor['year'] !== null) and ($sailor['year'] < (date('Y', $to) - $_CLASSES[BOATCLASS]['youth-age']))) or
+ (($sailor['year'] === null) and ($jugstrict))) {
+ unset($sailors[$key]);
+ }
+ }
+ }
+
+ $sortarray = array();
+
+ foreach ($sailors as $key => $sailor) {
+ // sort rlps desc
+ $sort = array();
+ foreach ($sailor['tmp_rlp'] as $key2 => $value) {
+ $sort[$key2] = $value[1];
+ }
+ array_multisort($sort, SORT_DESC, $sailors[$key]['tmp_rlp']);
+ // calc mean. rlp
+ $sum = 0;
+ $cnt = 0;
+ foreach ($sailors[$key]['tmp_rlp'] as $value) {
+ $sum += $value[1];
+ $sailors[$key]['regattas'][$value[0]]['used'] ++;
+ $cnt ++;
+ if ($cnt >= 9) {
+ break;
+ }
+ }
+ unset($sailors[$key]['tmp_rlp']);
+ if ($cnt > 0) {
+ $rlp = $sum / $cnt;
+ $sailors[$key]['rlp'] = $rlp;
+ $sailors[$key]['m'] = $cnt;
+ } else {
+ unset($sailors[$key]);
+ continue;
+ }
+
+ if ($rlp == 0) {
+ $sortarray[$key] = $cnt;
+ } else {
+ $sortarray[$key] = $cnt * 1000 + $rlp;
+ }
+ }
+ array_multisort($sortarray, SORT_DESC, $sailors);
+ unset($sortarray);
+
+ $i = 1;
+ foreach ($sailors as $key => $sailor) {
+ $sailors[$key]['rank'] = $i;
+ $i ++;
+ }
+
+ return $sailors;
+ } else {
+ return false;
+ }
+ }
+
+ function get_trim_boat($mysqli, $id = false) {
+ return get_db_entry($mysqli, DB_TABLE_TRIM_BOATS, $id);
+ }
+
+ function get_trim_boat_users($mysqli, $id) {
+ $result = db_get_data($mysqli, DB_TABLE_TRIM_USERS, '*', '`boat` = "' . mysqli_real_escape_string($mysqli, $id) . '"');
+ if ($result === false)
+ return false;
+ else
+ return $result;
+ }
+
+ function get_trim_user_boats($mysqli, $id) {
+ $boats = db_get_data($mysqli, DB_TABLE_TRIM_USERS, '*', '`user` = "' . mysqli_real_escape_string($mysqli, $id) . '"');
+ if ($boats === false) {
+ return false;
+ } else {
+ $result = [];
+ foreach ($boats as $value) {
+ $result[$value['boat']] = get_trim_boat($mysqli, $value['boat']);
+ }
+ return $result;
+ }
+ }
+
+ function trim_is_boat_user($mysqli, $user, $boat) {
+ $res = db_get_data($mysqli, DB_TABLE_TRIM_USERS, '*', '`user` = "' . mysqli_real_escape_string($mysqli, $user) . '" AND `boat` = "' . mysqli_real_escape_string($mysqli, $boat) . '"');
+ return ($res !== false) and (count($res) == 1);
+ }
+
+ function get_trim_trim($mysqli, $id = false) {
+ return get_db_entry($mysqli, DB_TABLE_TRIM_TRIMS, $id);
+ }
+
+ function get_trim_boat_trims($mysqli, $id) {
+ $result = db_get_data($mysqli, DB_TABLE_TRIM_TRIMS, '*', '`boat` = "' . mysqli_real_escape_string($mysqli, $id) . '"');
+ if ($result === false) {
+ return false;
+ } else {
+ return $result;
+ }
+ }
+
+?>
\ No newline at end of file
diff --git a/api/index.php b/api/index.php
index 4102512..9eb94c3 100644
--- a/api/index.php
+++ b/api/index.php
@@ -5,6 +5,7 @@
require_once(__DIR__ . '/../server/log.php');
require_once(__DIR__ . '/database.php');
require_once(__DIR__ . '/login.php');
+ require_once(__DIR__ . '/functions.php');
$request = false;
if (isset($_GET['request'])) {
@@ -76,15 +77,14 @@
} else {
$user_id = false;
}
- $perm = get_perm($mysqli, $user_id);
- function has_perm($permission) {
- global $perm;
- return ($perm & $permission) == $permission;
+ function isLoggedIn() {
+ global $user_id;
+ return $user_id !== false;
}
- function checkPermission($perm) {
- if (!has_perm($perm)) done(DONE_UNAUTHORIZED, ['error' => 'permission denied']);
+ function checkLoggedIn() {
+ if (!isLoggedIn()) done(DONE_UNAUTHORIZED, ['error' => 'permission denied']);
}
function checkRequest($param) {
@@ -98,6 +98,35 @@
}, $array);
}
+ $whereString = false;
+ if (isset($_REQUEST['index'], $_REQUEST['value'])) {
+ $whereString = '`' . mysqli_real_escape_string($mysqli, $_REQUEST['index']) . '`="' . mysqli_real_escape_string($mysqli, $_REQUEST['value']) . '"';
+ }
+
+ function sendEntries($table) {
+ global $mysqli, $whereString;
+ $response = db_get_data($mysqli, $table, '*', $whereString);
+ if ($response === false) done(DONE_DATABASE);
+ $keys = array_keys($response);
+ if (isset($_REQUEST['changed-after'])) {
+ $response = db_get_data($mysqli, $table, '*', '`changed` > "' . mysqli_real_escape_string($mysqli, date('Y-m-d H:i:s', $_REQUEST['changed-after'])) . '"' . ($whereString ? (' AND ' . $whereString) : ''));
+ if ($response === false) done(DONE_DATABASE);
+ }
+ $response = array_values($response);
+ done(DONE_OKAY, array('data' => replaceChanged($response), 'keys' => $keys));
+ }
+
+ function sendEntry($table) {
+ global $mysqli;
+ checkRequest('id');
+ $response = db_get_data($mysqli, $table, '*', '`id` = "' . mysqli_real_escape_string($mysqli, $_REQUEST['id']) . '"');
+ if ($response === false) done(DONE_DATABASE);
+ if (count($response) != 1) done(DONE_BAD_REQUEST, ['error' => 'id not found']);
+ $response = array_values($response)[0];
+ unset($response['changed']);
+ done(DONE_OKAY, ['data' => $response]);
+ }
+
switch ($action) {
case 'login':
@@ -110,11 +139,325 @@
break;
case 'logout':
- checkPermission(PERM_REGISTERED);
+ checkLoggedIn();
auth_logout($mysqli, $_REQUEST['auth']['id']);
done(DONE_OKAY);
break;
+ case 'get_update_time':
+ $times = array();
+ $response = db_get_data($mysqli, DB_TABLE_UPDATETIMES, '`update`', '`table` = "' . DB_TABLE_CLUBS . '"', 1);
+ if (($response !== false) and (count($response) > 0)) {
+ $times['clubs'] = strtotime(array_values($response)[0]['update']);
+ } else {
+ done(DONE_DATABASE);
+ }
+ $response = db_get_data($mysqli, DB_TABLE_UPDATETIMES, '`update`', '`table` = "' . BOATCLASS . DB_TABLE_SUFFIX_BOATS . '"', 1);
+ if (($response !== false) and (count($response) > 0)) {
+ $times['boats'] = strtotime(array_values($response)[0]['update']);
+ } else {
+ done(DONE_DATABASE);
+ }
+ $response = db_get_data($mysqli, DB_TABLE_UPDATETIMES, '`update`', '`table` = "' . BOATCLASS . DB_TABLE_SUFFIX_SAILORS . '"', 1);
+ if (($response !== false) and (count($response) > 0)) {
+ $times['sailors'] = strtotime(array_values($response)[0]['update']);
+ } else {
+ done(DONE_DATABASE);
+ }
+ $response = db_get_data($mysqli, DB_TABLE_UPDATETIMES, '`update`', '`table` = "' . BOATCLASS . DB_TABLE_SUFFIX_REGATTAS . '"', 1);
+ if (($response !== false) and (count($response) > 0)) {
+ $times['regattas'] = strtotime(array_values($response)[0]['update']);
+ } else {
+ done(DONE_DATABASE);
+ }
+ $response = db_get_data($mysqli, DB_TABLE_UPDATETIMES, '`update`', '`table` = "' . BOATCLASS . DB_TABLE_SUFFIX_RESULTS . '"', 1);
+ if (($response !== false) and (count($response) > 0)) {
+ $times['results'] = strtotime(array_values($response)[0]['update']);
+ } else {
+ done(DONE_DATABASE);
+ }
+ $response = db_get_data($mysqli, DB_TABLE_UPDATETIMES, '`update`', '`table` = "' . BOATCLASS . DB_TABLE_SUFFIX_PLANNING . '"', 1);
+ if (($response !== false) and (count($response) > 0)) {
+ $times['plannings'] = strtotime(array_values($response)[0]['update']);
+ } else {
+ done(DONE_DATABASE);
+ }
+ $response = db_get_data($mysqli, DB_TABLE_UPDATETIMES, '`update`', '`table` = "' . DB_TABLE_TRIM_BOATS . '"', 1);
+ if (($response !== false) and (count($response) > 0)) {
+ $times['trim_boats'] = strtotime(array_values($response)[0]['update']);
+ } else {
+ done(DONE_DATABASE);
+ }
+ $response = db_get_data($mysqli, DB_TABLE_UPDATETIMES, '`update`', '`table` = "' . DB_TABLE_TRIM_USERS . '"', 1);
+ if (($response !== false) and (count($response) > 0)) {
+ $times['trim_users'] = strtotime(array_values($response)[0]['update']);
+ } else {
+ done(DONE_DATABASE);
+ }
+ $response = db_get_data($mysqli, DB_TABLE_UPDATETIMES, '`update`', '`table` = "' . DB_TABLE_TRIM_TRIMS . '"', 1);
+ if (($response !== false) and (count($response) > 0)) {
+ $times['trim_trims'] = strtotime(array_values($response)[0]['update']);
+ } else {
+ done(DONE_DATABASE);
+ }
+ $response = db_get_data($mysqli, DB_TABLE_UPDATETIMES, '`update`', '`table` = "' . DB_TABLE_USERS . '"', 1);
+ if (($response !== false) and (count($response) > 0)) {
+ $times['users'] = strtotime(array_values($response)[0]['update']);
+ } else {
+ done(DONE_DATABASE);
+ }
+ done(DONE_OKAY, $times);
+ break;
+
+ case 'get_clubs':
+ sendEntries(DB_TABLE_CLUBS);
+ break;
+
+ case 'get_club':
+ sendEntry(DB_TABLE_CLUBS);
+ break;
+
+ case 'get_boats':
+ sendEntries(BOATCLASS . DB_TABLE_SUFFIX_BOATS);
+ break;
+
+ case 'get_boat':
+ sendEntry(BOATCLASS . DB_TABLE_SUFFIX_BOATS);
+ break;
+
+ case 'get_sailors':
+ sendEntries(BOATCLASS . DB_TABLE_SUFFIX_SAILORS);
+ break;
+
+ case 'get_sailor':
+ sendEntry(BOATCLASS . DB_TABLE_SUFFIX_SAILORS);
+ break;
+
+ case 'get_years':
+ $response = get_regatta_years($mysqli);
+ if ($response === false) done(DONE_DATABASE);
+ foreach ($response as $key => $value)
+ $response[$key] = ['year' => $value];
+ done(DONE_OKAY, ['data' => $response]);
+ break;
+
+ case 'get_regattas':
+ sendEntries(BOATCLASS . DB_TABLE_SUFFIX_REGATTAS);
+ break;
+
+ case 'get_regatta':
+ sendEntry(BOATCLASS . DB_TABLE_SUFFIX_REGATTAS);
+ break;
+
+ case 'get_results':
+ sendEntries(BOATCLASS . DB_TABLE_SUFFIX_RESULTS);
+ break;
+
+ case 'get_result':
+ sendEntry(BOATCLASS . DB_TABLE_SUFFIX_RESULTS);
+ break;
+
+ case 'get_plannings':
+ $response = db_get_data($mysqli, BOATCLASS . DB_TABLE_SUFFIX_PLANNING, '*', $whereString);
+ if ($response === false) done(DONE_DATABASE);
+ $keys = array_keys($response);
+ if (isset($_REQUEST['changed-after'])) {
+ $response = db_get_data($mysqli, BOATCLASS . DB_TABLE_SUFFIX_PLANNING, '*', '`changed` > "' . mysqli_real_escape_string($mysqli, date('Y-m-d H:i:s', $_REQUEST['changed-after'])) . '"' . ($whereString ? (' AND ' . $whereString) : ''));
+ if ($response === false) done(DONE_DATABASE);
+ }
+ $response = array_map(function ($entry) {
+ global $user_id;
+ if (($user_id === false) or ($entry['user'] != $user_id)) {
+ unset($entry['gemeldet'], $entry['bezahlt']);
+ }
+ return $entry;
+ }, $response);
+ $response = array_values($response);
+ done(DONE_OKAY, array('data' => replaceChanged($response), 'keys' => $keys));
+ break;
+
+ case 'get_planning':
+ checkRequest('id');
+ $response = db_get_data($mysqli, BOATCLASS . DB_TABLE_SUFFIX_PLANNING, '*', '`id` = "' . mysqli_real_escape_string($mysqli, $_REQUEST['id']) . '"');
+ if ($response === false) done(DONE_DATABASE);
+ if (count($response) != 1) done(DONE_BAD_REQUEST, ['error' => 'id not found']);
+ $response = array_values($response)[0];
+ if (($user_id === false) or ($response['user'] != $user_id)) {
+ unset($response['gemeldet'], $response['bezahlt']);
+ }
+ unset($response['changed']);
+ done(DONE_OKAY, ['data' => $response]);
+ break;
+
+ case 'get_trim_boats':
+ checkLoggedIn();
+ $users = db_get_data($mysqli, DB_TABLE_TRIM_USERS, 'boat', '`user`="' . $user_id . '"');
+ $boats = implode(',', array_column($users, 'boat'));
+ if ($boats == '') {
+ done(DONE_OKAY, array('data' => [], 'keys' => []));
+ }
+ $response = db_get_data($mysqli, DB_TABLE_TRIM_BOATS, '*', '`id` IN (' . $boats . ')' . ($whereString ? (' AND ' . $whereString) : ''));
+ if ($response === false) done(DONE_DATABASE);
+ $keys = array_keys($response);
+ if (isset($_REQUEST['changed-after'])) {
+ $response = db_get_data($mysqli, DB_TABLE_TRIM_BOATS, '*', '`id` IN (' . $boats . ') AND `changed` > "' . mysqli_real_escape_string($mysqli, date('Y-m-d H:i:s', $_REQUEST['changed-after'])) . '"' . ($whereString ? (' AND ' . $whereString) : ''));
+ if ($response === false) done(DONE_DATABASE);
+ }
+ $response = array_values($response);
+ done(DONE_OKAY, array('data' => replaceChanged($response), 'keys' => $keys));
+ break;
+
+ case 'get_trim_boat':
+ checkLoggedIn();
+ checkRequest('id');
+ $response = db_get_data($mysqli, DB_TABLE_TRIM_BOATS, '*', '`id` = "' . mysqli_real_escape_string($mysqli, $_REQUEST['id']) . '"');
+ if ($response === false) done(DONE_DATABASE);
+ if (count($response) != 1) done(DONE_BAD_REQUEST, ['error' => 'id not found']);
+ $response = array_values($response)[0];
+ if (count(db_get_data($mysqli, DB_TABLE_TRIM_USERS, 'id', '`user`="' . $user_id . '" AND `boat`="' . $response['id'] . '"')) != 1)
+ done(DONE_BAD_REQUEST, ['error' => 'id not found']);
+ unset($response['changed']);
+ done(DONE_OKAY, ['data' => $response]);
+ break;
+
+ case 'get_trim_users':
+ checkLoggedIn();
+ $users = db_get_data($mysqli, DB_TABLE_TRIM_USERS, 'boat', '`user`="' . $user_id . '"');
+ $boats = implode(',', array_column($users, 'boat'));
+ if ($boats == '') {
+ done(DONE_OKAY, array('data' => [], 'keys' => []));
+ }
+ $response = db_get_data($mysqli, DB_TABLE_TRIM_USERS, '*', '`boat` IN (' . $boats . ')' . ($whereString ? (' AND ' . $whereString) : ''));
+ if ($response === false) done(DONE_DATABASE);
+ $keys = array_keys($response);
+ if (isset($_REQUEST['changed-after'])) {
+ $response = db_get_data($mysqli, DB_TABLE_TRIM_USERS, '*', '`boat` IN (' . $boats . ') AND `changed` > "' . mysqli_real_escape_string($mysqli, date('Y-m-d H:i:s', $_REQUEST['changed-after'])) . '"' . ($whereString ? (' AND ' . $whereString) : ''));
+ if ($response === false) done(DONE_DATABASE);
+ }
+ $response = array_values($response);
+ done(DONE_OKAY, array('data' => replaceChanged($response), 'keys' => $keys));
+ break;
+
+ case 'get_trim_user':
+ checkLoggedIn();
+ checkRequest('id');
+ $response = db_get_data($mysqli, DB_TABLE_TRIM_USERS, '*', '`id` = "' . mysqli_real_escape_string($mysqli, $_REQUEST['id']) . '"');
+ if ($response === false) done(DONE_DATABASE);
+ if (count($response) != 1) done(DONE_BAD_REQUEST, ['error' => 'id not found']);
+ $response = array_values($response)[0];
+ if (count(db_get_data($mysqli, DB_TABLE_TRIM_USERS, 'id', '`user`="' . $user_id . '" AND `boat`="' . $response['boat'] . '"')) != 1)
+ done(DONE_BAD_REQUEST, ['error' => 'id not found']);
+ unset($response['changed']);
+ done(DONE_OKAY, ['data' => $response]);
+ break;
+
+ case 'get_trim_trims':
+ checkLoggedIn();
+ $users = db_get_data($mysqli, DB_TABLE_TRIM_USERS, 'boat', '`user`="' . $user_id . '"');
+ $boats = implode(',', array_column($users, 'boat'));
+ if ($boats == '') {
+ done(DONE_OKAY, array('data' => [], 'keys' => []));
+ }
+ $response = db_get_data($mysqli, DB_TABLE_TRIM_TRIMS, '*', '`boat` IN (' . $boats . ')' . ($whereString ? (' AND ' . $whereString) : ''));
+ if ($response === false) done(DONE_DATABASE);
+ $keys = array_keys($response);
+ if (isset($_REQUEST['changed-after'])) {
+ $response = db_get_data($mysqli, DB_TABLE_TRIM_TRIMS, '*', '`boat` IN (' . $boats . ') AND `changed` > "' . mysqli_real_escape_string($mysqli, date('Y-m-d H:i:s', $_REQUEST['changed-after'])) . '"' . ($whereString ? (' AND ' . $whereString) : ''));
+ if ($response === false) done(DONE_DATABASE);
+ }
+ $response = array_values($response);
+ done(DONE_OKAY, array('data' => replaceChanged($response), 'keys' => $keys));
+ break;
+
+ case 'get_trim_trim':
+ checkLoggedIn();
+ checkRequest('id');
+ $response = db_get_data($mysqli, DB_TABLE_TRIM_TRIMS, '*', '`id` = "' . mysqli_real_escape_string($mysqli, $_REQUEST['id']) . '"');
+ if ($response === false) done(DONE_DATABASE);
+ if (count($response) != 1) done(DONE_BAD_REQUEST, ['error' => 'id not found']);
+ $response = array_values($response)[0];
+ if (count(db_get_data($mysqli, DB_TABLE_TRIM_USERS, 'id', '`user`="' . $user_id . '" AND `boat`="' . $response['boat'] . '"')) != 1)
+ done(DONE_BAD_REQUEST, ['error' => 'id not found']);
+ unset($response['changed']);
+ done(DONE_OKAY, ['data' => $response]);
+ break;
+
+ case 'get_users':
+ $followFields = '';
+ for ($i = 1; $i <= 5; $i ++) $followFields .= ',' . BOATCLASS . '_sailor' . $i . ' AS sailor' . $i;
+ $response = db_get_data($mysqli, DB_TABLE_USERS, 'id,username,email' . $followFields, $whereString);
+ if ($response === false) done(DONE_DATABASE);
+ $keys = array_keys($response);
+ if (isset($_REQUEST['changed-after'])) {
+ $response = db_get_data($mysqli, DB_TABLE_USERS, 'id,username,email,' . $followFields, '`changed` > "' . mysqli_real_escape_string($mysqli, date('Y-m-d H:i:s', $_REQUEST['changed-after'])) . '"' . ($whereString ? (' AND ' . $whereString) : ''));
+ if ($response === false) done(DONE_DATABASE);
+ }
+ $response = array_map(function ($entry) {
+ global $user_id;
+ if ($entry['id'] != $user_id) {
+ $entry = ['id' => $entry['id'], 'username' => $entry['username']];
+ }
+ return $entry;
+ }, $response);
+ $response = array_values($response);
+ done(DONE_OKAY, array('data' => replaceChanged($response), 'keys' => $keys));
+ break;
+
+ case 'get_user':
+ checkRequest('id');
+ $followFields = '';
+ for ($i = 1; $i <= 5; $i ++) $followFields .= ',' . BOATCLASS . '_sailor' . $i . ' AS sailor' . $i;
+ $response = db_get_data($mysqli, DB_TABLE_USERS, 'id,username,email' . $followFields, '`id` = "' . mysqli_real_escape_string($mysqli, $_REQUEST['id']) . '"');
+ if ($response === false) done(DONE_DATABASE);
+ if (count($response) != 1) done(DONE_BAD_REQUEST, ['error' => 'id not found']);
+ $response = array_values($response)[0];
+ if ($response['id'] != $user_id) {
+ $response = ['id' => $response['id'], 'username' => $response['username']];
+ }
+ unset($response['changed']);
+ done(DONE_OKAY, ['data' => $response]);
+ break;
+
+ case 'add_subscription':
+ checkRequest('subscription');
+ $data = [
+ 'auth' => PUSH_AUTH,
+ 'subscription' => $_REQUEST['subscription']
+ ];
+ $ch = curl_init('https://push.ostertun.net/add_subscription');
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_POST, true);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
+ $result = curl_exec($ch);
+ curl_close($ch);
+ if ($result == "OK")
+ done(DONE_OKAY);
+ else {
+ logE('add_subscription', $result);
+ done(DONE_SERVER_ERROR);
+ }
+ break;
+
+ case 'remove_subscription':
+ checkRequest('subscription');
+ $data = [
+ 'auth' => PUSH_AUTH,
+ 'subscription' => $_REQUEST['subscription']
+ ];
+ $ch = curl_init('https://push.ostertun.net/remove_subscription');
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_POST, true);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
+ $result = curl_exec($ch);
+ curl_close($ch);
+ if ($result == "OK")
+ done(DONE_OKAY);
+ else {
+ logE('remove_subscription', $result);
+ done(DONE_SERVER_ERROR);
+ }
+ break;
+
default:
done(DONE_BAD_REQUEST, ['error' => 'action invalid']);
diff --git a/client/scripts/database.js b/client/scripts/database.js
new file mode 100644
index 0000000..4bd023a
--- /dev/null
+++ b/client/scripts/database.js
@@ -0,0 +1,799 @@
+const DB_VERSION = 3;
+
+const USER_ID = localStorage.getItem('auth_user');
+const USER_NAME = localStorage.getItem('auth_username');
+
+var canUseLocalDB = false;
+var syncTimer = null;
+var updateSyncStatusTimer;
+var syncInProgress = 0;
+var db;
+var user = null;
+
+var getJSON = function(url, callback) {
+ var xhr = new XMLHttpRequest();
+ xhr.open('POST', url, true);
+ xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
+ xhr.responseType = 'json';
+ xhr.timeout = 60000;
+ xhr.onload = function() {
+ callback(xhr.status, xhr.response);
+ };
+ xhr.ontimeout = function () {
+ console.log("getJSON: timeout");
+ callback(0, null);
+ }
+ xhr.onerror = function () {
+ console.log("getJSON: error");
+ callback(0, null);
+ }
+ if (USER_ID != null) {
+ authString = 'auth[id]=' + localStorage.getItem('auth_id');
+ authString += '&auth[hash]=' + encodeURIComponent(localStorage.getItem('auth_hash'));
+ xhr.send(authString);
+ } else {
+ xhr.send();
+ }
+};
+
+function isLoggedIn() {
+ return USER_ID !== null;
+}
+
+function search(string, fields) {
+ var keywords = string.split(' ');
+ for (kid in keywords) {
+ var keyword = keywords[kid].toLowerCase();
+ var found = false;
+ for (fid in fields) {
+ var field = fields[fid].toLowerCase();
+ if (field.indexOf(keyword) >= 0) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) return false;
+ }
+ return true;
+}
+
+function dbGetData(table, id = null) {
+ return new Promise(function(resolve) {
+ if (canUseLocalDB) {
+ if (id == null) {
+ db.transaction(table).objectStore(table).getAll().onsuccess = function (event) {
+ resolve(event.target.result);
+ };
+ } else {
+ var request = db.transaction(table).objectStore(table).get(id.toString());
+ request.onsuccess = function (event) {
+ resolve(typeof request.result != 'undefined' ? request.result : null);
+ }
+ }
+ } else {
+ if (id == null) {
+ getJSON(QUERY_URL + 'get_' + table, function (code, data) {
+ if (code == 200) {
+ resolve(data.data);
+ } else {
+ console.log("Something went wrong (HTTP " + code + ")");
+ fail(strings.error_network, 5000);
+ resolve([]);
+ }
+ });
+ } else {
+ getJSON(QUERY_URL + 'get_' + table.substr(0, table.length - 1) + '?id=' + id, function (code, data) {
+ if (code == 200) {
+ resolve(data.data);
+ } else {
+ console.log("Something went wrong (HTTP " + code + ")");
+ fail(strings.error_network, 5000);
+ resolve(null);
+ }
+ });
+ }
+ }
+ });
+}
+
+function dbGetDataIndex(table, indexName, value) {
+ return new Promise(function(resolve) {
+ if (canUseLocalDB) {
+ var request = db.transaction(table).objectStore(table).index(indexName).getAll(IDBKeyRange.only(value.toString()));
+ request.onsuccess = function (event) {
+ resolve(request.result);
+ }
+ } else {
+ getJSON(QUERY_URL + 'get_' + table + '?index=' + indexName + '&value=' + value, function (code, data) {
+ if (code == 200) {
+ resolve(data.data);
+ } else {
+ console.log("Something went wrong (HTTP " + code + ")");
+ fail(strings.error_network, 5000);
+ resolve([]);
+ }
+ });
+ }
+ });
+}
+
+function dbGetRegattasRange(minDate, maxDate) {
+ return new Promise(async function(resolve) {
+ var regattas = await dbGetData('regattas');
+ var result = [];
+ for (id in regattas) {
+ var regatta = regattas[id];
+ var dateFrom = parseDate(regatta['date']);
+ var dateTo = parseDate(regatta['date']);
+ dateTo.setDate(dateTo.getDate() + parseInt(regatta['length']) - 1);
+ if ((minDate <= dateTo) && (maxDate >= dateFrom)) {
+ regatta['dateFrom'] = dateFrom;
+ regatta['dateTo'] = dateTo;
+ result.push(regatta);
+ }
+ }
+ result.sort(function (a, b) {
+ if (a['date'] < b['date']) return -1;
+ if (a['date'] > b['date']) return 1;
+ return 0;
+ });
+ resolve(result);
+ });
+}
+
+var compareResultsRaceCount;
+function compareResults (a, b) {
+ if (a['netto'] != b['netto']) return (a['netto'] < b['netto']) ? -1 : 1;
+ var tempA = [...a['values']];
+ tempA.sort();
+ var tempB = [...b['values']];
+ tempB.sort();
+ for (var i = 0; i < compareResultsRaceCount; i ++) {
+ if (tempA[i] != tempB[i]) return (tempA[i] < tempB[i]) ? -1 : 1;
+ }
+ for (var i = compareResultsRaceCount - 1; i >= 0; i --) {
+ if (a['values_all'][i] != b['values_all'][i]) return (a['values_all'][i] < b['values_all'][i]) ? -1 : 1;
+ }
+ return 0;
+}
+
+function dbGetResultCalculated(regatta) {
+ return new Promise(async function(resolve) {
+ var results = await dbGetDataIndex('results', 'regatta', regatta.id);
+ if (results.length > 0) {
+
+ var gemeldet = results.length;
+
+ for (id in results) {
+ results[id]['finished'] = false;
+ results[id]['values'] = [];
+ results[id]['values_all'] = [];
+ results[id]['texts'] = [];
+ var copy = [];
+
+ for (var i = 0; i < regatta['races']; i ++) {
+ var race = results[id]['race' + (i + 1)].replace(',', '.');
+
+ if (!isNaN(race)) {
+ copy[i] = results[id]['values'][i] = parseFloat(race);
+ results[id]['texts'][i] = race;
+ results[id]['finished'] = true;
+ } else {
+ switch (race.toUpperCase()) {
+ // Nicht gestartet
+ case 'DNC': results[id]['values'][i] = gemeldet + 1; copy[i] = gemeldet + 1; break; // Did not come
+ case 'DNS': results[id]['values'][i] = gemeldet + 1; copy[i] = gemeldet + 1; break; // Did not started
+ // Startfehler
+ case 'OCS': results[id]['values'][i] = gemeldet + 1; copy[i] = gemeldet + 1; break; // On course site
+ case 'UFD': results[id]['values'][i] = gemeldet + 1; copy[i] = gemeldet + 1; break; // Uniform Flag Disqualified (disqu. nach 30.3)
+ case 'BFD': results[id]['values'][i] = gemeldet + 1; copy[i] = gemeldet + 1; break; // Black Flag Disqualified (disqu. nach 30.4)
+ // Nicht durch Ziel gegangen
+ case 'DNF': results[id]['values'][i] = gemeldet + 1; copy[i] = gemeldet + 1; break; // Did not finish
+ case 'RET': results[id]['values'][i] = gemeldet + 1; copy[i] = gemeldet + 1; break; // Retired (Aufgegeben)
+ case 'RAF': results[id]['values'][i] = gemeldet + 1; copy[i] = gemeldet + 1; break; // Retired after finish
+ // Disqualifizierun
+ case 'DSQ': results[id]['values'][i] = gemeldet + 1; copy[i] = gemeldet + 1; break; // Disqualified
+ case 'DNE': results[id]['values'][i] = gemeldet + 1; copy[i] = -1; break; // Disqualified, not excludable (disqu. kann nach 90.3(b) nicht gestrichen werden)
+ case 'DGM': results[id]['values'][i] = gemeldet + 1; copy[i] = -2; break; // Disqualification Gross Missconduct (kann nach 69.1(b)(2) nicht gestr. werden, grobes Fehlverhalten)
+ // Unbekannt
+ default: results[id]['values'][i] = 0; copy[i] = 0; break;
+ }
+
+ if (results[id]['values'][i] != 0) {
+ results[id]['texts'][i] = race + ' (' + results[id]['values'][i] + ')';
+ } else {
+ results[id]['texts'][i] = race + ' (Unknown - 0)';
+ }
+ }
+ }
+
+ results[id]['values_all'] = [...results[id]['values']];
+ for (var s = 0; s < regatta['streicher']; s ++) {
+ var max = Math.max(...copy);
+ for (var i = 0; i < regatta['races']; i ++) {
+ if (copy[i] == max) {
+ copy[i] = 0;
+ break;
+ }
+ }
+ }
+
+ var brutto = 0;
+ var netto = 0;
+ for (var i = 0; i < regatta['races']; i ++) {
+ brutto += results[id]['values_all'][i];
+ if (copy[i] == -1) { results[id]['values'][i] = gemeldet + 1; }
+ else if (copy[i] == -2) { results[id]['values'][i] = gemeldet + 1; }
+ else { results[id]['values'][i] = copy[i]; }
+ if (results[id]['values'][i] == 0) {
+ results[id]['texts'][i] = '[' + results[id]['texts'][i] + ']';
+ }
+ netto += results[id]['values'][i];
+ }
+ results[id]['brutto'] = brutto;
+ results[id]['netto'] = netto;
+ }
+
+ compareResultsRaceCount = regatta['races'];
+
+ results.sort(compareResults);
+
+ var place = 1;
+ for (id in results) {
+ if ((id > 0) && (compareResults(results[id], results[id - 1]) == 0)) {
+ results[id]['place'] = results[id - 1]['place'];
+ } else {
+ results[id]['place'] = place;
+ }
+ place ++;
+ }
+
+ resolve(results);
+
+ } else {
+ resolve([]);
+ }
+ });
+}
+
+async function updateSyncStatus() { // TODO
+// var syncStatus = document.getElementById('syncstatus');
+// var lastSync = await dbGetData('update_times', 'last_sync');
+// lastSync = new Date(lastSync.time * 1000);
+// var now = new Date();
+// var diff = Math.round((now - lastSync) / 1000);
+// var txt = '';
+//
+// if (diff < 30) { // 30 sec
+// txt = 'jetzt';
+// } else if (diff < 3600) { // 60 min
+// diff = Math.round(diff / 60);
+// txt = 'vor ' + diff + ' ' + (diff == 1 ? 'Minute' : 'Minuten');
+// } else if (diff < 86400) { // 24 std
+// diff = Math.round(diff / 3600);
+// txt = 'vor ' + diff + ' ' + (diff == 1 ? 'Stunde' : 'Stunden');
+// } else {
+// diff = Math.round(diff / 86400);
+// txt = 'vor ' + diff + ' ' + (diff == 1 ? 'Tag' : 'Tagen');
+// }
+//
+// var btn = ' Sync';
+// syncStatus.innerHTML = 'Zuletzt aktualisiert: ' + txt + btn;
+}
+
+async function runPageScript() {
+ if (canUseLocalDB) {
+ updateSyncStatus();
+ }
+ if (typeof updateSyncStatusTimer == 'undefined') { // TODO
+// var syncStatus = document.getElementById('syncstatus');
+ if (canUseLocalDB) {
+ updateSyncStatusTimer = window.setInterval(updateSyncStatus, 10000);
+ } else {
+// syncStatus.innerHTML = 'Keine Offline-Nutzung möglich.';
+ updateSyncStatusTimer = null;
+ }
+// syncStatus.style.display = 'block';
+ }
+
+ if (typeof siteScript === 'function') {
+ siteScript();
+ }
+ hideLoader();
+}
+
+function sync() {
+ if (!canUseLocalDB) return false;
+ if (syncInProgress > 0) return false;
+
+ var now = Math.floor(Date.now() / 1000);
+
+ db.transaction('update_times').objectStore('update_times').getAll().onsuccess = function (event) {
+ var localTimes = {};
+ event.target.result.forEach(function (entry) {
+ localTimes[entry['table']] = entry['time'];
+ });
+
+ syncInProgress = 10;
+ var syncOkay = true;
+ console.log("Sync Start");
+
+ var interval = window.setInterval(function () {
+ if (syncInProgress <= 0) {
+ window.clearInterval(interval);
+ if (syncOkay) {
+ var osUpdateTimes = db.transaction('update_times', 'readwrite').objectStore('update_times');
+ osUpdateTimes.put({ table: 'last_sync', time: now });
+ }
+ console.log("Sync Stop");
+
+ runPageScript();
+ }
+ }, 100);
+
+ getJSON(QUERY_URL + 'get_update_time', function (code, serverTimes) {
+ if (code == 200) {
+
+ // CLUBS
+ if (localTimes['clubs'] < serverTimes['clubs']) {
+ getJSON(QUERY_URL + 'get_clubs?changer-after=' + localTimes['clubs'], function (code, data) {
+ if (code == 200) {
+ var os = db.transaction('clubs', 'readwrite').objectStore('clubs');
+ console.log(data);
+ data.data.forEach(function (entry) {
+ os.put(entry);
+ });
+ os.openCursor().onsuccess = function (event) {
+ var cursor = event.target.result;
+ if (cursor) {
+ if (!data.keys.includes(parseInt(cursor.key))) {
+ os.delete(cursor.key);
+ }
+ cursor.continue();
+ } else {
+ var osUpdateTimes = db.transaction('update_times', 'readwrite').objectStore('update_times');
+ osUpdateTimes.put({ table: 'clubs', time: serverTimes['clubs'] });
+ syncInProgress --;
+ }
+ };
+ } else {
+ console.log("Something went wrong (HTTP " + code + ")");
+ syncOkay = false;
+ syncInProgress --;
+ }
+ });
+ } else {
+ syncInProgress --;
+ }
+
+ // BOATS
+ if (localTimes['boats'] < serverTimes['boats']) {
+ getJSON(QUERY_URL + 'get_boats?changer-after=' + localTimes['boats'], function (code, data) {
+ if (code == 200) {
+ var os = db.transaction('boats', 'readwrite').objectStore('boats');
+ console.log(data);
+ data.data.forEach(function (entry) {
+ os.put(entry);
+ });
+ os.openCursor().onsuccess = function (event) {
+ var cursor = event.target.result;
+ if (cursor) {
+ if (!data.keys.includes(parseInt(cursor.key))) {
+ os.delete(cursor.key);
+ }
+ cursor.continue();
+ } else {
+ var osUpdateTimes = db.transaction('update_times', 'readwrite').objectStore('update_times');
+ osUpdateTimes.put({ table: 'boats', time: serverTimes['boats'] });
+ syncInProgress --;
+ }
+ };
+ } else {
+ console.log("Something went wrong (HTTP " + code + ")");
+ syncOkay = false;
+ syncInProgress --;
+ }
+ });
+ } else {
+ syncInProgress --;
+ }
+
+ // SAILORS
+ if (localTimes['sailors'] < serverTimes['sailors']) {
+ getJSON(QUERY_URL + 'get_sailors?changer-after=' + localTimes['sailors'], function (code, data) {
+ if (code == 200) {
+ var os = db.transaction('sailors', 'readwrite').objectStore('sailors');
+ console.log(data);
+ data.data.forEach(function (entry) {
+ os.put(entry);
+ });
+ os.openCursor().onsuccess = function (event) {
+ var cursor = event.target.result;
+ if (cursor) {
+ if (!data.keys.includes(parseInt(cursor.key))) {
+ os.delete(cursor.key);
+ }
+ cursor.continue();
+ } else {
+ var osUpdateTimes = db.transaction('update_times', 'readwrite').objectStore('update_times');
+ osUpdateTimes.put({ table: 'sailors', time: serverTimes['sailors'] });
+ syncInProgress --;
+ }
+ };
+ } else {
+ console.log("Something went wrong (HTTP " + code + ")");
+ syncOkay = false;
+ syncInProgress --;
+ }
+ });
+ } else {
+ syncInProgress --;
+ }
+
+ // REGATTAS
+ if (localTimes['regattas'] < serverTimes['regattas']) {
+ getJSON(QUERY_URL + 'get_regattas?changer-after=' + localTimes['regattas'], function (code, data) {
+ if (code == 200) {
+ var os = db.transaction('regattas', 'readwrite').objectStore('regattas');
+ console.log(data);
+ data.data.forEach(function (entry) {
+ os.put(entry);
+ });
+ os.openCursor().onsuccess = async function (event) {
+ var cursor = event.target.result;
+ if (cursor) {
+ if (!data.keys.includes(parseInt(cursor.key))) {
+ os.delete(cursor.key);
+ }
+ cursor.continue();
+ } else {
+ // update years
+ var regattas = await dbGetData('regattas');
+ var years = {};
+ for (id in regattas) {
+ var entry = regattas[id];
+ var date = parseDate(entry['date']);
+ var y = date.getFullYear();
+ years[y] = y;
+ }
+ var osYears = db.transaction('years', 'readwrite').objectStore('years');
+ osYears.clear().onsuccess = function (event) {
+ for (var y in years) {
+ osYears.put({ year: y });
+ }
+ }
+
+ var osUpdateTimes = db.transaction('update_times', 'readwrite').objectStore('update_times');
+ osUpdateTimes.put({ table: 'regattas', time: serverTimes['regattas'] });
+ syncInProgress --;
+ }
+ };
+ } else {
+ console.log("Something went wrong (HTTP " + code + ")");
+ syncOkay = false;
+ syncInProgress --;
+ }
+ });
+ } else {
+ syncInProgress --;
+ }
+
+ // RESULTS
+ if (localTimes['results'] < serverTimes['results']) {
+ getJSON(QUERY_URL + 'get_results?changer-after=' + localTimes['results'], function (code, data) {
+ if (code == 200) {
+ var os = db.transaction('results', 'readwrite').objectStore('results');
+ console.log(data);
+ data.data.forEach(function (entry) {
+ os.put(entry);
+ });
+ os.openCursor().onsuccess = function (event) {
+ var cursor = event.target.result;
+ if (cursor) {
+ if (!data.keys.includes(parseInt(cursor.key))) {
+ os.delete(cursor.key);
+ }
+ cursor.continue();
+ } else {
+ var osUpdateTimes = db.transaction('update_times', 'readwrite').objectStore('update_times');
+ osUpdateTimes.put({ table: 'results', time: serverTimes['results'] });
+ syncInProgress --;
+ }
+ };
+ } else {
+ console.log("Something went wrong (HTTP " + code + ")");
+ syncOkay = false;
+ syncInProgress --;
+ }
+ });
+ } else {
+ syncInProgress --;
+ }
+
+ // PLANNINGS
+ if (localTimes['plannings'] < serverTimes['plannings']) {
+ getJSON(QUERY_URL + 'get_plannings?changer-after=' + localTimes['plannings'], function (code, data) {
+ if (code == 200) {
+ var os = db.transaction('plannings', 'readwrite').objectStore('plannings');
+ console.log(data);
+ data.data.forEach(function (entry) {
+ os.put(entry);
+ });
+ os.openCursor().onsuccess = function (event) {
+ var cursor = event.target.result;
+ if (cursor) {
+ if (!data.keys.includes(parseInt(cursor.key))) {
+ os.delete(cursor.key);
+ }
+ cursor.continue();
+ } else {
+ var osUpdateTimes = db.transaction('update_times', 'readwrite').objectStore('update_times');
+ osUpdateTimes.put({ table: 'plannings', time: serverTimes['plannings'] });
+ syncInProgress --;
+ }
+ };
+ } else {
+ console.log("Something went wrong (HTTP " + code + ")");
+ syncOkay = false;
+ syncInProgress --;
+ }
+ });
+ } else {
+ syncInProgress --;
+ }
+
+ if (isLoggedIn()) {
+ // TRIM_BOATS
+ if (localTimes['trim_boats'] < serverTimes['trim_boats']) {
+ getJSON(QUERY_URL + 'get_trim_boats?changer-after=' + localTimes['trim_boats'], function (code, data) {
+ if (code == 200) {
+ var os = db.transaction('trim_boats', 'readwrite').objectStore('trim_boats');
+ console.log(data);
+ data.data.forEach(function (entry) {
+ os.put(entry);
+ });
+ os.openCursor().onsuccess = function (event) {
+ var cursor = event.target.result;
+ if (cursor) {
+ if (!data.keys.includes(parseInt(cursor.key))) {
+ os.delete(cursor.key);
+ }
+ cursor.continue();
+ } else {
+ var osUpdateTimes = db.transaction('update_times', 'readwrite').objectStore('update_times');
+ osUpdateTimes.put({ table: 'trim_boats', time: serverTimes['trim_boats'] });
+ syncInProgress --;
+ }
+ };
+ } else {
+ console.log("Something went wrong (HTTP " + code + ")");
+ syncOkay = false;
+ syncInProgress --;
+ }
+ });
+ } else {
+ syncInProgress --;
+ }
+
+ // TRIM_USERS
+ if (localTimes['trim_users'] < serverTimes['trim_users']) {
+ getJSON(QUERY_URL + 'get_trim_users?changer-after=' + localTimes['trim_users'], function (code, data) {
+ if (code == 200) {
+ var os = db.transaction('trim_users', 'readwrite').objectStore('trim_users');
+ console.log(data);
+ data.data.forEach(function (entry) {
+ os.put(entry);
+ });
+ os.openCursor().onsuccess = function (event) {
+ var cursor = event.target.result;
+ if (cursor) {
+ if (!data.keys.includes(parseInt(cursor.key))) {
+ os.delete(cursor.key);
+ }
+ cursor.continue();
+ } else {
+ var osUpdateTimes = db.transaction('update_times', 'readwrite').objectStore('update_times');
+ osUpdateTimes.put({ table: 'trim_users', time: serverTimes['trim_users'] });
+ syncInProgress --;
+ }
+ };
+ } else {
+ console.log("Something went wrong (HTTP " + code + ")");
+ syncOkay = false;
+ syncInProgress --;
+ }
+ });
+ } else {
+ syncInProgress --;
+ }
+
+ // TRIM_TRIMS
+ if (localTimes['trim_trims'] < serverTimes['trim_trims']) {
+ getJSON(QUERY_URL + 'get_trim_trims?changer-after=' + localTimes['trim_trims'], function (code, data) {
+ if (code == 200) {
+ var os = db.transaction('trim_trims', 'readwrite').objectStore('trim_trims');
+ console.log(data);
+ data.data.forEach(function (entry) {
+ os.put(entry);
+ });
+ os.openCursor().onsuccess = function (event) {
+ var cursor = event.target.result;
+ if (cursor) {
+ if (!data.keys.includes(parseInt(cursor.key))) {
+ os.delete(cursor.key);
+ }
+ cursor.continue();
+ } else {
+ var osUpdateTimes = db.transaction('update_times', 'readwrite').objectStore('update_times');
+ osUpdateTimes.put({ table: 'trim_trims', time: serverTimes['trim_trims'] });
+ syncInProgress --;
+ }
+ };
+ } else {
+ console.log("Something went wrong (HTTP " + code + ")");
+ syncOkay = false;
+ syncInProgress --;
+ }
+ });
+ } else {
+ syncInProgress --;
+ }
+
+ } else {
+ syncInProgress -= 3;
+ }
+
+ // USERS
+ if (localTimes['users'] < serverTimes['users']) {
+ getJSON(QUERY_URL + 'get_users?changer-after=' + localTimes['users'], function (code, data) {
+ if (code == 200) {
+ var os = db.transaction('users', 'readwrite').objectStore('users');
+ console.log(data);
+ data.data.forEach(function (entry) {
+ os.put(entry);
+ });
+ os.openCursor().onsuccess = function (event) {
+ var cursor = event.target.result;
+ if (cursor) {
+ if (!data.keys.includes(parseInt(cursor.key))) {
+ os.delete(cursor.key);
+ }
+ cursor.continue();
+ } else {
+ var osUpdateTimes = db.transaction('update_times', 'readwrite').objectStore('update_times');
+ osUpdateTimes.put({ table: 'users', time: serverTimes['users'] });
+ syncInProgress --;
+ }
+ };
+ } else {
+ console.log("Something went wrong (HTTP " + code + ")");
+ syncOkay = false;
+ syncInProgress --;
+ }
+ });
+ } else {
+ syncInProgress --;
+ }
+
+ } else {
+ console.log("Something went wrong (HTTP " + code + ")");
+ syncOkay = false;
+ syncInProgress = 0;
+ }
+ });
+ };
+}
+
+function checkSync() {
+ if (!canUseLocalDB) return;
+ var osUpdateTimes = db.transaction('update_times').objectStore('update_times');
+ osUpdateTimes.get('last_sync').onsuccess = function (event) {
+ var lastSync = event.target.result.time;
+ var now = Math.floor(Date.now() / 1000);
+ if ((lastSync + 600) < now) { // sync max all 10 minutes
+ sync();
+ }
+ };
+}
+
+function initDatabase() {
+ if (window.indexedDB) {
+ var request = window.indexedDB.open('regatten_app_db_' + BOATCLASS, DB_VERSION);
+ request.onerror = function (event) {
+ console.log("Cannot open DB: " + event.target.errorCode);
+
+ runPageScript();
+ };
+ request.onsuccess = function (event) {
+ console.log("Database loaded");
+ db = event.target.result;
+
+ db.onversionchange = function (event) {
+ if (syncTimer != null) window.clearInterval(syncTimer);
+ if (updateSyncStatusTimer != null) window.clearInterval(updateSyncStatusTimer);
+// TODO document.getElementById('syncstatus').innerHTML = '';
+ canUseLocalDB = false;
+ db.close();
+ location.reload;
+ }
+
+ db.onerror = function (event) {
+ console.log("DB Error: " + event.target.errorCode);
+ };
+
+ canUseLocalDB = true;
+
+ db.transaction('update_times').objectStore('update_times').get('last_sync').onsuccess = function (event) {
+ var lastSync = event.target.result.time;
+ if (lastSync > 0) {
+ runPageScript();
+ }
+ };
+
+ checkSync();
+
+ syncTimer = window.setInterval(checkSync, 300000); // 5 min
+
+ window.ononline = function () {
+ checkSync();
+ }
+ };
+ request.onupgradeneeded = function (event) {
+ var db = event.target.result;
+ var upgradeTransaction = event.target.transaction;
+ var oldVersion = event.oldVersion;
+ var newVersion = event.newVersion;
+
+ console.log("Datenbank Version Upgrade von " + oldVersion + " auf " + newVersion);
+
+ if ((oldVersion < 1) && (newVersion >= 1)) {
+ console.log('to version 1');
+ var osClubs = db.createObjectStore('clubs', { keyPath: 'id' });
+ var osBoats = db.createObjectStore('boats', { keyPath: 'id' });
+ var osSailors = db.createObjectStore('sailors', { keyPath: 'id' });
+ var osRegattas = db.createObjectStore('regattas', { keyPath: 'id' });
+ var osResults = db.createObjectStore('results', { keyPath: 'id' });
+ osResults.createIndex('regatta', 'regatta', { unique: false });
+ var osPlannings = db.createObjectStore('plannings', { keyPath: 'id' });
+ osPlannings.createIndex('user', 'user', { unique: false });
+ osPlannings.createIndex('regatta', 'regatta', { unique: false });
+ var osTrimBoats = db.createObjectStore('trim_boats', { keyPath: 'id' });
+ var osTrimUsers = db.createObjectStore('trim_users', { keyPath: 'id' });
+ osTrimUsers.createIndex('boat', 'boat', { unique: false });
+ var osTrimTrims = db.createObjectStore('trim_trims', { keyPath: 'id' });
+ osTrimTrims.createIndex('boat', 'boat', { unique: false });
+ var osUpdateTimes = db.createObjectStore('update_times', { keyPath: 'table' });
+ osUpdateTimes.add({ table: 'last_sync', time: 0 });
+ osUpdateTimes.add({ table: 'clubs', time: 0 });
+ osUpdateTimes.add({ table: 'boats', time: 0 });
+ osUpdateTimes.add({ table: 'sailors', time: 0 });
+ osUpdateTimes.add({ table: 'regattas', time: 0 });
+ osUpdateTimes.add({ table: 'results', time: 0 });
+ osUpdateTimes.add({ table: 'plannings', time: 0 });
+ osUpdateTimes.add({ table: 'trim_boats', time: 0 });
+ osUpdateTimes.add({ table: 'trim_users', time: 0 });
+ osUpdateTimes.add({ table: 'trim_trims', time: 0 });
+ }
+
+ if ((oldVersion < 2) && (newVersion >= 2)) {
+ console.log('to version 2');
+ var osUsers = db.createObjectStore('users', { keyPath: 'id' });
+ osUsers.createIndex('username', 'username', { unique: true });
+ var osUpdateTimes = upgradeTransaction.objectStore('update_times');
+ osUpdateTimes.add({ table: 'users', time: 0 });
+ }
+
+ if ((oldVersion < 3) && (newVersion >= 3)) {
+ console.log('to version 3');
+ var osYears = db.createObjectStore('years', { keyPath: 'year' });
+ var osUpdateTimes = upgradeTransaction.objectStore('update_times');
+ osUpdateTimes.put({ table: 'regattas', time: 0 });
+ }
+
+ var osUpdateTimes = upgradeTransaction.objectStore('update_times');
+ osUpdateTimes.put({ table: 'last_sync', time: 0 });
+ }
+ } else {
+ runPageScript();
+ }
+}
diff --git a/client/scripts/datetime.js b/client/scripts/datetime.js
new file mode 100644
index 0000000..ac5e354
--- /dev/null
+++ b/client/scripts/datetime.js
@@ -0,0 +1,87 @@
+function parseDate(string) {
+ var year, month, day;
+ if (string.includes('.')) {
+ var split = string.split('.');
+ if (split.length != 3) return null;
+ year = parseInt(split[2]);
+ month = parseInt(split[1]);
+ day = parseInt(split[0]);
+ } else if (string.includes('/')) {
+ var split = string.split('/');
+ if (split.length != 3) return null;
+ year = parseInt(split[2]);
+ month = parseInt(split[0]);
+ day = parseInt(split[1]);
+ } else if (string.includes('-')) {
+ var split = string.split('-');
+ if (split.length != 3) return null;
+ if (split[2].length > 2) {
+ year = parseInt(split[2]);
+ month = parseInt(split[1]);
+ day = parseInt(split[0]);
+ } else {
+ year = parseInt(split[0]);
+ month = parseInt(split[1]);
+ day = parseInt(split[2]);
+ }
+ } else {
+ return null;
+ }
+
+ if (isNaN(year) || isNaN(month) || isNaN(day)) return null;
+ if (year.toString().length == 2) year = (year < 70 ? 2000 : 1900) + year;
+ if ((year < 1970) || (year > 3000)) return null;
+ if ((month < 1) || (month > 12)) return null;
+ if ((day < 1) || (day > 31)) return null;
+
+ var date = new Date(Date.UTC(year, month - 1, day));
+ return date;
+}
+
+function getToday() {
+ var date = new Date();
+ date = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
+ return date;
+}
+
+function formatDate(format, date = null) {
+ if (date === null) {
+ date = new Date();
+ } else {
+ date = new Date(date.valueOf());
+ date.setMinutes(date.getMinutes() + date.getTimezoneOffset());
+ }
+
+ format = format.replace("M", "%1%");
+ format = format.replace("F", "%2%");
+ format = format.replace("D", "%3%");
+ format = format.replace("l", "%4%");
+
+ var tmp = date.getFullYear().toString();
+ var tmp2 = tmp.substr(2);
+ format = format.replace("Y", tmp);
+ format = format.replace('y', tmp2);
+
+ tmp = (date.getMonth() + 1).toString();
+ tmp2 = (tmp.length > 1 ? tmp : ('0' + tmp));
+ format = format.replace('n', tmp);
+ format = format.replace('m', tmp2);
+
+ tmp = date.getDate().toString();
+ tmp2 = (tmp.length > 1 ? tmp : ('0' + tmp));
+ format = format.replace('j', tmp);
+ format = format.replace('d', tmp2);
+
+ tmp = date.getDay();
+ tmp2 = (tmp == 0 ? 7 : tmp);
+ format = format.replace('w', tmp);
+ format = format.replace('N', tmp2);
+
+ format = format.replace('%1%', strings.months_short[date.getMonth()]);
+ format = format.replace('%2%', strings.months_long[date.getMonth()]);
+
+ format = format.replace('%3%', strings.weekdays_short[date.getDay()]);
+ format = format.replace('%4%', strings.weekdays_long[date.getDay()]);
+
+ return format;
+}
diff --git a/client/scripts/regatten.js.php b/client/scripts/regatten.js.php
index 1885768..b920241 100644
--- a/client/scripts/regatten.js.php
+++ b/client/scripts/regatten.js.php
@@ -6,7 +6,8 @@
?>
-const apiUrl = '/api/';
+const QUERY_URL = '/api/';
+const BOATCLASS = '';
var randomId = function() { return '_' + Math.random().toString(36).substr(2, 9); }
@@ -181,33 +182,53 @@ var logout = function() {
});
}
-var initRegatten = function() {
- loggedin = (localStorage.getItem('auth_id') !== null);
-
- if (loggedin) {
- var auth = {
- id: localStorage.getItem('auth_id'),
- hash: localStorage.getItem('auth_hash')
- }
- var user = {
- id: localStorage.getItem('auth_user'),
- name: localStorage.getItem('auth_username')
- }
- if ((auth.hash === null) || (user.id === null) || (user.name === null)) {
- logoutClearStorage();
- return;
+function resetDb() {
+ $('#menu-developer').hideMenu();
+ if (canUseLocalDB) {
+ showLoader();
+ var request = window.indexedDB.deleteDatabase('regatten_app_db_' + BOATCLASS);
+ request.onerror = function (event) {
+ console.log("Cannot open DB: " + event.target.errorCode);
+ toastError('There was an error deleting your database.
Please report this to dev@regatten.net');
+ hideLoader();
+ };
+ request.onsuccess = function (event) {
+ console.log('DB deleted');
+ toastInfo('The database was deleted. Please reload or close this tab.
At the next visit, a new database will be created.');
+ hideLoader();
}
+ } else {
+ toastWarn('Your device does not support storing data locally. All data is fetched directly from our server.
As a result, you can not reset your database.');
}
+}
+
+function resetCache() {
+ $('#menu-developer').hideMenu();
+ navigator.serviceWorker.getRegistrations().then(function (registrations) {
+ for (let registration of registrations) {
+ console.log('Unregister sW:', registration);
+ registration.unregister();
+ }
+ });
+ caches.keys().then((keyList) => {
+ return Promise.all(keyList.map((key) => {
+ console.log('Cache deleted:', key);
+ return caches.delete(key);
+ }));
+ });
+ toastInfo('The serviceWorker and the cache were deleted. A new serviceWorker will be generated on the next refresh.');
+}
+
+var initRegatten = function() {
+ showLoader();
- if (loggedin) {
+ initDatabase();
+
+ if (isLoggedIn) {
$('.show-notloggedin').css('display', 'none');
- $('.replace-userid-href').attr('href', $('.replace-userid-href').attr('href').replace('%USERID%', user.id));
- $('.replace-username').html(user.name);
+ $('.replace-userid-href').attr('href', $('.replace-userid-href').attr('href').replace('%USERID%', USER_ID));
+ $('.replace-username').html(USER_NAME);
} else {
$('.show-loggedin').css('display', 'none');
}
-
- if (typeof siteScript !== 'undefined') {
- siteScript();
- }
}
\ No newline at end of file
diff --git a/client/scripts/strings.js.php b/client/scripts/strings.js.php
index ae61288..d53b9d5 100644
--- a/client/scripts/strings.js.php
+++ b/client/scripts/strings.js.php
@@ -8,4 +8,51 @@
const strings = {
inetMsgOffline: "Keine Internet-Verbindung erkannt",
inetMsgOnline: "Du bist wieder online",
+ error_network: "Verbindung fehlgeschlagen.
Stelle sicher, dass Du mit dem Internet verbunden bist und versuche es erneut!",
+ months_short: [
+ 'Jan.',
+ 'Feb.',
+ 'März',
+ 'Apr.',
+ 'Mai',
+ 'Juni',
+ 'Juli',
+ 'Aug.',
+ 'Sep.',
+ 'Okt.',
+ 'Nov.',
+ 'Dez.'
+ ],
+ months_long: [
+ 'Januar',
+ 'Februar',
+ 'März',
+ 'April',
+ 'Mai',
+ 'Juni',
+ 'Juli',
+ 'August',
+ 'September',
+ 'Oktober',
+ 'November',
+ 'Dezember'
+ ],
+ weekdays_short: [
+ 'So',
+ 'Mo',
+ 'Di',
+ 'Mi',
+ 'Do',
+ 'Fr',
+ 'Sa'
+ ],
+ weekdays_long: [
+ 'Sonntag',
+ 'Montag',
+ 'Dienstag',
+ 'Mittwoch',
+ 'Donnerstag',
+ 'Freitag',
+ 'Samstag'
+ ],
}
\ No newline at end of file
diff --git a/content/index.php b/content/index.php
index 9baa79b..3b4130a 100644
--- a/content/index.php
+++ b/content/index.php
@@ -7,30 +7,52 @@
$sp['output'] .= $tpl->load('card', [$content]);
// Favorites
- $content = "
';
+ $content .= 'Du folgst keinen Seglern.
';
+ $content .= 'Um jemandem zu folgen, gehe zur Segler-Liste und wähle bis zu fünf Segler aus.';
+ $content .= '
'; + $content .= 'Du fährst in den nächsten vier Wochen auf keine Regatta!'; + $content .= '
'; $sp['output'] .= $tpl->load('card', [$content, 'html-id' => 'card-yournext']); + // Not logged in + $content = '';
+ $content .= 'Um alle Funktionen dieser Seite nutzen zu können, logge Dich bitte ein.
';
+ $content .= 'Solltest Du noch kein Benutzerkonto haben, kannst Du Dich kostenlos registrieren.';
+ $content .= '
'; + $content .= 'Keine Regatten in den nächsten zwei Wochen!'; + $content .= '
'; $sp['output'] .= $tpl->load('card', [$content, 'html-id' => 'card-next']); // Last - $content = "'; + $content .= 'Keine Regatten in den letzten zwei Wochen!'; + $content .= '
'; $sp['output'] .= $tpl->load('card', [$content, 'html-id' => 'card-last']); @@ -46,20 +68,6 @@ $sp['output'] .= $tpl->load('card', [$content]); - $sp['scripts'] = ' - - '; + $sp['scripts'] = '' . $scripts->load('index'); ?> \ No newline at end of file diff --git a/index.php b/index.php index 8585582..cdad4b6 100644 --- a/index.php +++ b/index.php @@ -3,6 +3,7 @@ require_once(__DIR__ . '/server/config.php'); require_once(__DIR__ . '/server/log.php'); require_once(__DIR__ . '/server/templates.php'); + require_once(__DIR__ . '/server/scripts.php'); $request = false; if (isset($_GET['request'])) { @@ -36,6 +37,7 @@ ]; $tpl = new Templates(__DIR__ . '/server/templates/'); + $scripts = new Scripts(__DIR__ . '/server/scripts/'); require_once(__DIR__ . '/content/' . $site . '.php'); diff --git a/server/page/headerfooter.php b/server/page/headerfooter.php index 120e37d..79c39d6 100644 --- a/server/page/headerfooter.php +++ b/server/page/headerfooter.php @@ -7,6 +7,7 @@ else echo ''; } ?> + + +