diff --git a/src/structure/components/com_sportsmanager/admin.php b/src/structure/components/com_sportsmanager/admin.php index b70b281..c783808 100644 --- a/src/structure/components/com_sportsmanager/admin.php +++ b/src/structure/components/com_sportsmanager/admin.php @@ -21,14 +21,14 @@ require_once JPATH_SITE . '/components/com_sportsmanager/database/init.php'; function UhrzeitWandlerDE(string $input): string { // mögliche Datumsformate $formats = [ - 'Y-m-d H:i', - 'd.m.Y H:i', + 'Y-m-d H:i', + 'd.m.Y H:i', 'd.m.Y H:i:s', ]; foreach ($formats as $format) { $dt = DateTime::createFromFormat($format, $input); - + // prüfen, ob Parsing erfolgreich war UND das Datum exakt passt if ($dt && $dt->format($format) === $input) { return $dt->format('Y-m-d H:i:s'); @@ -684,15 +684,12 @@ function adminEinstellungen(): void $spalte_mitglieder_zeigen = $jInput->get('spalte_mitglieder_zeigen', 0, 'INT'); $turnierbaum_zeigen = $jInput->get('turnierbaum_zeigen', 0, 'INT'); $termine_beantragen = $jInput->get('termine_beantragen', 0, 'INT'); + $enableEmailReminders = $jInput->get('enable_email_reminders', 0, 'INT'); + $spielerimport_persoenliche_daten_vorauswahl = $jInput->get('spielerimport_persoenliche_daten_vorauswahl', 0, 'INT'); $api_push_key = $jInput->get('api_push_key', '', 'RAW'); - /* - $twitter_benutzername = $db->escape(trim( $jInput->get('twitter_benutzername', '', 'RAW') )); - $twitter_kennwort = !empty($twitter_benutzername) ? $db->escape(trim( $jInput->get('twitter_kennwort', '', 'RAW') )) : ""; - */ - $query = "REPLACE #__sportsmanager_einstellungen" . "\n SET name = 'basis_spielernr'" . ", wert = '$basis_spielernr'"; @@ -803,6 +800,12 @@ function adminEinstellungen(): void die($db->stderr(true)); } + $query = "REPLACE #__sportsmanager_einstellungen SET name = 'enable_email_reminders', wert = '$enableEmailReminders'"; + $db->setQuery($query); + if (!$db->execute()) { + die($db->stderr(true)); + } + redirectSportsManagerURL('&task=admin_uebersicht'); } @@ -9615,7 +9618,7 @@ function adminBegegnungenImportieren(): void if ($encoding == "UTF-8") echo $data[$Titelzeile['Heim']]; else - echo utf8_encode($data[$Titelzeile['Heim']]); + echo utf8_encode($data[$Titelzeile['Heim']]); echo ""; if ($Begegnung[$Zeile]['gast_team_id'] == "") { if ($data[$Titelzeile['Gast']] == "spielfrei") { @@ -10260,7 +10263,7 @@ function adminBegegnungenPokalrundeAuslosenForm(): void if (!$db->execute()) { die($db->stderr(true)); } - + redirectSportsManagerURL('&task=admin_begegnungen&veranstaltungid=' . $veranstaltungId); } else{ @@ -10606,6 +10609,7 @@ function adminEditTurnier(): void $turnierort = $db->escape(trim($jInput->get('turnierort', '', 'RAW'))); $erster_tag = normalisiertesDatum(sprintf("%04d-%02d-%02d", $jInput->get('erster_tag_jahr', 2000, 'INT'), $jInput->get('erster_tag_monat', 1, 'INT'), $jInput->get('erster_tag_tag', 1, 'INT'))); $mehrtaegig = $jInput->get('mehrtaegig', 0, 'INT'); + $reminder_count = $jInput->get('reminder_count', 0, 'INT'); if (!$mehrtaegig) $letzter_tag = $erster_tag; else @@ -10629,7 +10633,20 @@ function adminEditTurnier(): void } if ($id == 0) { - $query = "INSERT INTO #__sportsmanager_turnier (veranstalter_id, turnierbezeichnung, saison_id, turnierort, erster_tag" . ($letzter_tag != null ? ", letzter_tag" : "") . ", kategorie) VALUES ('$veranstalterId', '$turnierbezeichnung', '$saison_id', '$turnierort', '$erster_tag'" . ($letzter_tag != null ? ", '$letzter_tag'" : "") . ", '$kategorie');"; + $query = $db->getQuery(true) + ->select('wert') + ->from('#__sportsmanager_einstellungen') + ->where('name = ' . $db->quote('enable_email_reminders')); + $remindersEnabled = loadResult($db, $query); + + $query = "INSERT INTO #__sportsmanager_turnier (veranstalter_id, turnierbezeichnung, saison_id, turnierort, erster_tag" + . ($letzter_tag != null ? ", letzter_tag" : "") + . ", kategorie, reminder_count) VALUES ('$veranstalterId', '$turnierbezeichnung', '$saison_id', '$turnierort', '$erster_tag'" + . ($letzter_tag != null ? ", '$letzter_tag'" : "") + . ", '$kategorie', " + . (!$remindersEnabled ? "'3'" : "'0'") + . ")"; + $db->setQuery($query); if (!$db->execute()) { die($db->stderr(true)); @@ -10643,7 +10660,8 @@ function adminEditTurnier(): void . "\n turnierort = '$turnierort'," . "\n erster_tag = '$erster_tag'," . "\n letzter_tag = " . ($letzter_tag != null ? "'$letzter_tag'" : "NULL") . "," - . "\n kategorie = '$kategorie'" + . "\n kategorie = '$kategorie'," + . "\n reminder_count = '$reminder_count'" . "\n WHERE turnier_id = $id"; $db->setQuery($query); if (!$db->execute()) { diff --git a/src/structure/components/com_sportsmanager/database/update.php b/src/structure/components/com_sportsmanager/database/update.php index 712aa2d..ad54812 100644 --- a/src/structure/components/com_sportsmanager/database/update.php +++ b/src/structure/components/com_sportsmanager/database/update.php @@ -5300,11 +5300,11 @@ function updateDatabase(): void $query = "INSERT IGNORE #__sportsmanager_einstellungen SET name = 'verband_anzeigen', wert = '1';"; $db->setQuery( $query ); if (!$db->execute()) { die($db->stderr(true)); } - + $query = "INSERT IGNORE #__sportsmanager_einstellungen SET name = 'turnierbaum_zeigen', wert = '0';"; $db->setQuery( $query ); if (!$db->execute()) { die($db->stderr(true)); } - + $query = "INSERT IGNORE #__sportsmanager_einstellungen SET name = 'spalte_mitglieder_zeigen', wert = '1';"; $db->setQuery( $query ); if (!$db->execute()) { die($db->stderr(true)); } @@ -5331,7 +5331,7 @@ function updateDatabase(): void . "\n DROP INDEX `begegnung_id`, ADD UNIQUE `begegnung_id` (`begegnung_id`) USING BTREE;"; $db->setQuery( $query ); if (!$db->execute()) { die($db->stderr(true)); } - + $query = "UPDATE #__sportsmanager_einstellungen" . "\n SET wert = '108'" . "\n WHERE name = 'datenbank_version'"; @@ -5341,6 +5341,30 @@ function updateDatabase(): void } } + if ($datenbank_version < 109) { + $query = "ALTER TABLE #__sportsmanager_turnier ADD COLUMN `reminder_count` TINYINT DEFAULT '0'"; + $db->setQuery($query); + if (!$db->execute()) { die($db->stderr(true)); } + + // set all existing tournaments to 3 to prevent email flooding + $query = "UPDATE #__sportsmanager_turnier SET `reminder_count` = '3'"; + $db->setQuery($query); + if (!$db->execute()) { die($db->stderr(true)); } + + // 3: prevent email flood for past tournaments + $query = "INSERT IGNORE #__sportsmanager_einstellungen SET name = 'enable_email_reminders', wert = '0';"; + $db->setQuery( $query ); + if (!$db->execute()) { die($db->stderr(true)); } + + $query = "UPDATE #__sportsmanager_einstellungen" + . "\n SET wert = '109'" + . "\n WHERE name = 'datenbank_version'"; + $db->setQuery($query); + if (!$db->execute()) { + die($db->stderr(true)); + } + } + if ($termin_aktionen_email_setzen) { $query = "SELECT aktion_user_id, termin_aktion_id" . "\n FROM #__sportsmanager_termin_aktion"; diff --git a/src/structure/components/com_sportsmanager/sportsmanager.php b/src/structure/components/com_sportsmanager/sportsmanager.php index 4583fd9..5d0b164 100644 --- a/src/structure/components/com_sportsmanager/sportsmanager.php +++ b/src/structure/components/com_sportsmanager/sportsmanager.php @@ -42,11 +42,14 @@ require_once JPATH_SITE . '/components/com_sportsmanager/views/sportsmanager/vie require_once JPATH_SITE . '/components/com_sportsmanager/views/sportsmanager/view_admin.php'; require_once JPATH_SITE . '/components/com_sportsmanager/views/sportsmanager/view_ticker.php'; require_once JPATH_SITE . '/components/com_sportsmanager/util/image.php'; +require_once JPATH_SITE . '/components/com_sportsmanager/util/email.php'; require_once JPATH_SITE . '/components/com_sportsmanager/database/update.php'; // will also include init.php and util.php initDatabase(); updateDatabase(); +sentEmailReminders(); + if (isset($_POST['filter_saison_id'])) setcookie('sportsmanager_filter_saison_id', $_POST['filter_saison_id'], time() + (60 * 60 * 24)); else if (isset($_REQUEST['filter_saison_id'])) @@ -1186,7 +1189,7 @@ function benutzerVeranstaltungModerator($veranstaltung_id = NULL): bool return false; $user_id = Factory::getContainer()->get(SiteApplication::class)->getIdentity()->id; - $query = "SELECT * FROM #__sportsmanager_berechtigt_fuer_veranstaltung INNER JOIN #__sportsmanager_veranstaltung ON veranstaltung_id = berechtigt_veranstaltung_id WHERE berechtigt_user_id = $user_id AND DATEDIFF(letzter_tag, NOW()) >= -14"; + $query = "SELECT * FROM #__sportsmanager_berechtigt_fuer_veranstaltung INNER JOIN #__sportsmanager_veranstaltung ON veranstaltung_id = berechtigt_veranstaltung_id WHERE berechtigt_user_id = $user_id AND DATEDIFF(letzter_tag, NOW()) >= -21"; if ($veranstaltung_id != NULL) $query .= " AND berechtigt_veranstaltung_id = $veranstaltung_id"; $rows = loadObjectList($db, $query); @@ -1204,7 +1207,7 @@ function benutzerVeranstaltungIdsModerator(): array return array(); $user_id = Factory::getContainer()->get(SiteApplication::class)->getIdentity()->id; - $query = "SELECT DISTINCT veranstaltung_id FROM #__sportsmanager_berechtigt_fuer_veranstaltung INNER JOIN #__sportsmanager_veranstaltung ON veranstaltung_id = berechtigt_veranstaltung_id WHERE berechtigt_user_id = $user_id AND DATEDIFF(letzter_tag, NOW()) >= -14"; + $query = "SELECT DISTINCT veranstaltung_id FROM #__sportsmanager_berechtigt_fuer_veranstaltung INNER JOIN #__sportsmanager_veranstaltung ON veranstaltung_id = berechtigt_veranstaltung_id WHERE berechtigt_user_id = $user_id AND DATEDIFF(letzter_tag, NOW()) >= -21"; $rows = loadObjectList($db, $query); $ids = array(); @@ -1222,7 +1225,7 @@ function benutzerTurnierModerator($turnier_id = NULL): bool return false; $user_id = Factory::getContainer()->get(SiteApplication::class)->getIdentity()->id; - $query = "SELECT * FROM #__sportsmanager_berechtigt_fuer_turnier INNER JOIN #__sportsmanager_turnier ON turnier_id = berechtigt_turnier_id WHERE berechtigt_user_id = $user_id AND DATEDIFF(letzter_tag, NOW()) >= -14"; + $query = "SELECT * FROM #__sportsmanager_berechtigt_fuer_turnier INNER JOIN #__sportsmanager_turnier ON turnier_id = berechtigt_turnier_id WHERE berechtigt_user_id = $user_id AND DATEDIFF(letzter_tag, NOW()) >= -21"; if ($turnier_id != NULL) $query .= " AND berechtigt_turnier_id = $turnier_id"; $rows = loadObjectList($db, $query); diff --git a/src/structure/components/com_sportsmanager/tools.php b/src/structure/components/com_sportsmanager/tools.php index 0aca5bd..7f6beea 100644 --- a/src/structure/components/com_sportsmanager/tools.php +++ b/src/structure/components/com_sportsmanager/tools.php @@ -201,7 +201,7 @@ function kategorieFilter($prefix, $suffix = ""): string function turnierFilter($prefix): string { $user_id = isExternalDatabase() ? 0 : Factory::getContainer()->get(SiteApplication::class)->getIdentity()->id; - return " " . $prefix . " (SELECT berechtigt_turnier_id FROM #__sportsmanager_berechtigt_fuer_turnier WHERE berechtigt_user_id = $user_id AND DATEDIFF(letzter_tag, NOW()) >= -14) "; + return " " . $prefix . " (SELECT berechtigt_turnier_id FROM #__sportsmanager_berechtigt_fuer_turnier WHERE berechtigt_user_id = $user_id AND DATEDIFF(letzter_tag, NOW()) >= -21) "; } function vereinFilter($prefix): string @@ -219,7 +219,7 @@ function veranstalterFilter($prefix): string function veranstaltungFilter($prefix): string { $user_id = isExternalDatabase() ? 0 : Factory::getContainer()->get(SiteApplication::class)->getIdentity()->id; - return " " . $prefix . " (SELECT berechtigt_veranstaltung_id FROM #__sportsmanager_berechtigt_fuer_veranstaltung INNER JOIN #__sportsmanager_veranstaltung ON veranstaltung_id = berechtigt_veranstaltung_id WHERE berechtigt_user_id = $user_id AND DATEDIFF(letzter_tag, NOW()) >= -14) "; + return " " . $prefix . " (SELECT berechtigt_veranstaltung_id FROM #__sportsmanager_berechtigt_fuer_veranstaltung INNER JOIN #__sportsmanager_veranstaltung ON veranstaltung_id = berechtigt_veranstaltung_id WHERE berechtigt_user_id = $user_id AND DATEDIFF(letzter_tag, NOW()) >= -21) "; } // Berechnet Datum zum Montag der ersten Kalenderwoche eines Jahres diff --git a/src/structure/components/com_sportsmanager/util/email.php b/src/structure/components/com_sportsmanager/util/email.php new file mode 100644 index 0000000..4b2b5c5 --- /dev/null +++ b/src/structure/components/com_sportsmanager/util/email.php @@ -0,0 +1,125 @@ +get(SiteApplication::class); + $db = getDatabase(); + + $query = $db->getQuery(true) + ->select('wert') + ->from('#__sportsmanager_einstellungen') + ->where('name = ' . $db->quote('enable_email_reminders')); + $row = loadResult($db, $query); + + if (!$row) { + return; // quit when email reminders are disabled + } + + $query = $db->getQuery(true) + ->select('tournament.turnier_id, tournament.turnierbezeichnung, tournament.letzter_tag, tournament.reminder_count, GROUP_CONCAT(user.email SEPARATOR ", ") as emails') + ->from($db->quoteName('#__sportsmanager_turnier', 'tournament')) + ->join('INNER', $db->quoteName('#__sportsmanager_berechtigt_fuer_turnier', 'entitled') . ' ON tournament.turnier_id = entitled.berechtigt_turnier_id') + ->join('INNER', $db->quoteName('#__users', 'user') . ' ON entitled.berechtigt_user_id = user.id') + ->where('tournament.reminder_count < 3') + ->group('tournament.turnier_id, tournament.turnierbezeichnung'); + $rows = loadObjectList($db, $query); + + if(!empty($rows)) { + $mailFrom = $app->getCfg('mailfrom'); + $fromName = $app->getCfg('fromname'); + + $mailer = Factory::getContainer()->get(MailerFactoryInterface::class)->createMailer(); + $mailer->setSender($mailFrom, $fromName); + foreach ($rows as $row) { + $currentReminder = $row->reminder_count + 1; + + if (hasResultsAlready($db, $row)) { + updateDBReminders($db, $row, 3); // do not sent any more reminders + continue; + } + + if (!isset($row->emails) || $row->emails == "" || $row->emails == NULL) { + Log::add('can\'t sent ' . $currentReminder .'. email reminder for tournament ' . $row->turnierbezeichnung . ': no recipient set', Log::WARNING, 'com_sportsmanager'); + continue; + } + + $now = new DateTime(); + $last_day = new DateTime($row->letzter_tag); + $last_day->modify('+1 day'); // start to count at the end of the day, not at the beginning + $diff = $now->getTimestamp() - $last_day->getTimestamp(); + + $reminderDelays = [ + 1 => 24*60*60, // 24h + 2 => 3*24*60*60, // 3d + 3 => 13*24*60*60 // 13d + ]; + + foreach ($reminderDelays as $count => $delay) { + if ($diff >= $delay && $row->reminder_count < $count) { + $subject = ($row->reminder_count == 2 ? "Letzte " : "") . "Erinnerung: " . $row->turnierbezeichnung . " Ergebnisse einreichen!"; + $body = "Hi," + . "\n\nDies ist die " . $currentReminder . ". " . ($row->reminder_count == 2 ? "*und damit letzte* " : "") . "Erinnerung die Turnierergebnisse einzureichen." + . "\n\nTurnier: " . $row->turnierbezeichnung + . "\nTurnierende: " . FormatiertesDatum($row->letzter_tag, false, false) + . "\n\nLaut Turnierordnung müssen die Ergebnisse spätestens 24 Stunden nach Turnierende eingetragen werden. Bitte reich die Ergebnisse umgehend nach." + . "\n\nDu erhältst diese Mail, weil du als Berechtigter für das Turnier eingetragen wurdest. Falls du nicht der Veranstalter bist, leite diese Email bitte entsprechend weiter." + . "\n\nHochladen der Ergebnisse über " . SportsManagerURL('&task=admin_turnierdisziplinen&turnierid=' . $row->turnier_id, -1) . "."; + + $mailer->setSubject($subject); + $mailer->setBody($body); + + $emailArray = explode(", ", $row->emails); + foreach ($emailArray as $email) { + $mailer->addBcc($email); + } + $mailer->send(); + + updateDBReminders($db, $currentReminder, $row->turnier_id); + } + } + } + } +} + +function updateDBReminders($db, $reminder, $tournamentId): void +{ + $query = $db->getQuery(true) + ->update($db->quoteName('#__sportsmanager_turnier')) + ->set($db->quoteName('reminder_count') . ' = ' . $db->quote($reminder)) + ->where($db->quoteName('turnier_id') . ' = ' . $db->quote($tournamentId)); + + $db->setQuery($query); + $db->execute(); +} + +/** + * checks if a tournament has at least one result entry for a discipline + * @param $db + * @param $row mixed tournament entry + * @return bool true if at least one result is given, else false + * @since 2.2 + */ +function hasResultsAlready($db, mixed $row): bool +{ + $subQuery = $db->getQuery(true) + ->select($db->quoteName('turnierdisziplin_id')) + ->from($db->quoteName('#__sportsmanager_turnierdisziplin')) + ->where($db->quoteName('turnier_id') . ' = ' . $db->quote($row->turnier_id)); + + $query = $db->getQuery(true) + ->select('COUNT(*) AS count') + ->from($db->quoteName('#__sportsmanager_turniermeldung', 'tm')) + ->where($db->quoteName('tm.turnierdisziplin_id') . ' IN (' . $subQuery . ')'); + + $result = loadResult($db, $query); + return $result && $result[0]->count > 0; +} diff --git a/src/structure/components/com_sportsmanager/views/sportsmanager/view_admin.php b/src/structure/components/com_sportsmanager/views/sportsmanager/view_admin.php index bc7a059..ab99e95 100644 --- a/src/structure/components/com_sportsmanager/views/sportsmanager/view_admin.php +++ b/src/structure/components/com_sportsmanager/views/sportsmanager/view_admin.php @@ -737,8 +737,9 @@ class HTML_sportsmanager_admin - id="show_member_count" name="anzahl_mitglieder_zeigen" placeholder="Zahl eingeben"> + name="anzahl_mitglieder_zeigen" placeholder="Zahl eingeben"> @@ -876,6 +877,22 @@ class HTML_sportsmanager_admin + + + + + + + +   @@ -11369,20 +11386,6 @@ class HTML_sportsmanager_admin class="componentheadingget('pageclass_sfx'); ?>"> : - -
@@ -11565,8 +11568,8 @@ class HTML_sportsmanager_admin +
@@ -11595,14 +11599,51 @@ class HTML_sportsmanager_admin
- "/> "/> + "/>
+ + setQuery( $query ); if (!$db->execute()) { die($db->stderr(true)); } - $query = "INSERT IGNORE #__sportsmanager_einstellungen SET name = 'datenbank_version', wert = '107';"; + $query = "INSERT IGNORE #__sportsmanager_einstellungen SET name = 'datenbank_version', wert = '108';"; $db->setQuery( $query ); if (!$db->execute()) { die($db->stderr(true)); } @@ -1144,15 +1145,19 @@ return new class () implements InstallerScriptInterface $query = "INSERT IGNORE #__sportsmanager_einstellungen SET name = 'verband_anzeigen', wert = '1';"; $db->setQuery( $query ); if (!$db->execute()) { die($db->stderr(true)); } - + $query = "INSERT IGNORE #__sportsmanager_einstellungen SET name = 'turnierbaum_zeigen', wert = '0';"; $db->setQuery( $query ); if (!$db->execute()) { die($db->stderr(true)); } - + $query = "INSERT IGNORE #__sportsmanager_einstellungen SET name = 'spalte_mitglieder_zeigen', wert = '1';"; $db->setQuery( $query ); if (!$db->execute()) { die($db->stderr(true)); } - + + $query = "INSERT IGNORE #__sportsmanager_einstellungen SET name = 'enable_email_reminders', wert = '0';"; + $db->setQuery( $query ); + if (!$db->execute()) { die($db->stderr(true)); } + $query = "INSERT INTO #__sportsmanager_verschieberegel (bezeichnung, initial_ohne_termin, keine_gegenvorschlaege, vorlaufzeit_tage, termine_minimal, termine_maximal, ablehnen)" . "\n VALUES ('Beliebig', '0', '0', '0', '1', '3', '0');"; $db->setQuery($query);