Skip to content

Commit

Permalink
rework mailing system
Browse files Browse the repository at this point in the history
- add PHPMailer 6.7.1 (slimmed down, without language files)
- replace inline messages by templates
- send HTML and plaintext mails
- fix after-round mails and game reset
  • Loading branch information
bratkartoffel committed Apr 5, 2023
1 parent 7dee780 commit c3c67ea
Show file tree
Hide file tree
Showing 41 changed files with 8,891 additions and 322 deletions.
20 changes: 20 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
root = true

[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = false
max_line_length = 120
tab_width = 4
ij_continuation_indent_size = 8
ij_formatter_off_tag = @formatter:off
ij_formatter_on_tag = @formatter:on
ij_formatter_tags_enabled = true
ij_smart_tabs = false
ij_visual_guides = none
ij_wrap_on_typing = false

[*.txt.tpl]
trim_trailing_whitespace = false
2 changes: 2 additions & 0 deletions .htaccess
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@
RedirectMatch 403 /doc
RedirectMatch 403 /include
RedirectMatch 403 /install/sql
RedirectMatch 403 /mails
RedirectMatch 403 /pages
RedirectMatch 403 /pics/uploads
RedirectMatch 403 /tests
RedirectMatch 403 /vendor
</IfModule>

# cache images, scripts and styles for 1 day
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- (mailing) add PHPMailer for sending mails, allow manual configuration

### Fixed

- (reset) reset player stock for the items added in `1.11.5`
- (reset) send out mails on round end
- (bank) allow larger values for bank and money (needed for bank level 10+)

## [1.11.9] - 2023-03-31
Expand Down
13 changes: 5 additions & 8 deletions actions/einstellungen.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,15 +122,12 @@
}

$email_activation_code = createRandomCode();
$email_activation_link = Config::get(Config::SECTION_BASE, 'base_url') . '/actions/activate.php?email=' . urlencode($email) . '&amp;code=' . $email_activation_code;
$email_activation_link = sprintf('%s/actions/activate.php?email=%s&code=%s', Config::get(Config::SECTION_BASE, 'base_url'), urlencode($email), $email_activation_code);

if (!sendMail($email, Config::get(Config::SECTION_BASE, 'game_title') . ': Aktivierung Ihres Accounts',
'<html lang="de"><body><h3>Willkommen beim Bioladenmanager 2,</h3>
<p>Doch bevor Sie Ihr eigenes Imperium aufbauen können, müssen Sie Ihren Account aktivieren. Klicken Sie hierzu bitte auf folgenden Link:</p>
<p><a href="' . $email_activation_link . '">' . $email_activation_link . '</a></p>
<p>Falls Sie sich nicht bei diesem Spiel registriert haben, so leiten Sie die EMail bitte ohne Bearbeitung weiter an: ' . Config::get(Config::SECTION_BASE, 'admin_email') . '</p>
Grüsse ' . Config::get(Config::SECTION_BASE, 'admin_name') . '</body></html>'
)) {
if (!sendMail($email, Config::get(Config::SECTION_BASE, 'game_title') . ': Änderung EMail-Addresse', 'email_change', array(
'{{USERNAME}}' => escapeForOutput(Database::getInstance()->getPlayerNameById($_SESSION['blm_user'])),
'{{ACTIVATION_LINK}}' => $email_activation_link,
))) {
redirectTo(sprintf('/?p=einstellungen&email=%s', $email), 150, __LINE__);
}

Expand Down
61 changes: 25 additions & 36 deletions actions/pwd_reset.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,41 +13,20 @@

$email = getOrDefault($_POST, 'email');

function sendRecoveryMail(string $email, array $data, string $token): bool
function sendRecoveryMail(string $email, string $name, string $resetLink): bool
{
return sendMail($email, Config::get(Config::SECTION_BASE, 'game_title') . ': Passwort vergessen',
sprintf('<html lang="de"><body><h3>Hallo %s,</h3>
die Funktion "Passwort vergessen" wurde bei deinem Account ausgelöst. Wenn du das selbst warst, dann kannst du über folgende Link
dein Passwort zurücksetzen:
<p>
<a href="%s/actions/pwd_reset.php?a=2&amp;id=%d&amp;token=%s">%s/actions/pwd_reset.php?a=2&amp;id=%d&amp;token=%s</a>
</p>
<p>
Klicke bitte nur auf den Link, wenn du die Anfrage auch selbst ausgelöst hast. Wenn du die Anfrage nicht gestellt hast,
dann wende dich bitte an einen Administrator. Diesen kannst du entweder im Spiel oder auch per Mail erreichen: %s
</p>
Grüsse,
%s
</body></html>
', escapeForOutput($data['Name']), Config::get(Config::SECTION_BASE, 'base_url'), $data['ID'], $token, Config::get(Config::SECTION_BASE, 'base_url'), $data['ID'], $token, Config::get(Config::SECTION_BASE, 'admin_email'), Config::get(Config::SECTION_BASE, 'admin_name')
));
return sendMail($email, Config::get(Config::SECTION_BASE, 'game_title') . ': Passwort vergessen', 'password_recovery', array(
'{{USERNAME}}' => escapeForOutput($name),
'{{RESET_LINK}}' => $resetLink,
));
}

function sendPasswordMail(string $email, string $name, string $password): bool
{
return sendMail($email, Config::get(Config::SECTION_BASE, 'game_title') . ': Passwort vergessen',
sprintf('<html lang="de"><body><h3>Hallo %s,</h3>
dein Passwort wurde zurückgesetzt auf:
<p>%s</p>
Grüsse,
%s
</body></html>
', escapeForOutput($name), $password, Config::get(Config::SECTION_BASE, 'admin_name')
));
return sendMail($email, Config::get(Config::SECTION_BASE, 'game_title') . ': Dein neues Passwort', 'password_reset', array(
'{{USERNAME}}' => escapeForOutput($name),
'{{PASSWORD}}' => $password,
));
}

switch (getOrDefault($_REQUEST, 'a')) {
Expand All @@ -69,11 +48,16 @@ function sendPasswordMail(string $email, string $name, string $password): bool
if (strtotime($request['created']) < time() - (3600 * 4)) {
Database::getInstance()->begin();
if (Database::getInstance()->updateTableEntry(Database::TABLE_PASSWORD_RESET, $request['ID'],
array('created' => date('Y-m-d H:i:s'))) !== 1) {
array('created' => date('Y-m-d H:i:s'))) !== 1) {
Database::getInstance()->rollBack();
redirectTo($back_link, 142, __LINE__);
}
if (!sendRecoveryMail($email, $data, $request['token'])) {
$link = sprintf('%s/actions/pwd_reset.php?a=2&id=%d&token=%s',
Config::get(Config::SECTION_BASE, 'base_url'),
$data['ID'],
$request['token']
);
if (!sendRecoveryMail($email, $data['Name'], $link)) {
Database::getInstance()->rollBack();
redirectTo($back_link, 172, __LINE__);
}
Expand All @@ -89,13 +73,18 @@ function sendPasswordMail(string $email, string $name, string $password): bool
$token = createRandomCode();
Database::getInstance()->begin();
if (Database::getInstance()->createTableEntry(Database::TABLE_PASSWORD_RESET, array(
'user_id' => $data['ID'],
'token' => $token
)) !== 1) {
'user_id' => $data['ID'],
'token' => $token
)) !== 1) {
Database::getInstance()->rollBack();
redirectTo($back_link, 141, __LINE__);
}
if (!sendRecoveryMail($email, $data, $token)) {
$link = sprintf('%s/actions/pwd_reset.php?a=2&id=%d&token=%s',
Config::get(Config::SECTION_BASE, 'base_url'),
$data['ID'],
$token
);
if (!sendRecoveryMail($email, $data['Name'], $link)) {
Database::getInstance()->rollBack();
redirectTo($back_link, 172, __LINE__);
}
Expand Down
14 changes: 6 additions & 8 deletions actions/registrieren.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,12 @@
}
Database::getInstance()->commit();

$email_activation_link = Config::get(Config::SECTION_BASE, 'base_url') . '/actions/activate.php?user=' . urlencode($name) . '&amp;code=' . $email_activation_code;
if (!sendMail($email, Config::get(Config::SECTION_BASE, 'game_title') . ': Aktivierung Ihres Accounts',
'<html lang="de"><body><h3>Hallo ' . escapeForOutput($name) . ' und Willkommen beim Bioladenmanager 2,</h3>
<p>Doch bevor Sie Ihr eigenes Imperium aufbauen können, müssen Sie Ihren Account aktivieren. Klicken Sie hierzu bitte auf folgenden Link:</p>
<p><a href="' . $email_activation_link . '">' . $email_activation_link . '</a></p>
<p>Falls Sie sich nicht bei diesem Spiel registriert haben, so leiten Sie die EMail bitte ohne Bearbeitung weiter an: ' . Config::get(Config::SECTION_BASE, 'admin_email') . '</p>
Grüsse ' . Config::get(Config::SECTION_BASE, 'admin_name') . '</body></html>'
)) {
$email_activation_link = sprintf('%s/actions/activate.php?user=%s&code=%s', Config::get(Config::SECTION_BASE, 'base_url'), urlencode($name), $email_activation_code);

if (!sendMail($email, Config::get(Config::SECTION_BASE, 'game_title') . ': Registrierung', 'registration', array(
'{{USERNAME}}' => escapeForOutput($name),
'{{ACTIVATION_LINK}}' => $email_activation_link,
))) {
redirectTo(sprintf('/?p=anmelden&name=%s', $name), 144, __LINE__);
}

Expand Down
12 changes: 12 additions & 0 deletions config/config-defaults.ini
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,18 @@ export_hmac = sha3-512
; default is 20 MiB
import_max_table_size = 20971520

[mail]
; hostname to connect to
hostname = "localhost"
; port to connect to
port = 25
; enable authentication
authentication = false
; authentication username
username = someone
; authentication password
password = secret

[database]
; hostname to connect to
hostname = "localhost"
Expand Down
1 change: 1 addition & 0 deletions cronjobs/cron.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

const IS_CRON = true;
require_once __DIR__ . '/../include/functions.inc.php';
require_once __DIR__ . '/../include/game_version.inc.php';
require_once __DIR__ . '/../include/database.class.php';

if (!IS_CRON) {
Expand Down
1 change: 1 addition & 0 deletions include/config.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
class Config
{
public const SECTION_BASE = 'base';
public const SECTION_MAIL = 'mail';
public const SECTION_CAPTCHA = 'captcha';
public const SECTION_DATABASE = 'database';
public const SECTION_PLANTAGE = 'plantage';
Expand Down
98 changes: 37 additions & 61 deletions include/database.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -418,14 +418,7 @@ public function getLeaderOnlineTime(int $count = 1): ?array
WHERE ID > 0
ORDER BY Onlinezeit DESC, ID LIMIT 0, :limit');
$stmt->bindParam('limit', $count, PDO::PARAM_INT);
$result = $this->executeAndExtractRows($stmt);
if (count($result) == 0) {
return null;
} elseif ($count == 1) {
return $result[0];
} else {
return $result;
}
return $this->executeAndExtractRows($stmt);
}

public function getLeaderMafia(int $count = 1): ?array
Expand All @@ -434,14 +427,36 @@ public function getLeaderMafia(int $count = 1): ?array
FROM ' . self::TABLE_USERS . ' m INNER JOIN ' . self::TABLE_STATISTICS . ' s ON m.ID = s.user_id
ORDER BY s.AusgabenMafia DESC, m.ID LIMIT 0, :limit');
$stmt->bindParam('limit', $count, PDO::PARAM_INT);
$result = $this->executeAndExtractRows($stmt);
if (count($result) == 0) {
return null;
} elseif ($count == 1) {
return $result[0];
} else {
return $result;
}
return $this->executeAndExtractRows($stmt);
}

public function getMafiaGodfather(int $count = 1): ?array
{
$stmt = $this->prepare('WITH x AS (
SELECT senderName, receiverName, action, success FROM ' . self::TABLE_LOG_MAFIA . ' m GROUP BY senderId, created
)
SELECT senderName, COUNT(*) AS cnt, SUM(success) AS success FROM x GROUP BY senderName ORDER BY cnt DESC LIMIT 0, :limit');
$stmt->bindParam('limit', $count, PDO::PARAM_INT);
return $this->executeAndExtractRows($stmt);
}

public function getMafiaVictim(int $count = 1): ?array
{
$stmt = $this->prepare('WITH x AS (
SELECT senderName, receiverName, action, success FROM ' . self::TABLE_LOG_MAFIA . ' m GROUP BY senderId, created
)
SELECT receiverName, COUNT(*) AS cnt, SUM(success) AS success FROM x GROUP BY receiverName ORDER BY cnt DESC LIMIT 0, :limit');
$stmt->bindParam('limit', $count, PDO::PARAM_INT);
return $this->executeAndExtractRows($stmt);
}

public function getMafiaAttackTypes(): ?array
{
$stmt = $this->prepare('WITH x AS (
SELECT senderName, receiverName, action, success, SUM(amount) as amount FROM ' . self::TABLE_LOG_MAFIA . ' m GROUP BY senderId, created
)
SELECT action, COUNT(*) AS cnt, SUM(success) AS success, SUM(amount) as amount FROM x GROUP BY action ORDER BY cnt DESC');
return $this->executeAndExtractRows($stmt);
}

public function getLeaderMarket(int $count = 1): ?array
Expand All @@ -450,14 +465,7 @@ public function getLeaderMarket(int $count = 1): ?array
FROM ' . self::TABLE_USERS . ' m INNER JOIN ' . self::TABLE_STATISTICS . ' s ON m.ID = s.user_id
ORDER BY s.AusgabenMarkt DESC, m.ID LIMIT 0, :limit');
$stmt->bindParam('limit', $count, PDO::PARAM_INT);
$result = $this->executeAndExtractRows($stmt);
if (count($result) == 0) {
return null;
} elseif ($count == 1) {
return $result[0];
} else {
return $result;
}
return $this->executeAndExtractRows($stmt);
}

public function getLeaderBuildings(int $count = 1): ?array
Expand All @@ -466,14 +474,7 @@ public function getLeaderBuildings(int $count = 1): ?array
FROM ' . self::TABLE_USERS . ' m INNER JOIN ' . self::TABLE_STATISTICS . ' s ON m.ID = s.user_id
ORDER BY s.AusgabenGebaeude DESC, m.ID LIMIT 0, :limit');
$stmt->bindParam('limit', $count, PDO::PARAM_INT);
$result = $this->executeAndExtractRows($stmt);
if (count($result) == 0) {
return null;
} elseif ($count == 1) {
return $result[0];
} else {
return $result;
}
return $this->executeAndExtractRows($stmt);
}

public function getLeaderResearch(int $count = 1): ?array
Expand All @@ -482,14 +483,7 @@ public function getLeaderResearch(int $count = 1): ?array
FROM ' . self::TABLE_USERS . ' m INNER JOIN ' . self::TABLE_STATISTICS . ' s ON m.ID = s.user_id
ORDER BY s.AusgabenForschung DESC, m.ID LIMIT 0, :limit');
$stmt->bindParam('limit', $count, PDO::PARAM_INT);
$result = $this->executeAndExtractRows($stmt);
if (count($result) == 0) {
return null;
} elseif ($count == 1) {
return $result[0];
} else {
return $result;
}
return $this->executeAndExtractRows($stmt);
}

public function getLeaderProduction(int $count = 1): ?array
Expand All @@ -499,13 +493,7 @@ public function getLeaderProduction(int $count = 1): ?array
ORDER BY s.AusgabenProduktion DESC, m.ID LIMIT 0, :limit');
$stmt->bindParam('limit', $count, PDO::PARAM_INT);
$result = $this->executeAndExtractRows($stmt);
if (count($result) == 0) {
return null;
} elseif ($count == 1) {
return $result[0];
} else {
return $result;
}
return $this->executeAndExtractRows($stmt);
}

public function getLeaderInterest(int $count = 1): ?array
Expand All @@ -515,13 +503,7 @@ public function getLeaderInterest(int $count = 1): ?array
ORDER BY s.EinnahmenZinsen DESC, m.ID LIMIT 0, :limit');
$stmt->bindParam('limit', $count, PDO::PARAM_INT);
$result = $this->executeAndExtractRows($stmt);
if (count($result) == 0) {
return null;
} elseif ($count == 1) {
return $result[0];
} else {
return $result;
}
return $this->executeAndExtractRows($stmt);
}

public function getLeaderIgmSent(int $count = 1): ?array
Expand All @@ -532,13 +514,7 @@ public function getLeaderIgmSent(int $count = 1): ?array
ORDER BY IgmGesendet DESC, ID LIMIT 0, :limit');
$stmt->bindParam('limit', $count, PDO::PARAM_INT);
$result = $this->executeAndExtractRows($stmt);
if (count($result) == 0) {
return null;
} elseif ($count == 1) {
return $result[0];
} else {
return $result;
}
return $this->executeAndExtractRows($stmt);
}

public function getAdminBioladenLogCount(?string $werFilter, ?int $wareFilter): ?int
Expand Down
Loading

0 comments on commit c3c67ea

Please sign in to comment.