diff --git a/CHANGELOG.md b/CHANGELOG.md index af819ea28..c858029fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,8 +49,10 @@ We could not reconstruct _all_ changes, but we tried our best to make the most o - [Installation] Added database value User@Server into MySQL error message - [Installation] Added check for incompatible SQL Modes to the first installation page - [Installation] If there is no `config.php` file available during installation, create it during setup from the default config +- [Info2] Added ability to replace variables in info texts and to see disabled info pages for admins - [Discord] Introduced a new module to manage Discord Servers - [Party] Add information `Gesamt` in the Party box to show how many people can sign up for a party +- [Party] Added ability to switch party in internet system for admins - [Birthday] New module to show users birthdays - [Hall of fame] New module to present all tournament winners in a Hall of Fame - [Server] Added Voice as server type diff --git a/inc/Classes/Display.php b/inc/Classes/Display.php index 482b207f5..62169be46 100644 --- a/inc/Classes/Display.php +++ b/inc/Classes/Display.php @@ -1278,9 +1278,11 @@ public function FetchIcon($picname, $link = '', $hint = null, $target = null, $a } /** - * @param int $userid - * @param string $username - * @return string + * Adds user icon and username based on template ls_usericon.htm to output + * + * @param int $userid The numeric user id to fetch the icon for + * @param string $username The username to display, empty if not given + * @return string raw html for output * @throws \Exception * @throws \SmartyException */ @@ -1293,7 +1295,7 @@ public function FetchUserIcon($userid, $username = '') } $smarty->assign('userid', $userid); - $smarty->assign('username', $username); + $smarty->assign('username', htmlspecialchars($username)); // username may contain special characters $smarty->assign('hint', t('Benutzerdetails aufrufen')); if (in_array($userid, $authentication->online_users)) { diff --git a/inc/Classes/Func.php b/inc/Classes/Func.php index 5a68ecb5b..fe5445866 100644 --- a/inc/Classes/Func.php +++ b/inc/Classes/Func.php @@ -353,7 +353,7 @@ public function AllowHTML($string) } /** - * Transforms given input text to HTML-enriched output. + * Transforms given input text to HTML-enriched output. * Based on the mode provided, various tags are allowed. * These are - to my understanding - as follows: * mode 0: Full BBcode parsing, Smileys @@ -367,7 +367,7 @@ public function AllowHTML($string) public function text2html($string, $mode = 0) { global $db, $database; - + if ($mode == 0) { $parser = new \Youthweb\BBCodeParser\Manager(); @@ -612,7 +612,7 @@ public function log_event($message, $type = 1, $sort_tag = '', $target_id = '') $userId = $auth['userid'] ?? 0; $entry = $db->qry(" - INSERT INTO %prefix%log + INSERT INTO %prefix%log SET userid = %int%, description=%string%, @@ -986,7 +986,7 @@ public function CheckNewPosts($last_change, $table, $entryid, $userid = 0) return 1; } else { $last_read = $database->queryWithOnlyFirstRow(' - SELECT UNIX_TIMESTAMP(date) AS date + SELECT UNIX_TIMESTAMP(date) AS date FROM %prefix%lastread WHERE userid = ? AND tab = ? AND entryid = ?', [$userid, $table, $entryid]); @@ -1118,4 +1118,53 @@ public function isModActive($mod, &$caption = '') return array_key_exists($mod, $this->ActiveModules); } + + /** + * Searches through a text and replaces occurences of %VARIABLENAME% with their counterpart. + * Just has basic stuff required to make information pages more dynamic, more to be added + * Be careful that you only expose uncritical commonly visible values or user-specifc information, otherwise this could be used to leak important data. + * + * @param string $text The text to replace placeholders in + * + * @global array $auth fetches userid for replacement + * + * @return string The text with placeholders replaced + */ + public function replaceVariables($text) { + global $auth; + + //initialize replacement array + $placeholderNames = []; + $replacementValues = []; + + if (array_key_exists('userid', $auth)) { + $placeholderNames []= '%USERID%'; + $replacementValues []= $auth['userid']; + } + + if (array_key_exists('username', $auth)) { + $placeholderNames []= '%USERNAME%'; + $replacementValues []= $auth['username']; + } + + if (array_key_exists('party_id', $_SESSION)) { + $placeholderNames []= '%PARTYID%'; + $replacementValues []= $_SESSION['party_id']; + } + + + //fetch partyprice... + $party = new \LanSuite\Module\Party\Party(); + $entrancedata = $party->GetUserParticipationData(); + if ($entrancedata) { + $placeholderNames []= '%PARTYPRICEID%'; + $replacementValues []= $entrancedata['price_id']; + $placeholderNames []= '%PARTYPRICETEXT%'; + $replacementValues []= $entrancedata['price_text']; + $placeholderNames []= '%PARTYPRICEVALUE%'; + $replacementValues []= $entrancedata['price']; + } + + return str_replace($placeholderNames, $replacementValues, $text); + } } diff --git a/modules/faq/show.php b/modules/faq/show.php index 01430846e..f07f0f27e 100644 --- a/modules/faq/show.php +++ b/modules/faq/show.php @@ -2,6 +2,8 @@ $get_cat = $db->qry("SELECT catid, name FROM %prefix%faq_cat ORDER BY name"); $count_cat = $db->num_rows($get_cat); +$admin_link = ''; + if ($count_cat == 0) { $func->information(t('Keine Einträge vorhanden.'), "index.php?mod=home"); } else { @@ -9,17 +11,19 @@ while ($row = $db->fetch_array($get_cat)) { if ($auth['type'] > \LS_AUTH_TYPE_ADMIN) { - $admin_link = $dsp->FetchIcon('delete', 'index.php?mod=faq&object=item&action=delete_cat&catid=' . $row["catid"] . '&step=2'); + $admin_link .= $dsp->FetchIcon('delete', 'index.php?mod=faq&object=item&action=delete_cat&catid=' . $row["catid"] . '&step=2'); } if ($auth['type'] > \LS_AUTH_TYPE_USER) { $admin_link .= $dsp->FetchIcon('edit', 'index.php?mod=faq&object=cat&action=change_cat&catid=' . $row["catid"] . '&step=2'); } + $dsp->AddFieldsetStart($admin_link . $row["name"]); $get_item = $db->qry("SELECT caption,itemid FROM %prefix%faq_item WHERE catid = %int% ORDER BY caption", $row['catid']); + $admin_link = ''; while ($row = $db->fetch_array($get_item)) { if ($auth['type'] > \LS_AUTH_TYPE_ADMIN) { - $admin_link = $dsp->FetchIcon('delete', 'index.php?mod=faq&object=item&action=delete_item&itemid=' . $row["itemid"] . '&step=2'); + $admin_link .= $dsp->FetchIcon('delete', 'index.php?mod=faq&object=item&action=delete_item&itemid=' . $row["itemid"] . '&step=2'); } if ($auth['type'] > \LS_AUTH_TYPE_USER) { $admin_link .= $dsp->FetchIcon('edit', 'index.php?mod=faq&object=cat&action=change_item&itemid=' . $row["itemid"] . '&step=2'); diff --git a/modules/info2/mod_settings/config.xml b/modules/info2/mod_settings/config.xml index 8230853bd..c1c6e75f1 100644 --- a/modules/info2/mod_settings/config.xml +++ b/modules/info2/mod_settings/config.xml @@ -5,12 +5,6 @@ Allgemein - - info2_toolbar - boolean - 1 - Erweiterte Toolbar - info2_use_fckedit boolean diff --git a/modules/info2/show.php b/modules/info2/show.php index 75da53773..7d4b607bb 100644 --- a/modules/info2/show.php +++ b/modules/info2/show.php @@ -18,16 +18,19 @@ $dsp->NewContent("{$info["caption$val"]}", $info["shorttext$val"]); $framework->addToPageTitle($info["caption$val"]); - if ($info['active'] == 1) { + if ($info['active'] == 1 || $auth['type'] > \LS_AUTH_TYPE_USER) { if ($info["text$val"] == null) { $func->information(t("Es liegen Informationen zu der ausgewählten Seite vor, jedoch nicht in deiner aktuell gewählten Sprache: %1", $language)); } else { - $dsp->AddSingleRow($func->AllowHTML($info["text$val"]), '', 'textContent'); + $dsp->AddSingleRow($func->replaceVariables($func->AllowHTML($info["text$val"]), '', 'textContent')); + if (!$info['active']) { + $func->information(t('Diese Info-Seite ist nicht aktiviert. Ein Admin muss sie zuerst im Info-Modul aktivieren')); + } } } else { $func->error(t('Diese Info-Seite ist nicht aktiviert. Ein Admin muss sie zuerst im Info-Modul aktivieren')); } - + // Show edit/aktivate Buttons // TODO add delete if ($auth['type'] > \LS_AUTH_TYPE_USER) { diff --git a/modules/party/Classes/Party.php b/modules/party/Classes/Party.php index d5ea423dc..22d6a7877 100644 --- a/modules/party/Classes/Party.php +++ b/modules/party/Classes/Party.php @@ -21,7 +21,7 @@ class Party public function __construct($party_id = null) { - global $cfg, $db, $database, $request; + global $cfg, $database, $request; $setPartyIDGETParameter = $request->query->get('set_party_id'); $setPartyIDPOSTParameter = $request->request->get('set_party_id'); @@ -48,7 +48,9 @@ public function __construct($party_id = null) $this->party_id = $party_id; } + //@TODO: We should not switch the party just because somebody used this class $_SESSION['party_id'] = $this->party_id; + $this->UpdatePartyArray(); } @@ -209,7 +211,7 @@ public function add_user_to_party($user_id, $price_id = "0", $paid = "NULL", $ch */ private function update_user_at_party($user_id, $paid, $price_id = "0", $checkin = "0", $checkout = "0", $seatcontrol = "NULL") { - global $db, $database, $func; + global $cache, $db, $database, $func; $timestamp = time(); if ($checkin == "1") { @@ -247,6 +249,9 @@ private function update_user_at_party($user_id, $paid, $price_id = "0", $checkin $msg = str_replace("%PARTY%", $this->party_id, str_replace("%ID%", $user_id, str_replace("%PIRCEID%", $price_id, str_replace("%SEATCONTROL%", $seatcontrol, str_replace("%CHECKOUT%", $checkout, str_replace("%CHECKIN%", $checkin, str_replace("%PAID%", $paid, t('Die Anmeldung von %ID% bei der Party %PARTY% wurde geändert. Neu: Bezahlt = %PAID%, Checkin = %CHECKIN%, Checkout = %CHECKOUT%, Pfand = %SEATCONTROL%, Preisid = %PIRCEID%')))))))); $func->log_event($msg, 1); $db->qry('UPDATE %prefix%party_user SET %plain%', $query); + + // reset cached party statistics + $cache->delete('party.guestcount.' . $this->party_id); } /** @@ -258,7 +263,7 @@ private function update_user_at_party($user_id, $paid, $price_id = "0", $checkin public function delete_user_from_party($user_id) { $checkin = null; - global $db, $database, $cfg; + global $cache, $database, $cfg; $timestamp = time(); if ($checkin == "1" || $cfg["signon_autocheckin"] == "1") { @@ -267,11 +272,14 @@ public function delete_user_from_party($user_id) $checkin = "0"; } - $db->qry(" + $database->query(" DELETE FROM %prefix%party_user WHERE - user_id = %int% - AND party_id = %int%", $user_id, $this->party_id); + user_id = ? + AND party_id = ?", [$user_id, $this->party_id]); + + // reset cached party statistics + $cache->delete('party.guestcount.' . $this->party_id); } /** @@ -339,7 +347,7 @@ public function get_user_group_dropdown($group_id = "NULL", $nogroub = 0, $selec * @param string $select_opts * @return void */ - public function add_user_group($group, $description, $selection, $select_opts) + public function addUsergroup($group, $description, $selection, $select_opts) { global $db, $database; @@ -355,25 +363,26 @@ public function add_user_group($group, $description, $selection, $select_opts) /** * Change a user group * - * @param int $group_id - * @param string $group - * @param string $description + * @param int $groupId Id of the user group to change + * @param string $groupName The (new) name of the group + * @param string $description Description of the group * @param string $selection * @param string $select_opts * @return void */ - public function update_user_group($group_id, $group, $description, $selection, $select_opts) + public function updateUserGroup($groupId, $groupName, $description, $selection, $select_opts) { - global $db, $database; + global $database; - $db->qry(" + $database->query(" UPDATE %prefix%party_usergroups SET - group_name = %string%, - description = %string%, - selection = %string%, - select_opts = %string% - WHERE group_id = %int%", $group, $description, $selection, $select_opts, $group_id); + group_name = ?, + description = ?, + selection = ?, + select_opts = ? + WHERE group_id = ?", [$groupName, $description, $selection, $select_opts, $groupId] + ); } /** @@ -390,37 +399,51 @@ public function delete_usergroups($del_group, $set_group) $database->query("UPDATE %prefix%user SET group_id = ? WHERE group_id = ?", [$set_group, $del_group]); $database->query("DELETE FROM %prefix%party_usergroups WHERE group_id = ?", [$del_group]); } - + /** * Returns the amount of users registered for a party. - * - * @param int $party_id The ID of the party to calculate this for + * + * @param int $partyId The ID of the party to calculate this for (uses object value otherwise) + * @param * @return array Result array with elements "qty" and "paid" */ - public function getGuestQty($party_id = NULL) + public function getGuestQty($partyId = null, $showOrga = null) { - $cfg = []; - $db = null; - global $cache; - - if (empty($party_id)) { - $party_id = $this->party_id; - } - - $partyCache = $cache->getItem('party.guestcount.' . $party_id); + global $cfg, $cache, $database; + + $partyIdParameter = $partyId ?? $this->party_id; + $showOrgaParameter = $showOrga ?? $cfg["guestlist_showorga"]; + + $partyCache = $cache->getItem('party.guestcount.' . $partyIdParameter); if (!$partyCache->isHit()) { - // Fetch in one query - if ($cfg["guestlist_showorga"] == 0) { - $querytype = "type = 1"; - } else { + // Include Admins or not + if ($showOrgaParameter) { $querytype = "type >= 1"; + } else { + $querytype = "type = 1"; } // Fetch amounts from DB - $countQry = $db->qry('SELECT COUNT(*) as qty, party.paid as paid FROM %prefix%user as user LEFT JOIN %prefix%party_user as party ON user.userid = party.user_id WHERE party_id=%int% AND (%plain%) GROUP BY paid ORDER BY paid DESC;'); - while ($guestCounts = $countQry->fetch_array()){} + $guestCounts = $database->queryWithOnlyFirstRow('SELECT COUNT(*) as qty, party.paid as paid FROM %prefix%user as user LEFT JOIN %prefix%party_user as party ON user.userid = party.user_id WHERE party_id= ? AND ' . $querytype . ' GROUP BY paid ORDER BY paid DESC;', [$partyIdParameter]); $partyCache->set($guestCounts); $cache->save($partyCache); } return $partyCache->get(); } + + /** + * Get details about this users participation at the party. + * Most prominently the name and price of the entrance ticket + * + * @param int|null $userId The userid to look the status up for + * + * @return array Array with party & Price information + */ + public function getUserParticipationData(int|null $userId = null) : array + { + global $database, $auth; + + $userIdParameter = $userId ?? $auth['userid']; + return $database->queryWithOnlyFirstRow("SELECT * FROM %prefix%party_user AS pu LEFT JOIN %prefix%party_prices AS price ON price.price_id=pu.price_id WHERE user_id= ? and pu.party_id =?", [$userIdParameter, $this->party_id]) ?? []; + } + } diff --git a/modules/party/boxes/signonstatus.php b/modules/party/boxes/signonstatus.php index c37522c2e..39692f185 100644 --- a/modules/party/boxes/signonstatus.php +++ b/modules/party/boxes/signonstatus.php @@ -13,15 +13,15 @@ } // Number of registered users -$get_cur = $db->qry_first('SELECT COUNT(userid) as n FROM %prefix%user AS user WHERE %plain%', $querytype); +$get_cur = $database->queryWithOnlyFirstRow('SELECT COUNT(userid) as n FROM %prefix%user AS user WHERE ' . $querytype, []); $reg = $get_cur["n"]; // Number of users who signed up for the party -$get_cur = $db->qry_first('SELECT COUNT(userid) as n FROM %prefix%user AS user LEFT JOIN %prefix%party_user AS party ON user.userid = party.user_id WHERE party_id=%int% AND (%plain%)', $party->party_id, $querytype); +$get_cur = $database->queryWithOnlyFirstRow('SELECT COUNT(userid) as n FROM %prefix%user AS user LEFT JOIN %prefix%party_user AS party ON user.userid = party.user_id WHERE party_id = ? AND ' . $querytype, [$party->party_id]); $cur = $get_cur["n"]; // Number of users who have signed up and payed -$get_cur = $db->qry_first('SELECT COUNT(userid) as n FROM %prefix%user AS user LEFT JOIN %prefix%party_user AS party ON user.userid = party.user_id WHERE (%plain%) AND (party.paid > 0) AND party_id=%int%', $querytype, $party->party_id); +$get_cur = $database->queryWithOnlyFirstRow('SELECT COUNT(userid) as n FROM %prefix%user AS user LEFT JOIN %prefix%party_user AS party ON user.userid = party.user_id WHERE '. $querytype .' AND (party.paid > 0) AND party_id = ?', [$party->party_id]); $paid = $get_cur["n"]; // Max. attenteed @@ -76,9 +76,9 @@ if ($cfg['sys_internet']) { $options = ''; - $res = $db->qry('SELECT party_id, name FROM %prefix%partys'); - if ($db->num_rows($res) > 1 && $cfg['display_change_party']) { - while ($row = $db->fetch_array($res)) { + $queryResult = $database->queryWithFullResult('SELECT party_id, name FROM %prefix%partys', []); + if (count($queryResult) && $cfg['display_change_party'] || $auth['type'] >= \LS_AUTH_TYPE_ADMIN) { + foreach ($queryResult as $row) { ($row['party_id'] == $party->party_id)? $selected = 'selected="selected"' : $selected = ''; if (strlen($row['name']) > 20) { $row['name'] = substr($row['name'], 0, 18) .'...'; @@ -90,8 +90,7 @@ $partyName = $_SESSION['party_info']['name'] ?? ''; $box->ItemRow("data", ''. $partyName .''); } - $db->free_result($res); - + date_default_timezone_set($cfg['sys_timezone']); $partyBegin = $_SESSION['party_info']['partybegin'] ?? time(); $partyEnd = $_SESSION['party_info']['partyend'] ?? time(); @@ -105,26 +104,26 @@ $box->EngangedRow(t('Frei').': '. ($max - $paid)); if (!$cfg['sys_internet']) { - $checkedin = $db->qry_first(' + $checkedin = $database->queryWithOnlyFirstRow(' SELECT COUNT(p.user_id) as n FROM %prefix%user AS u LEFT JOIN %prefix%party_user AS p ON u.userid = p.user_id WHERE - (%plain%) + ' . $querytype. ' AND (p.checkin > 0) - AND p.party_id = %int%', $querytype, $party->party_id); + AND p.party_id = ?', [$party->party_id]); $box->EngangedRow(t('Eingecheckt').': '. ($checkedin['n'])); - $checkedout = $db->qry_first(' + $checkedout = $database->queryWithOnlyFirstRow(' SELECT COUNT(p.user_id) as n FROM %prefix%user AS u LEFT JOIN %prefix%party_user AS p ON u.userid = p.user_id WHERE - (%plain%) + ' . $querytype. ' AND (p.checkout > 0) - AND p.party_id = %int%', $querytype, $party->party_id); + AND p.party_id = ?', [$party->party_id]); $box->EngangedRow(t('Ausgecheckt').': '. ($checkedout['n'])); } @@ -132,7 +131,7 @@ if ($cfg['sys_internet']) { $box->EmptyRow(); $box->ItemRow("data", ''. t('Counter') .''); - + $partyEnd = $_SESSION['party_info']['partyend'] ?? 0; if ($partyEnd < time()) { $box->EngangedRow(t('Diese Party ist bereits vorüber')); @@ -147,9 +146,9 @@ } else { $count = t('Noch %1 Tage.', array(floor($count/1440))); } - + $box->EngangedRow($count); - + $checked = $database->queryWithOnlyFirstRow("SELECT UNIX_TIMESTAMP(checked) AS n FROM %prefix%partys WHERE party_id = ?", [$party->party_id]); $box->EmptyRow(); $box->ItemRow("data", "". t('Letzter Kontocheck') .""); diff --git a/modules/seating/Classes/Seat2.php b/modules/seating/Classes/Seat2.php index f312d4689..a719c6015 100644 --- a/modules/seating/Classes/Seat2.php +++ b/modules/seating/Classes/Seat2.php @@ -13,7 +13,7 @@ class Seat2 public function SeatNameLink($userid, $MaxBlockLength = 0, $break = '
') { global $db, $database, $party; - + // Unterscheidung Bezahlt oder Unbezahlt (aber nur 1 res. Platz) $seat_paid = $database->queryWithOnlyFirstRow(" SELECT @@ -46,7 +46,7 @@ public function SeatNameLink($userid, $MaxBlockLength = 0, $break = '
') AND s.userid = ? AND s.status = ?", [$party->party_id, $userid, $seat_status]); } - + if (!$row || !$row['blockid']) { return ''; @@ -136,7 +136,7 @@ public function SeatOfUserArray($userid): array|bool s.userid = ? AND s.status = ? AND b.party_id = ?", [$userid, $seat_status, $party->party_id]); - + $blockID = $row['blockid'] ?? 0; if ($blockID) { $arr = array(); @@ -161,7 +161,7 @@ public function SeatOfUserArray($userid): array|bool private function CoordinateToBlockAndName($x, $y, $blockid, $MaxBlockLength = 0, $LinkIt = 0, $userid = 0): bool|string { global $db, $database; - + $row = $database->queryWithOnlyFirstRow(" SELECT name, @@ -175,7 +175,7 @@ private function CoordinateToBlockAndName($x, $y, $blockid, $MaxBlockLength = 0, if ($MaxBlockLength > 4 and strlen($row['name']) > $MaxBlockLength) { $row['name'] = substr($row['name'], 0, $MaxBlockLength - 3) . '...'; } - + $LinkText = $row['name'] .' - '. $this->CoordinateToName($x, $y, $row['orientation']); if ($LinkIt == 1) { return "$LinkText"; @@ -328,7 +328,7 @@ public function DrawPlan($blockid, $mode, $linktarget = '', $selected_user = fal $smarty->assign('row_count', $block['rows'] + 1); $smarty->assign('col_count', $block['cols'] + 1); $smarty->assign('mode', $mode); - + // Get seperators $sep_cols = array(); $sep_rows = array(); @@ -378,7 +378,7 @@ public function DrawPlan($blockid, $mode, $linktarget = '', $selected_user = fal $partyUserCheckin = $party_user['checkin']; $partyUserCheckout = $party_user['checkout']; } - + $seat_state[$seat_row['row']][$seat_row['col']] = $seat_row['status']; $seat_ip[$seat_row['row']][$seat_row['col']] = $seat_row['ip']; $seat_userid[$seat_row['row']][$seat_row['col']] = $seat_row['userid']; @@ -468,7 +468,7 @@ public function DrawPlan($blockid, $mode, $linktarget = '', $selected_user = fal myG = vectorModel.createElement("g"); mySvg.appendChild(myG); '; - + // Icon selection in mode 2 if ($mode == 2) { $jscode .= "CreateText('Auswahl:', 0, 14);\n"; @@ -562,7 +562,7 @@ public function DrawPlan($blockid, $mode, $linktarget = '', $selected_user = fal $y = 56; for ($i = 300; $i <= 383; $i++) { $jscode .= "DrawClearSeatingSymbol($i, $x, $y, 'javascript:UpdateCurrentDrawingSymbol(\"$i\")', 'Test');\n"; - + $x += 14; if ($x > 580) { $x = 0; @@ -570,7 +570,7 @@ public function DrawPlan($blockid, $mode, $linktarget = '', $selected_user = fal } } } - + $jscode .= "CreateRect(4, $YStartPlanFrame, ". (($SVGWidth / 3) - 8) .", 20, '#d6d6d6 ', '#9d9d9d', '');\n"; $jscode .= "CreateText('". $block['text_tl'] ."', ". (($SVGWidth / 6 * 1) - strlen($block['text_tl']) * 4) .", ". ($YStartPlanFrame + 15) .", '');\n"; $jscode .= "CreateRect(". (($SVGWidth / 3) + 4) .", $YStartPlanFrame, ". (($SVGWidth / 3) - 8) .", 20, '#d6d6d6 ', '#9d9d9d', '');\n"; @@ -592,7 +592,7 @@ public function DrawPlan($blockid, $mode, $linktarget = '', $selected_user = fal for ($i = 0; $i <= strlen($block['text_lb']); $i++) { $jscode .= "CreateText('". substr($block['text_lb'], $i, 1) ."', 12, ". ((($SVGHeight - $YStartPlanFrame - 70) / 6 * 5 + ($YStartPlanFrame + 27)) - strlen($block['text_lb']) * 5 + 10 * $i) .", '');\n"; } - + $jscode .= "CreateRect(". ($SVGWidth - 25) .", ". ($YStartPlanFrame + 27) .", 20, ". ((($SVGHeight - $YStartPlanFrame - 70) / 3) - 8) .", '#d6d6d6 ', '#9d9d9d', '');\n"; for ($i = 0; $i <= strlen($block['text_rt']); $i++) { $jscode .= "CreateText('". substr($block['text_rt'], $i, 1) ."', ". ($SVGWidth - 17) .", ". ((($SVGHeight - $YStartPlanFrame - 70) / 6 * 1 + ($YStartPlanFrame + 27)) - strlen($block['text_rt']) * 5 + 10 * $i) .", '');\n"; @@ -607,7 +607,7 @@ public function DrawPlan($blockid, $mode, $linktarget = '', $selected_user = fal for ($i = 0; $i <= strlen($block['text_rb']); $i++) { $jscode .= "CreateText('". substr($block['text_rb'], $i, 1) ."', ". ($SVGWidth - 17) .", ". ((($SVGHeight - $YStartPlanFrame - 70) / 6 * 5 + ($YStartPlanFrame + 27)) - strlen($block['text_rb']) * 5 + 10 * $i) .", '');\n"; } - + $jscode .= "CreateRect(4, ". ($SVGHeight - 35) .", ". (($SVGWidth / 3) - 8) .", 20, '#d6d6d6 ', '#9d9d9d', '');\n"; $jscode .= "CreateText('". $block['text_bl'] ."', ". (($SVGWidth / 6 * 1) - strlen($block['text_bl']) * 4) .", ". ($SVGHeight - 20) .", '');\n"; $jscode .= "CreateRect(". (($SVGWidth / 3) + 4) .", ". ($SVGHeight - 35) .", ". (($SVGWidth / 3) - 8) .", 20, '#d6d6d6 ', '#9d9d9d', '');\n"; @@ -659,7 +659,7 @@ public function DrawPlan($blockid, $mode, $linktarget = '', $selected_user = fal // Show plan default: $templ['seat']['cell_nr'] = $cell_nr; - + if ($y == 1) { $jscode .= "CreateText('". $this->CoordinateToName($x + 1, -1, $block['orientation']) ."', ". ($XOffset - 2) .", ". ($YStartPlan - 6) .", '');\n"; } @@ -728,13 +728,30 @@ public function DrawPlan($blockid, $mode, $linktarget = '', $selected_user = fal case "9": $tooltip .= t('Block') .': '. $this->CoordinateToBlockAndName($x + 1, $y, $blockid) . HTML_NEWLINE; $tooltip .= t('Benutzername') .': '. $user_info[$y][$x]['username'] . HTML_NEWLINE; - if (!$cfg['sys_internet'] or $auth['type'] > \LS_AUTH_TYPE_USER or ($auth['userid'] == $selected_user and $selected_user != false)) { - $tooltip .= t('Name') .': '. trim($user_info[$y][$x]['firstname']) .' '. trim($user_info[$y][$x]['name']) . HTML_NEWLINE; - } + if ( + !$cfg['sys_internet'] + || $auth['type'] > \LS_AUTH_TYPE_USER + || ( + $selected_user + && $auth['userid'] == $user_info[$y][$x]['userid'] + ) + ) { + $tooltip .= t('Name') .': '. trim($user_info[$y][$x]['firstname']) .' '. trim($user_info[$y][$x]['name']) . HTML_NEWLINE; + } $tooltip .= t('Clan') .': '. $user_info[$y][$x]['clan'] . HTML_NEWLINE; $tooltip .= t('IP') .': '. $seat_ip[$y][$x] . HTML_NEWLINE; - if ($func->chk_img_path($user_info[$y][$x]['avatar_path']) and - ($cfg['seating_show_user_pics'] or !$cfg['sys_internet'] or $auth['type'] > \LS_AUTH_TYPE_USER or ($auth['userid'] == $selected_user and $selected_user != false))) { + if ( + $func->chk_img_path($user_info[$y][$x]['avatar_path']) + && ( + $cfg['seating_show_user_pics'] + || !$cfg['sys_internet'] + || $auth['type'] > \LS_AUTH_TYPE_USER + || ( + $selected_user + && $auth['userid'] == $user_info[$y][$x]['userid'] + ) + ) + ) { $tooltip .= '' . HTML_NEWLINE; } break; @@ -781,7 +798,7 @@ public function DrawPlan($blockid, $mode, $linktarget = '', $selected_user = fal } else { $userid = $auth['userid']; } - + if ($seat_userid[$y][$x] == $userid) { $seat_state[$y][$x] = 4; // My Seat @@ -855,7 +872,7 @@ public function DrawPlan($blockid, $mode, $linktarget = '', $selected_user = fal $jscode .= ' }'; } $framework->addJavaScriptCode($jscode); - + return $plan; } @@ -867,7 +884,7 @@ public function DrawPlan($blockid, $mode, $linktarget = '', $selected_user = fal public function ReserveSeatIfPaidAndOnlyOneMarkedSeat($userid) { global $db, $database, $party; - + $res = $db->qry(" SELECT s.seatid, @@ -891,7 +908,7 @@ public function ReserveSeatIfPaidAndOnlyOneMarkedSeat($userid) public function MarkSeatIfNotPaidAndSeatReserved($userid) { global $db, $database, $party; - + $row = $database->queryWithOnlyFirstRow(" SELECT s.seatid, diff --git a/modules/usrmgr/group.php b/modules/usrmgr/group.php index 8dd96f4c1..01daf6646 100644 --- a/modules/usrmgr/group.php +++ b/modules/usrmgr/group.php @@ -16,7 +16,7 @@ $error_usrmgr['group'] = t('Gib einen Gruppennamen ein'); $_GET['step'] = 2; } - + $selectionParameter = $_POST['selection'] ?? 0; if ($selectionParameter == 1) { if (!(preg_match("/^[0-9]+-[0-9]+$/i", trim($_POST['select_opts'])) || preg_match("/^-[0-9]+$/i", trim($_POST['select_opts'])) || preg_match("/^[0-9]+\+$/i", trim($_POST['select_opts'])))) { @@ -29,7 +29,7 @@ $_GET['step'] = 2; } break; - + // Move Up case 16: $database->query("UPDATE %prefix%party_usergroups SET pos = 0 WHERE pos = ?", [$_GET["pos"] - 1]); @@ -45,7 +45,7 @@ $database->query("UPDATE %prefix%party_usergroups SET pos = ? WHERE pos = 0", [$_GET["pos"]]); $_GET['step'] = 15; break; - + case 22: if ($_GET['group_id'] == $_POST['group_id']) { $_GET['step'] = 21; @@ -70,7 +70,7 @@ } else { $dsp->SetForm("index.php?mod=usrmgr&action=group&step=3&var=new"); } - + $groupNameParameter = $_POST['group_name'] ?? ''; $errorTextGroup = $error_usrmgr['group'] ?? ''; $dsp->AddTextFieldRow("group_name", t('Gruppenname'), $groupNameParameter, $errorTextGroup); @@ -80,7 +80,7 @@ $dsp->AddTextFieldRow("description", t('Benutzergruppenbeschreibung'), $descriptionParameter, $errorTextGroupDescription); $dsp->AddFormSubmitRow(t('Hinzufügen')); - + if ($varParameter != "update") { $count = $database->queryWithOnlyFirstRow("SELECT COUNT(group_id) AS n FROM %prefix%party_usergroups WHERE selection != 0"); if ($count['n'] > 1) { @@ -105,29 +105,29 @@ } } break; - + case 3: $selectionParameter = $_POST['selection'] ?? ''; $selectionOptsParameter = $_POST['select_opts'] ?? ''; if ($_GET['var'] == "new") { - $party->add_user_group($_POST['group_name'], $_POST['description'], $selectionParameter, $selectionOptsParameter); + $party->addUsergroup($_POST['group_name'], $_POST['description'], $selectionParameter, $selectionOptsParameter); $func->confirmation(t('Benutzergruppe wurde hinzugefügt'), 'index.php?mod=usrmgr&action=group&step=2'); } elseif ($_GET['var'] == "update") { - $party->update_user_group($_GET['group_id'], $_POST['group_name'], $_POST['description'], $selectionParameter, $selectionOptsParameter); + $party->updateUserGroup($_GET['group_id'], $_POST['group_name'], $_POST['description'], $selectionParameter, $selectionOptsParameter); $func->confirmation(t('Benutzergruppe wurde erfolgreich editiert.'), 'index.php?mod=usrmgr&action=group&step=2'); } else { $func->error(t('Die Benutzergruppe konnte nicht angelegt werden.'), 'index.php?mod=usrmgr&action=group&step=2'); } - + break; - + case 9: $dsp->NewContent(t('Gruppe auswählen'), t('Gruppe auswählen')); $dsp->SetForm("index.php?mod=usrmgr&action=group&step=10"); $party->get_user_group_dropdown(); $dsp->AddFormSubmitRow(t('Weiter')); break; - + case 10: if (isset($_POST['group_id'])) { $_GET['group_id'] = $_POST['group_id']; @@ -157,7 +157,7 @@ $func->question($text, "index.php?mod=usrmgr&action=group&step=12&userids=$userids&group_id={$_GET['group_id']}", "index.php?mod=usrmgr&action=group&step=10&group_id={$_GET['group_id']}"); } elseif ($_GET["userid"]) { $user_data = $database->queryWithOnlyFirstRow("SELECT user.username, g.group_name FROM %prefix%user AS user LEFT JOIN %prefix%party_usergroups AS g ON user.group_id = g.group_id WHERE userid = ?", [$_GET["userid"]]); - + if ($user_data["username"]) { $func->question(t('Willst du den Benutzer %1 der Gruppe %2 zuweisen?', $user_data["username"], $user_data["group_name"]), "index.php?mod=usrmgr&action=group&step=12&userid={$_GET["userid"]}&group_id={$_GET['group_id']}", "index.php?mod=usrmgr&action=group&step=10&group_id={$_GET['group_id']}"); } else { @@ -166,9 +166,9 @@ } else { $func->error(t('Dieser Benutzer existiert nicht'), "index.php?mod=usrmgr&action=group&step=10"); } - + break; - + case 12: if ($_GET["userids"]) { $userids = explode(",", $_GET["userids"]); @@ -181,14 +181,14 @@ $func->confirmation(t('Die Gruppenzuweisung wurde erfolgreich durchgeführt'), "index.php?mod=usrmgr&action=group&group_id={$_GET['group_id']}"); break; - + // Sort Groups case 15: $dsp->NewContent(t('Gruppen sortieren'), t('Hier kannst du die Gruppen sortieren in welcher Reihenfolge sie Angewendet werden sollen. Die oberste hat die höchste Priorität')); $groups = $db->qry("SELECT * FROM %prefix%party_usergroups WHERE selection != 0 ORDER BY pos"); $z = 0; - + while ($group = $db->fetch_array($groups)) { $z++; $database->query("UPDATE %prefix%party_usergroups SET pos = ? WHERE group_id = ?", [$z, $group["group_id"]]); @@ -201,32 +201,32 @@ $link .= "[v]"; } $link .= " " . $usrmgr_selection[$group['selection']] . " " . $group['select_opts']; - + $dsp->AddDoubleRow("$z) ". $group["group_name"], $link); } $db->free_result($groups); $dsp->AddBackButton("index.php?mod=usrmgr&action=group"); break; - + // Delete Group case 20: $row = $database->queryWithOnlyFirstRow("SELECT * FROM %prefix%party_usergroups WHERE group_id = ?", [$_POST['group_id']]); $func->question(t('Wollen sie die Gruppe %1 wirklich löschen?', $row['group_name']), "index.php?mod=usrmgr&action=group&step=21&group_id={$_POST['group_id']}", "index.php?mod=usrmgr&action=group"); break; - + case 21: $dsp->NewContent(t('Gruppe zuweisen'), t('Welche Gruppe möchtest du den Benutzern die in der gelöschten Gruppe sind zuweisen?')); $dsp->SetForm("index.php?mod=usrmgr&action=group&step=22&group_id={$_GET['group_id']}"); $party->get_user_group_dropdown("NULL", 1); $dsp->AddFormSubmitRow(t('Weiter')); break; - + case 22: $party->delete_usergroups($_GET['group_id'], $_POST['group_id']); $func->confirmation(t('Gruppe erfolgreich gelöscht.'), "index.php?mod=usrmgr&action=group"); break; - + // Multi-User-Assign case 30: foreach ($_POST['action'] as $key => $val) { diff --git a/website/docs/modules/Info2.md b/website/docs/modules/Info2.md new file mode 100644 index 000000000..70eeb3605 --- /dev/null +++ b/website/docs/modules/Info2.md @@ -0,0 +1,36 @@ +--- +id: settings +title: Settings +sidebar_position: 1 +--- + +## Module Description + +This module provides the abilitity to create and manage multiple rich-text pages for user information. +Multiple default pages are provided as example / template including generic party information, how to reach the party, participation rules and so on. + +## Configuration options + +| Option | Impact | Default value | +|------------|---------------------------|---------------| +|Use WYSIWYG-Editor| Loads FCKedit for editing of Info pages, raw HTML-Input field will be used otherwise | Yes | +|Add new Entries as subentries of info2 | If enabled new & enabled entries will be automatically added as submenu-Item for the Module| Yes | + +## Placeholders and replacement values + +The following placeholders can be used at the moment in info texts and will be replaced on display with the related values. +The placeholder name will be displayed if the value cannot be resolved + +### User-Related +| Variable | Replacement value | +|------------|---------------------------| +| %USERID% | The numeric ID of the user| +| %USERNAME% | The username (nickname) | + +## Party Related +| Variable | Replacement value | +|------------------|---------------------------| +| %PARTYID% | The numeric ID of the currently selected party for the user| +| %PARTYPRICEID% | If the user is already registered for the party then this will reflect the price ID| +| %PARTYPRICETEXT% | The name of the ticket price item given| +| %PARTYPRICEVALUE%| The amount defined for the price item| diff --git a/website/docs/modules/_category_.json b/website/docs/modules/_category_.json new file mode 100644 index 000000000..f0f971c21 --- /dev/null +++ b/website/docs/modules/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "Modules", + "position": 4, + "collapsed": false, + "link": { + "type": "generated-index" + } +} diff --git a/website/docs/other/_category_.json b/website/docs/other/_category_.json index 738e2883b..5bea44087 100644 --- a/website/docs/other/_category_.json +++ b/website/docs/other/_category_.json @@ -1,6 +1,6 @@ { "label": "Other", - "position": 4, + "position": 5, "collapsed": false, "link": { "type": "generated-index"