Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b71ca1848c | |||
| 895e36c8ec | |||
| 65ae062a96 | |||
| 7ac6d34e7b | |||
| a1eafee419 | |||
| fa17ce4858 | |||
| 81495b21c4 | |||
| c7371b0fc0 | |||
| a9ff982c45 | |||
| d8fec04d81 | |||
| e1e95639ad | |||
| 8e606ad331 | |||
| ecdc0e6540 | |||
| 65e6a3634f | |||
| 38103fdaf6 | |||
| a267b15054 | |||
| f01824d84d | |||
| d065b6d962 |
@@ -1,5 +1,6 @@
|
||||
.idea
|
||||
PROTOTYPING
|
||||
tools
|
||||
src/installer/cache
|
||||
src/private/cache
|
||||
src/private/vendor
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
<p align="center">
|
||||
<b><a href="https://imgur.com/a/3vfIPJQ" target="_blank">View more screenshots</a>
|
||||
</p>
|
||||
|
||||
[](https://imgur.com/a/3vfIPJQ)
|
||||
|
||||
<p align="center">
|
||||
<a href="https://imgur.com/a/3vfIPJQ" target="_blank">View more screenshots</a> |
|
||||
<a href="https://github.com/Wruczek/ts-website/wiki/%5BDE%5D-Readme-%7C-Liesmich-%5B2.x%5D" target="_blank">🇩🇪 Deutsches Readme</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<b>Need help? <a href="https://t.me/tswebsite">Join our telegram group</a></b> for news, announcements, help and general chat about ts-website.
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
**ts-website** - free website for your TeamSpeak 3 server<br>
|
||||
|
||||
<hr>
|
||||
|
||||
#### Useful links
|
||||
- [Demo](https://ts.wruczek.tech/)
|
||||
- [Installation instructions](https://github.com/Wruczek/ts-website/wiki/%5BEN%5D-Website-Installation)
|
||||
- [Wiki](https://github.com/Wruczek/ts-website/wiki)
|
||||
- [Report Issues / Suggestions](https://github.com/Wruczek/ts-website/issues/new)
|
||||
- [Translate ts-website](https://wruczek.oneskyapp.com/collaboration/project/325562)
|
||||
- **[ts-website Telegram group](https://t.me/tswebsite) - support, announcements, and general chat**
|
||||
|
||||
#### Main Features
|
||||
- News page, dynamic server status, customizable admin status, server viewer, group assigner, ban list, rules, FAQ, impressum
|
||||
- Ability for users to login with their TeamSpeak identity
|
||||
- Multiple languages with auto-detection for default language
|
||||
- Supports for PHP 5 and 7, Apache 2 and nginx
|
||||
- Modern and responsive design
|
||||
- Caching
|
||||
- Free and Open source, under GPL-3.0
|
||||
|
||||
### Other stuff
|
||||
I am happy to take any programming-related requests, add additional features or modify the code to suit your needs for a small donation :) I am experienced at Java, PHP, HTML, CSS, Javascript, SQL, server configurations ect.
|
||||
|
||||
For business enquiries only: **wruczekk** at **gmail.com**, for anything else please join our [Telegram group](https://t.me/ts-website).
|
||||
+53
-11
@@ -18,32 +18,74 @@ if ($banlist !== null) {
|
||||
$data = [];
|
||||
|
||||
foreach ($banlist as $ban) {
|
||||
// Bans abbreviations:
|
||||
// if we see a UID, IP or MyTSID ban, and we know
|
||||
// the nickname of the banned user, we will show
|
||||
// the user's name and then the type of ban
|
||||
// that should be enough info for most users.
|
||||
// it is possible to hover over the ban type to
|
||||
// view the exact ban target
|
||||
//
|
||||
// for example, Wruczek got banned on his UID. we know that
|
||||
// his last nickname was "Wruczek", so we simply show, that
|
||||
// the ban is issued for:
|
||||
// Wruczek (UID)
|
||||
// after hovering over the "UID", you will see the exact UID
|
||||
//
|
||||
// if we dont know the last name of the banned user, we
|
||||
// will just show the UID, IP or MyTSID
|
||||
|
||||
$name = "(cannot determine a name)";
|
||||
$target = "(unknown)";
|
||||
$lastNickname = Utils::escape($ban["lastnickname"]);
|
||||
$filter = "";
|
||||
$abbreviation = null;
|
||||
|
||||
if ($ban["lastnickname"]) {
|
||||
$name = (string)$ban["lastnickname"];
|
||||
} else if ($ban["uid"]) {
|
||||
$name = new Html("<code>" . $ban["uid"] . "</code>");
|
||||
} else if ($ban["name"]) {
|
||||
$name = (string)$ban["name"];
|
||||
} else if ($ban["ip"]) {
|
||||
$ip = str_replace("\\", "", (string) $ban["ip"]);
|
||||
if ($ban["ip"]) {
|
||||
$ip = str_replace("\\", "", (string)$ban["ip"]);
|
||||
|
||||
try {
|
||||
$name = Utils::censorIpAddress($ip);
|
||||
$ip = Utils::censorIpAddress($ip);
|
||||
} catch (\Exception $e) {}
|
||||
|
||||
if ($lastNickname) {
|
||||
$abbreviation = [$ip, "IP"];
|
||||
} else {
|
||||
$target = $ip;
|
||||
}
|
||||
|
||||
if ($ip === Utils::getClientIp()) {
|
||||
$ipbanned = [
|
||||
"invoker" => (string)$ban["invokername"],
|
||||
"reason" => (string)$ban["reason"]
|
||||
];
|
||||
}
|
||||
} else if ($ban["uid"]) {
|
||||
if ($lastNickname) {
|
||||
$abbreviation = [$ban["uid"], "UID"];
|
||||
} else {
|
||||
$target = new Html("<code>" . $ban["uid"] . "</code>");
|
||||
}
|
||||
} else if ($ban["name"]) {
|
||||
$target = $ban["name"];
|
||||
} else if (!empty($ban["mytsid"])) { // empty, older TS servers dont have MYTS bans, so the key might not exist
|
||||
if ($lastNickname) {
|
||||
$abbreviation = [$ban["mytsid"], "MyTSID"];
|
||||
} else {
|
||||
$target = new Html("<code>" . $ban["mytsid"] . "</code>");
|
||||
}
|
||||
}
|
||||
|
||||
if ($abbreviation) {
|
||||
$html = '%s (<span class="bans-highlight" data-toggle="tooltip" title="%s">%s</span>)';
|
||||
$target = new Html(sprintf($html, $lastNickname, $abbreviation[0], $abbreviation[1]));
|
||||
|
||||
// make sure that the "full" data is also searchable in DataTables
|
||||
$filter = "{$abbreviation[0]} $lastNickname";
|
||||
}
|
||||
|
||||
$data[] = [
|
||||
"name" => $name,
|
||||
"filter" => $filter,
|
||||
"target" => $target,
|
||||
"reason" => (string)$ban["reason"],
|
||||
"invoker" => (string)$ban["invokername"],
|
||||
"created" => $ban["created"],
|
||||
|
||||
@@ -178,6 +178,11 @@ body {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.bans-highlight {
|
||||
color: #e83e8c;
|
||||
font-family: var(--font-family-monospace);
|
||||
}
|
||||
|
||||
/* Responsive datatables styles */
|
||||
|
||||
table.dataTable>tbody>tr.child ul.dtr-details>li:first-child {
|
||||
|
||||
@@ -50,20 +50,6 @@ INSERT INTO `DBPREFIXfaq` (`faqid`, `langid`, `question`, `answer`, `lastmodify`
|
||||
(2, 1, 'How can I configure the FAQ?', 'An administrator can add, edit and remove questions in <a href=\"admin\">admin panel</a>.', '2018-12-26 12:33:18'),
|
||||
(3, 1, 'Question 3', 'Answer 3 in <b>HTML</b>', '2018-12-26 13:10:32');
|
||||
|
||||
DROP TABLE IF EXISTS `DBPREFIXlanguages`;
|
||||
CREATE TABLE `DBPREFIXlanguages` (
|
||||
`langid` int(11) NOT NULL,
|
||||
`englishname` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`nativename` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`langcode` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'In this format: https://bit.ly/2MCGg6M',
|
||||
`isdefault` tinyint(1) NOT NULL DEFAULT '0'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
INSERT INTO `DBPREFIXlanguages` (`langid`, `englishname`, `nativename`, `langcode`, `isdefault`) VALUES
|
||||
(1, 'English', 'English', 'en', 1),
|
||||
(2, 'English (US)', 'English (US)', 'en-us', 0),
|
||||
(3, 'Polish', 'Polski', 'pl', 0);
|
||||
|
||||
DROP TABLE IF EXISTS `DBPREFIXnews`;
|
||||
CREATE TABLE `DBPREFIXnews` (
|
||||
`newsid` int(11) NOT NULL,
|
||||
@@ -75,239 +61,7 @@ CREATE TABLE `DBPREFIXnews` (
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
INSERT INTO `DBPREFIXnews` (`newsid`, `title`, `langid`, `added`, `edited`, `content`) VALUES
|
||||
(1, 'Welcome to ts-website!', 1, '2018-12-26 13:10:32', NULL, '<b>Hi there!</b> If you are reading this, it means that TS-website has been installed successfully.<br>\r\nYou can login to your <a href=\"admin\">ACP</a> to configure many parts of it.<br>\r\nNeed help? Join our <a href=\"https://t.me/tswebsite\" target=\"_blank\">Telegram group</a> for support.\r\nHave a good day!');
|
||||
|
||||
DROP TABLE IF EXISTS `DBPREFIXtranslations`;
|
||||
CREATE TABLE `DBPREFIXtranslations` (
|
||||
`id` int(10) NOT NULL,
|
||||
`langid` int(10) NOT NULL,
|
||||
`identifier` varchar(128) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`value` text COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`comment` text COLLATE utf8mb4_unicode_ci
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
INSERT INTO `DBPREFIXtranslations` (`id`, `langid`, `identifier`, `value`, `comment`) VALUES
|
||||
(1, 1, 'AUTHORS', 'Wruczek <wruczekk@gmail.com>', 'Language authors'),
|
||||
(2, 3, 'AUTHORS', 'Wruczek <wruczekk@gmail.com>', NULL),
|
||||
(3, 1, 'COOKIEALERT_MESSAGE', '<b>Do you like cookies?</b> 🍪 We use cookies to ensure you get the best experience on our website. <a href=\"http://cookiesandyou.com/\" target=\"_blank\">Learn more</a>', 'Remember to change link to a website in your language'),
|
||||
(4, 3, 'COOKIEALERT_MESSAGE', '<b>Lubisz ciasteczka?</b> 🍪 Używamy ciasteczek, aby zapewnić najwyższą jakość usług. <a href=\"http://wszystkoociasteczkach.pl/\" target=\"_blank\">Dowiedz się więcej</a>', NULL),
|
||||
(5, 1, 'COOKIEALERT_AGREE', 'I agree', NULL),
|
||||
(6, 3, 'COOKIEALERT_AGREE', 'Zgadzam się', NULL),
|
||||
(7, 1, 'OUTDATED_DATA', '<b>Warning!</b> Some information cannot be obtained now. Showing outdated data from {0}.', '{0} will be replaced with fuzzy date (for example \"8 hours ago\"). Please try to match the your message grammatically'),
|
||||
(8, 3, 'OUTDATED_DATA', '<b>Uwaga!</b> Niektóre dane nie mogą być teraz uzyskane. Pokazuje nieaktualne dane z {0}.', NULL),
|
||||
(9, 1, 'SHOW_PROBLEMS', 'Show problems', NULL),
|
||||
(10, 3, 'SHOW_PROBLEMS', 'Pokaż problemy', NULL),
|
||||
(11, 1, 'PROBLEMS_DESCRIPTION', 'Problems encountered while connecting to the TeamSpeak server', NULL),
|
||||
(12, 3, 'PROBLEMS_DESCRIPTION', 'Problemy napotkane podczas próby połączenia się z serwerem TeamSpeak', NULL),
|
||||
(13, 1, 'NO_JAVASCRIPT_ENABLED', 'This website will not work without <a href=\"https://www.enable-javascript.com/\" target=\"_blank\">JavaScript enabled</a>.', 'Remember to change the website address to include instructions in your language'),
|
||||
(14, 3, 'NO_JAVASCRIPT_ENABLED', 'Ta stronie nie będzie działać bez <a href=\"https://www.enable-javascript.com/pl/\" target=\"_blank\">włączonej obsługi JavaScript</a>.', NULL),
|
||||
(15, 1, 'CANNOT_GET_DATA', 'Cannot get data for \"{0}\"! Please contact website owner.', '{0} will be replaced with component name that cannot be refreshed (for example banlist or viewer)'),
|
||||
(16, 3, 'CANNOT_GET_DATA', 'Nie mogę pobrać informacji o \"{0}\"! Skontaktuj się z właścicielem strony.', NULL),
|
||||
(17, 1, 'NO_REASON_SET', '<b>(no reason set)</b>', 'Please keep the \"<b>\" tags in place, as they help to distinguish a placeholder form a real message'),
|
||||
(18, 3, 'NO_REASON_SET', '<b>(brak powodu)</b>', NULL),
|
||||
(19, 1, 'BANS_HEADER_NAME', 'Name / IP / UID', NULL),
|
||||
(20, 3, 'BANS_HEADER_NAME', 'Nazwa / IP / UID', NULL),
|
||||
(21, 1, 'BANS_HEADER_REASON', 'Reason', NULL),
|
||||
(22, 3, 'BANS_HEADER_REASON', 'Powód', NULL),
|
||||
(23, 1, 'BANS_HEADER_INVOKER', 'Banned by', NULL),
|
||||
(24, 3, 'BANS_HEADER_INVOKER', 'Zbanowany przez', NULL),
|
||||
(25, 1, 'BANS_HEADER_BANDATE', 'Ban date', NULL),
|
||||
(26, 3, 'BANS_HEADER_BANDATE', 'Data zbanowania', NULL),
|
||||
(27, 1, 'BANS_HEADER_EXPIRES', 'Expires', NULL),
|
||||
(28, 3, 'BANS_HEADER_EXPIRES', 'Wygasa', NULL),
|
||||
(29, 1, 'DATATABLES_LANGUAGE_NAME', 'English', 'This language will be used to load language file for DataTables. Please choose a language from this list: https://datatables.net/plug-ins/i18n/#Translations.\r\n\r\nIf chosen correctly, this url: \"//cdn.datatables.net/plug-ins/1.10.12/i18n/{NAME}.json\" should return a valid JSON object with translations. For example: \"//cdn.datatables.net/plug-ins/1.10.12/i18n/English.json\"'),
|
||||
(30, 3, 'DATATABLES_LANGUAGE_NAME', 'Polish', NULL),
|
||||
(31, 1, 'BANS_NEVEREXPIRES', 'Never', NULL),
|
||||
(32, 3, 'BANS_NEVEREXPIRES', 'Nigdy', NULL),
|
||||
(33, 1, 'STATUS_ADDRESS', 'Address:', ''),
|
||||
(34, 3, 'STATUS_ADDRESS', 'Adres:', NULL),
|
||||
(35, 1, 'STATUS_CLIENTS_ONLINE', 'Online:', NULL),
|
||||
(36, 3, 'STATUS_CLIENTS_ONLINE', 'Online:', NULL),
|
||||
(37, 1, 'STATUS_RESERVED_SLOTS', '{0} reserved slots', NULL),
|
||||
(38, 3, 'STATUS_RESERVED_SLOTS', '{0} zarezerwowanych slotów', NULL),
|
||||
(39, 1, 'STATUS_TOP_ONLINE', 'Top online:', NULL),
|
||||
(40, 3, 'STATUS_TOP_ONLINE', 'Rekord online:', NULL),
|
||||
(41, 1, 'STATUS_TOP_ONLINE_DESC', 'Achieved on {0}', NULL),
|
||||
(42, 3, 'STATUS_TOP_ONLINE_DESC', 'Ustanowiono {0}', NULL),
|
||||
(43, 1, 'STATUS_UPTIME', 'Uptime:', NULL),
|
||||
(44, 3, 'STATUS_UPTIME', 'Uptime:', NULL),
|
||||
(45, 1, 'STATUS_VERSION', 'Version:', NULL),
|
||||
(46, 3, 'STATUS_VERSION', 'Wersja:', NULL),
|
||||
(47, 1, 'STATUS_VERSION_DESC', '{0} on {1}', NULL),
|
||||
(48, 3, 'STATUS_VERSION_DESC', '{0} na {1}', NULL),
|
||||
(49, 1, 'STATUS_PING', 'Avg. ping:', NULL),
|
||||
(50, 3, 'STATUS_PING', 'Śr. ping:', NULL),
|
||||
(51, 1, 'STATUS_PACKETLOSS', 'Avg. packet loss:', NULL),
|
||||
(52, 3, 'STATUS_PACKETLOSS', 'Śr. utrata pakietów:', NULL),
|
||||
(53, 1, 'STATUS_ERROR', 'Cannot retrieve server status', NULL),
|
||||
(54, 3, 'STATUS_ERROR', 'Błąd podczas wczytywania statusu serwera', NULL),
|
||||
(55, 1, 'STATUS_PANEL_TITLE', 'Server status', NULL),
|
||||
(56, 3, 'STATUS_PANEL_TITLE', 'Status serwera', NULL),
|
||||
(57, 1, 'MOMENTJS_LANG', 'en-gb', 'Language for Moment.js, full list: https://github.com/moment/moment/tree/develop/locale'),
|
||||
(58, 2, 'MOMENTJS_LANG', 'en-us', NULL),
|
||||
(59, 3, 'MOMENTJS_LANG', 'pl', NULL),
|
||||
(60, 1, 'LOGIN_CONFIRMATION_CODE', 'Hi, here\'s your confirmation code to login: [b]{0}[/b]', 'You can use BBCode. Use {0} for the confirmation code.'),
|
||||
(61, 3, 'LOGIN_CONFIRMATION_CODE', 'Cześć, oto twój kod potwierdzający logowanie: [b]{0}[/b]', NULL),
|
||||
(62, 1, 'UNSUPPORTED_BROWSER', 'Your browser is not supported. Please switch to the latest version of Chrome, Firefox, Safari or Edge to use this website.', ''),
|
||||
(63, 3, 'UNSUPPORTED_BROWSER', 'Twoja przeglądarka nie jest wspierana. Zainstaluj najnowszą wersję Chrome, Firefox, Safari lub Edge by korzystać z tej strony.', NULL),
|
||||
(64, 1, 'DATATABLES_PLACEHOLDER_SEARCH', 'Search...', NULL),
|
||||
(65, 3, 'DATATABLES_PLACEHOLDER_SEARCH', 'Szukaj...', NULL),
|
||||
(66, 1, 'WEBSITE_TITLE', ' | TS-website English Language', NULL),
|
||||
(67, 3, 'WEBSITE_TITLE', ' | TS-website Język Polski', NULL),
|
||||
(68, 1, 'ADMIN_STATUS_ONLINE', 'Online', NULL),
|
||||
(69, 3, 'ADMIN_STATUS_ONLINE', 'Online', NULL),
|
||||
(70, 1, 'ADMIN_STATUS_AWAY', 'Away', NULL),
|
||||
(71, 3, 'ADMIN_STATUS_AWAY', 'Zaraz wracam', NULL),
|
||||
(72, 1, 'ADMIN_STATUS_OFFLINE', 'Offline', NULL),
|
||||
(73, 3, 'ADMIN_STATUS_OFFLINE', 'Offline', NULL),
|
||||
(76, 1, 'ADMIN_STATUS_EMPTY_GROUP', 'Nothing to show', NULL),
|
||||
(77, 3, 'ADMIN_STATUS_EMPTY_GROUP', 'Nic do pokazania', NULL),
|
||||
(78, 1, 'ADMIN_STATUS_EMPTY_STATUS', 'Admin status is empty', NULL),
|
||||
(79, 3, 'ADMIN_STATUS_EMPTY_STATUS', 'Status administracji jest pusty', NULL),
|
||||
(80, 1, 'ASSIGNER_PANEL_TITLE', 'Group assigner', NULL),
|
||||
(81, 3, 'ASSIGNER_PANEL_TITLE', 'Przydzielanie grup', NULL),
|
||||
(82, 1, 'ASSIGNER_TITLE', 'Group assigner', NULL),
|
||||
(83, 3, 'ASSIGNER_TITLE', 'Przydzielanie grup', NULL),
|
||||
(84, 1, 'BANS_EMPTY', 'Banlist is empty', NULL),
|
||||
(85, 3, 'BANS_EMPTY', 'Lista banów jest pusta', NULL),
|
||||
(86, 1, 'BANS_TITLE', 'Banlist', NULL),
|
||||
(87, 3, 'BANS_TITLE', 'Lista banów', NULL),
|
||||
(88, 1, 'BANS_PANEL_TITLE', 'Banlist', NULL),
|
||||
(89, 3, 'BANS_PANEL_TITLE', 'Lista banów', NULL),
|
||||
(90, 1, 'BANS_BANNED_ALERT_TITLE', 'Your IP has been banned by {0}', NULL),
|
||||
(91, 3, 'BANS_BANNED_ALERT_TITLE', 'Twoje IP zostało zbanowane przez {0}', NULL),
|
||||
(92, 1, 'BANS_BANNED_ALERT_REASON', 'Reason: {0}', NULL),
|
||||
(93, 3, 'BANS_BANNED_ALERT_REASON', 'Powód: {0}', NULL),
|
||||
(94, 1, 'BANS_VIEW_MORE_TIP', 'Click on a row to view more details about a ban', NULL),
|
||||
(95, 3, 'BANS_VIEW_MORE_TIP', 'Kliknij na wiersz by pokazać więcej informacji o banie', NULL),
|
||||
(96, 1, 'RULES_TITLE', 'Rules', NULL),
|
||||
(97, 3, 'RULES_TITLE', 'Regulamin', NULL),
|
||||
(98, 1, 'RULES_PANEL_TITLE', 'Rules', NULL),
|
||||
(99, 3, 'RULES_PANEL_TITLE', 'Regulamin', NULL),
|
||||
(100, 1, 'FAQ_COPY_LINK', 'Copy link to that answer', NULL),
|
||||
(101, 3, 'FAQ_COPY_LINK', 'Kopiuj link do tej odpowiedzi', NULL),
|
||||
(102, 1, 'FAQ_PANEL_TITLE', 'FAQ', NULL),
|
||||
(103, 3, 'FAQ_PANEL_TITLE', 'FAQ', NULL),
|
||||
(104, 1, 'FAQ_TITLE', 'FAQ', NULL),
|
||||
(105, 3, 'FAQ_TITLE', 'FAQ', NULL),
|
||||
(106, 1, 'FAQ_COPY_LINK_SUCCESS', 'Copied!', NULL),
|
||||
(107, 3, 'FAQ_COPY_LINK_SUCCESS', 'Skopiowano!', NULL),
|
||||
(108, 1, 'FAQ_COPY_LINK_ERROR', 'Error!', NULL),
|
||||
(109, 3, 'FAQ_COPY_LINK_ERROR', 'Błąd!', NULL),
|
||||
(110, 1, 'HOME_TITLE', 'News', NULL),
|
||||
(111, 3, 'HOME_TITLE', 'Aktualności', NULL),
|
||||
(112, 1, 'HOME_PANEL_TITLE', 'News', NULL),
|
||||
(113, 3, 'HOME_PANEL_TITLE', 'Aktualności', NULL),
|
||||
(114, 1, 'HOME_EMPTY', 'No news available at this moment', NULL),
|
||||
(115, 3, 'HOME_EMPTY', 'Brak atualności', NULL),
|
||||
(116, 1, 'HOME_INVALID_PAGE', 'Invalid page number', NULL),
|
||||
(117, 3, 'HOME_INVALID_PAGE', 'Zły numer strony', NULL),
|
||||
(118, 1, 'HOME_PREVIOUS_NEWS', 'Previous', 'This value is only used by assistive technologies (screen readers ect.)'),
|
||||
(119, 3, 'HOME_PREVIOUS_NEWS', 'Poprzednia', NULL),
|
||||
(120, 1, 'HOME_NEXT_NEWS', 'Next', 'This value is only used by assistive technologies (screen readers ect.)'),
|
||||
(121, 3, 'HOME_NEXT_NEWS', 'Następna', NULL),
|
||||
(122, 1, 'ADMIN_STATUS_PANEL_TITLE', 'Admin status', NULL),
|
||||
(123, 3, 'ADMIN_STATUS_PANEL_TITLE', 'Status administracji', NULL),
|
||||
(124, 1, 'ADMIN_STATUS_HIDE_OFFLINE_TIP', 'Hide offline admins', NULL),
|
||||
(125, 3, 'ADMIN_STATUS_HIDE_OFFLINE_TIP', 'Ukryj administratorów offline', NULL),
|
||||
(126, 1, 'ADMIN_STATUS_SHOW_OFFLINE_TIP', 'Show offline admins', NULL),
|
||||
(127, 3, 'ADMIN_STATUS_SHOW_OFFLINE_TIP', 'Pokaż administratorów offline', NULL),
|
||||
(128, 1, 'ADMIN_STATUS_ERROR', 'Admin status error', NULL),
|
||||
(129, 3, 'ADMIN_STATUS_ERROR', 'Błąd statusu administracji', NULL),
|
||||
(130, 1, 'NAV_TOGGLE', 'Toggle navigation', 'This value is only used by assistive technologies (screen readers ect.)'),
|
||||
(131, 3, 'NAV_TOGGLE', 'Przełącz nawigację', NULL),
|
||||
(132, 1, 'NAV_VIEWER', 'Viewer', NULL),
|
||||
(133, 3, 'NAV_VIEWER', 'Podgląd', NULL),
|
||||
(134, 1, 'NAV_ASSIGNER', 'Assigner', NULL),
|
||||
(135, 3, 'NAV_ASSIGNER', 'Grupy', NULL),
|
||||
(136, 1, 'NAV_BANS', 'Bans', NULL),
|
||||
(137, 3, 'NAV_BANS', 'Bany', NULL),
|
||||
(138, 1, 'NAV_RULES', 'Rules', NULL),
|
||||
(139, 3, 'NAV_RULES', 'Regulamin', NULL),
|
||||
(140, 1, 'NAV_FAQ', 'FAQ', NULL),
|
||||
(141, 3, 'NAV_FAQ', 'FAQ', NULL),
|
||||
(142, 1, 'NAV_ACCOUNT_LOGIN', 'Login', NULL),
|
||||
(143, 3, 'NAV_ACCOUNT_LOGIN', 'Zaloguj się', NULL),
|
||||
(144, 1, 'NAV_ACCOUNT_LOGOUT', 'Logout', NULL),
|
||||
(145, 3, 'NAV_ACCOUNT_LOGOUT', 'Wyloguj się', NULL),
|
||||
(146, 1, 'VIEWER_TITLE', 'Server viewer', NULL),
|
||||
(147, 3, 'VIEWER_TITLE', 'Podgląd serwera', NULL),
|
||||
(148, 1, 'VIEWER_PANEL_TITLE', 'Server viewer', NULL),
|
||||
(149, 3, 'VIEWER_PANEL_TITLE', 'Podgląd serwera', NULL),
|
||||
(150, 1, 'VIEWER_SHOW_EMPTY', 'Show empty channels', NULL),
|
||||
(151, 3, 'VIEWER_SHOW_EMPTY', 'Pokaż puste kanały', NULL),
|
||||
(152, 1, 'VIEWER_HIDE_EMPTY', 'Hide empty channels', NULL),
|
||||
(153, 3, 'VIEWER_HIDE_EMPTY', 'Ukryj puste kanały', NULL),
|
||||
(154, 1, 'VIEWER_TIP_ALERT', 'Click on a channel to join it. Hover over a user to check their info', NULL),
|
||||
(155, 3, 'VIEWER_TIP_ALERT', 'Kliknij na kanał, by na niego dołączyć. Nakieruj na użytkownika, by sprawdzić informacje o nim', NULL),
|
||||
(158, 1, 'ARIA_CLOSE', 'Close', 'This value is only used by assistive technologies (screen readers ect.)'),
|
||||
(159, 3, 'ARIA_CLOSE', 'Zamknij', NULL),
|
||||
(160, 1, 'VIEWER_ERROR', 'Viewer error', NULL),
|
||||
(161, 3, 'VIEWER_ERROR', 'Błąd podglądu', NULL),
|
||||
(162, 1, 'VIEWER_CONNECTION_CONFIRMATION', 'Do you want to connect to this channel?', NULL),
|
||||
(163, 3, 'VIEWER_CONNECTION_CONFIRMATION', 'Czy chcesz dołączyć na ten kanał?', NULL),
|
||||
(164, 1, 'VIEWER_CLIENT_LASTACTIVE', 'Last active:', NULL),
|
||||
(165, 3, 'VIEWER_CLIENT_LASTACTIVE', 'Aktywny:', NULL),
|
||||
(166, 1, 'VIEWER_CLIENT_ONLINE', 'Online time:', NULL),
|
||||
(167, 3, 'VIEWER_CLIENT_ONLINE', 'Online przez:', NULL),
|
||||
(168, 1, 'VIEWER_CLIENT_JOINED', 'First joined:', NULL),
|
||||
(169, 3, 'VIEWER_CLIENT_JOINED', 'Dołączył:', NULL),
|
||||
(170, 1, 'VIEWER_CLIENT_TITLE', 'Client info', NULL),
|
||||
(171, 3, 'VIEWER_CLIENT_TITLE', 'Informacje o kliencie', NULL),
|
||||
(172, 1, 'VIEWER_SERVER_ICON', 'Server icon', NULL),
|
||||
(173, 3, 'VIEWER_SERVER_ICON', 'Ikona serwera', NULL),
|
||||
(174, 1, 'VIEWER_DEFAULT_CHANNEL', 'Default channel', NULL),
|
||||
(175, 3, 'VIEWER_DEFAULT_CHANNEL', 'Kanał domyślny', NULL),
|
||||
(176, 1, 'VIEWER_CHANNEL_UNSUB1', ', unsubscribed', 'Please note that this string starts with \", \"'),
|
||||
(177, 3, 'VIEWER_CHANNEL_UNSUB1', ', odsubskrybowany', NULL),
|
||||
(178, 1, 'VIEWER_CHANNEL_OCCUPIED', 'Fully occupied', NULL),
|
||||
(179, 3, 'VIEWER_CHANNEL_OCCUPIED', 'Zajęty', NULL),
|
||||
(180, 1, 'VIEWER_CHANNEL_PASSWORD', 'Password-protected', NULL),
|
||||
(181, 3, 'VIEWER_CHANNEL_PASSWORD', 'Zabezpieczony hasłem', NULL),
|
||||
(182, 1, 'VIEWER_CHANNEL_UNSUB2', 'Unsubscribed', NULL),
|
||||
(183, 3, 'VIEWER_CHANNEL_UNSUB2', 'Odsubskrybowany', NULL),
|
||||
(184, 1, 'VIEWER_CHANNEL_ICON', 'Channel icon', NULL),
|
||||
(185, 3, 'VIEWER_CHANNEL_ICON', 'Ikona kanału', NULL),
|
||||
(186, 1, 'VIEWER_CHANNEL_MODERATED', 'Moderated', NULL),
|
||||
(187, 3, 'VIEWER_CHANNEL_MODERATED', 'Moderowany', NULL),
|
||||
(188, 1, 'VIEWER_CHANNEL_MUSIC_CODED', 'Music codec', NULL),
|
||||
(189, 3, 'VIEWER_CHANNEL_MUSIC_CODED', 'Kodek muzyczny', NULL),
|
||||
(190, 1, 'VIEWER_CLIENT_AWAY', 'Away', NULL),
|
||||
(191, 3, 'VIEWER_CLIENT_AWAY', 'Zaraz wracam', NULL),
|
||||
(194, 1, 'VIEWER_CLIENT_OUTPUT_DISABLED', 'Sound disabled', NULL),
|
||||
(195, 3, 'VIEWER_CLIENT_OUTPUT_DISABLED', 'Głos wyłączony', NULL),
|
||||
(196, 1, 'VIEWER_CLIENT_OUTPUT_MUTED', 'Deafened', NULL),
|
||||
(197, 3, 'VIEWER_CLIENT_OUTPUT_MUTED', 'Głos wyciszony', NULL),
|
||||
(198, 1, 'VIEWER_CLIENT_MIC_DISABLED', 'Microphone disabled', NULL),
|
||||
(199, 3, 'VIEWER_CLIENT_MIC_DISABLED', 'Mikrofon wyłączony', NULL),
|
||||
(200, 1, 'VIEWER_CLIENT_MIC_MUTED', 'Muted', NULL),
|
||||
(201, 3, 'VIEWER_CLIENT_MIC_MUTED', 'Mikrofon wyciszony', NULL),
|
||||
(202, 1, 'VIEWER_CLIENT_COMMANDER', 'Channel commander', NULL),
|
||||
(203, 3, 'VIEWER_CLIENT_COMMANDER', 'Dowódca kanału', NULL),
|
||||
(204, 1, 'VIEWER_CLIENT_ICON', 'Client icon', NULL),
|
||||
(205, 3, 'VIEWER_CLIENT_ICON', 'Ikona klienta', NULL),
|
||||
(206, 1, 'VIEWER_CLIENT_PRIORITY_SPEAKER', 'Priority speaker', NULL),
|
||||
(207, 3, 'VIEWER_CLIENT_PRIORITY_SPEAKER', 'Mówca priorytetowy', NULL),
|
||||
(208, 1, 'VIEWER_CLIENT_TALK_POWER_GRANTED', 'Talk power granted', NULL),
|
||||
(209, 3, 'VIEWER_CLIENT_TALK_POWER_GRANTED', 'Moc konwersacji przyznana', NULL),
|
||||
(210, 1, 'VIEWER_CLIENT_TALK_POWER_INSUFFICIENT', 'Insufficient talk power', NULL),
|
||||
(211, 3, 'VIEWER_CLIENT_TALK_POWER_INSUFFICIENT', 'Niewystarczająca moc konwersacji', NULL),
|
||||
(212, 1, 'ASSIGNER_NOT_LOGGED_IN', 'Log in before using group assigner', NULL),
|
||||
(213, 3, 'ASSIGNER_NOT_LOGGED_IN', 'Zaloguj się przed przydzielaniem grup', NULL),
|
||||
(214, 1, 'ASSIGNER_LOGIN_BUTTON', 'Login', NULL),
|
||||
(215, 3, 'ASSIGNER_LOGIN_BUTTON', 'Zaloguj się', NULL),
|
||||
(216, 1, 'ASSIGNER_SAVE_BUTTON', 'Save', NULL),
|
||||
(217, 3, 'ASSIGNER_SAVE_BUTTON', 'Zapisz', NULL),
|
||||
(218, 1, 'ASSIGNER_INVALID_GROUPS', 'Invalid group settings', NULL),
|
||||
(219, 3, 'ASSIGNER_INVALID_GROUPS', 'Nieprawidłowe ustawienia grup', NULL),
|
||||
(220, 1, 'ASSIGNER_NOT_CONFIGURED', 'Group assigner is not configured by the website administrator', NULL),
|
||||
(221, 3, 'ASSIGNER_NOT_CONFIGURED', 'Przydzielanie grup nie jest skonfigurowane przez administratora strony', NULL),
|
||||
(222, 1, 'ASSIGNER_SAVE_SUCCESS', 'Your groups have been updated', NULL),
|
||||
(223, 3, 'ASSIGNER_SAVE_SUCCESS', 'Twoje grupy zostały zaktualizowane', NULL),
|
||||
(224, 1, 'ASSIGNER_SAVE_ERROR', 'Group change error', NULL),
|
||||
(225, 3, 'ASSIGNER_SAVE_ERROR', 'Błąd zmiany grup', NULL),
|
||||
(226, 1, 'ASSIGNER_SAVE_NO_CHANGE', 'No changes has been made', NULL),
|
||||
(227, 3, 'ASSIGNER_SAVE_NO_CHANGE', 'Nie wprowadzono żadnych zmian', NULL);
|
||||
(1, 'Welcome to ts-website!', 1, '2018-12-26 03:10:32', NULL, '<b>Hi there!</b> If you are reading this, it means that TS-website has been installed successfully.<br>\r\nYou can login to your <a href=\"admin\">ACP</a> to configure many parts of it.<br>\r\nNeed help? Join our <a href=\"https://t.me/tswebsite\" target=\"_blank\">Telegram group</a> for support.\r\nHave a good day!');
|
||||
|
||||
|
||||
ALTER TABLE `DBPREFIXconfig`
|
||||
@@ -316,25 +70,13 @@ ALTER TABLE `DBPREFIXconfig`
|
||||
ALTER TABLE `DBPREFIXfaq`
|
||||
ADD PRIMARY KEY (`faqid`);
|
||||
|
||||
ALTER TABLE `DBPREFIXlanguages`
|
||||
ADD PRIMARY KEY (`langid`);
|
||||
|
||||
ALTER TABLE `DBPREFIXnews`
|
||||
ADD PRIMARY KEY (`newsid`);
|
||||
|
||||
ALTER TABLE `DBPREFIXtranslations`
|
||||
ADD PRIMARY KEY (`id`);
|
||||
|
||||
|
||||
ALTER TABLE `DBPREFIXfaq`
|
||||
MODIFY `faqid` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4;
|
||||
|
||||
ALTER TABLE `DBPREFIXlanguages`
|
||||
MODIFY `langid` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4;
|
||||
|
||||
ALTER TABLE `DBPREFIXnews`
|
||||
MODIFY `newsid` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2;
|
||||
|
||||
ALTER TABLE `DBPREFIXtranslations`
|
||||
MODIFY `id` int(10) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=228;
|
||||
COMMIT;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -22,6 +22,10 @@ error_reporting(E_ALL);
|
||||
set_time_limit(0);
|
||||
|
||||
$stepNumber = empty($_GET["step"]) || !file_exists(__DIR__ . "/pages/" . (int)$_GET["step"] . ".php") ? 1 : (int) $_GET["step"];
|
||||
|
||||
ob_start();
|
||||
require __DIR__ . "/pages/$stepNumber.php";
|
||||
$pageContent = ob_get_clean();
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
@@ -80,7 +84,7 @@ $stepNumber = empty($_GET["step"]) || !file_exists(__DIR__ . "/pages/" . (int)$_
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<?php require_once __DIR__ . "/pages/$stepNumber.php" ?>
|
||||
<?= $pageContent ?>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
@@ -117,7 +117,12 @@
|
||||
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title text-center">Welcome to TS-website <?= __TSWEBSITE_VERSION ?> Installer!</h4>
|
||||
<h4 class="card-title text-center mb-0">Welcome to TS-website Installer!</h4>
|
||||
|
||||
<p class="card-text text-center text-muted font-italic mb-5">
|
||||
Version <?= __TSWEBSITE_VERSION ?> (<?= __TSWEBSITE_COMMIT ?>)
|
||||
</p>
|
||||
|
||||
<p class="card-text">This wizard will guide you through the installation process of TS-website.</p>
|
||||
<p class="card-text text-danger" id="hidejs">Please enable Javascript before continuing!</p>
|
||||
<p class="card-text">
|
||||
|
||||
@@ -11,6 +11,11 @@ if(!empty($_POST["allow-metrics-checkbox"])) {
|
||||
<div class="card-body">
|
||||
<h4 class="card-title text-center">Requirements check</h4>
|
||||
|
||||
<div class="alert alert-dark text-center mb-3" id="filePermError" style="display: none">
|
||||
Looks like you have failed file permission checks. Try running:<br>
|
||||
<code>sudo chown -R www-data:www-data "<?= realpath(__BASE_DIR) ?>"</code>
|
||||
</div>
|
||||
|
||||
<div class="text-center mb-2">
|
||||
<button class="btn btn-secondary" type="button" data-toggle="collapse" data-target="#requirementsTableCollapse">
|
||||
Show details
|
||||
@@ -38,6 +43,11 @@ if(!empty($_POST["allow-metrics-checkbox"])) {
|
||||
<script>
|
||||
// Show requirements table on error
|
||||
$("#requirementsTableCollapse").collapse("show")
|
||||
|
||||
<?php if(defined("FILE_PERM_ERROR")) { ?>
|
||||
// Show file permission fix tip
|
||||
$("#filePermError").show()
|
||||
<?php } ?>
|
||||
</script>
|
||||
<?php } else { ?>
|
||||
<div class="text-center">
|
||||
@@ -131,13 +141,13 @@ function checkRequirements() {
|
||||
// file / directory writable checks
|
||||
{
|
||||
// path => true if file, false if directory
|
||||
$paths = [
|
||||
$paths = array(
|
||||
__CONFIG_FILE => true,
|
||||
__INSTALLER_LOCK_FILE => true,
|
||||
__CACHE_DIR => false,
|
||||
__CACHE_DIR . "/templates" => false,
|
||||
__CACHE_DIR . "/servericons" => false,
|
||||
];
|
||||
);
|
||||
|
||||
foreach ($paths as $path => $isFile) {
|
||||
$exists = file_exists($path);
|
||||
@@ -161,7 +171,13 @@ function checkRequirements() {
|
||||
if(!$exists)
|
||||
$msg = ($isFile ? "File" : "Directory") . " <code>$realpath</code> does not exists, please create it";
|
||||
|
||||
showCheckResult("Is <code>$basename</code> writable?", $exists && $writable ? 0 : 2, $msg);
|
||||
$success = $exists && $writable;
|
||||
|
||||
if (!$success && !defined("FILE_PERM_ERROR")) {
|
||||
define("FILE_PERM_ERROR", true);
|
||||
}
|
||||
|
||||
showCheckResult("Is <code>$basename</code> writable?", $success ? 0 : 2, $msg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,8 +248,9 @@ function showCheckResult($name, $state, $resulttext) {
|
||||
} else {
|
||||
$attr = "fa-times-circle color-danger";
|
||||
|
||||
if(!defined("CANNOT_INSTALL"))
|
||||
if(!defined("CANNOT_INSTALL")) {
|
||||
define("CANNOT_INSTALL", true);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
+36
-21
@@ -44,24 +44,39 @@ if (!empty($_POST)) {
|
||||
if (isset($dbconfig)) {
|
||||
try {
|
||||
$db = new Medoo($dbconfig);
|
||||
$sqlfile = $usingMysql ? "dbinstall_mysql" : "dbinstall_sqlite";
|
||||
$sqlquery = file_get_contents(__DIR__ . "/../$sqlfile.sql");
|
||||
|
||||
if($sqlquery === false) {
|
||||
$errormessage = "Cannot read $sqlfile.sql file!";
|
||||
$sqlfiles = [];
|
||||
|
||||
if ($usingMysql) {
|
||||
$sqlfiles = [
|
||||
"dbinstall_mysql",
|
||||
"dbinstall_mysql_lang"
|
||||
];
|
||||
} else {
|
||||
// no other option yet
|
||||
}
|
||||
|
||||
foreach ($sqlfiles as $file) {
|
||||
$sqlquery = file_get_contents(__DIR__ . "/../$file.sql");
|
||||
|
||||
if($sqlquery === false) {
|
||||
throw new Exception("Cannot read SQL file: $file.sql");
|
||||
}
|
||||
|
||||
$sqlquery = str_replace("DBPREFIX", $dbprefix, $sqlquery);
|
||||
$sqlresult = $db->pdo->exec($sqlquery);
|
||||
|
||||
if($sqlresult === false) {
|
||||
if ($sqlresult === false) {
|
||||
throw new Exception("EXEC returned false");
|
||||
}
|
||||
}
|
||||
|
||||
$phpcode = <<<EOT
|
||||
// if all queries succeeded, create a config file and save connection info there
|
||||
$phpcode = <<<EOT
|
||||
<?php
|
||||
/*
|
||||
* TS-website database config file
|
||||
* Generated at %s with TS-website %s
|
||||
* Generated at %s with TS-website %s (%s)
|
||||
*/
|
||||
|
||||
return [
|
||||
@@ -69,24 +84,24 @@ return [
|
||||
];
|
||||
|
||||
EOT;
|
||||
$confarray = "";
|
||||
$confarray = "";
|
||||
|
||||
// Add all variables to the config
|
||||
foreach ($dbconfig as $key => $value) {
|
||||
$confarray .= sprintf(' "%s" => "%s",' . PHP_EOL, addcslashes($key, '"'), addcslashes($value, '"'));
|
||||
}
|
||||
// Add all variables to the config
|
||||
foreach ($dbconfig as $key => $value) {
|
||||
$confarray .= sprintf(' "%s" => "%s",' . PHP_EOL, addcslashes($key, '"'), addcslashes($value, '"'));
|
||||
}
|
||||
|
||||
// Remove semicolon and new line from the end
|
||||
$confarray = rtrim($confarray, "," . PHP_EOL);
|
||||
// Remove semicolon and new line from the end
|
||||
$confarray = rtrim($confarray, "," . PHP_EOL);
|
||||
|
||||
// Replace all variables with sprintf
|
||||
$phpcode = sprintf($phpcode, date("d-m-Y H:i:s"), __TSWEBSITE_VERSION, $confarray);
|
||||
// Replace all variables with sprintf
|
||||
$phpcode = sprintf($phpcode, date("d-m-Y H:i:s"), __TSWEBSITE_VERSION, __TSWEBSITE_COMMIT, $confarray);
|
||||
|
||||
if(file_put_contents(__CONFIG_FILE, $phpcode) === false) {
|
||||
$errormessage = "Cannot write to <code>" . __CONFIG_FILE . "</code>! Please check the file/directory permissions";
|
||||
} else {
|
||||
header("Location: ?step=" . ($stepNumber + 1));
|
||||
}
|
||||
if(file_put_contents(__CONFIG_FILE, $phpcode) === false) {
|
||||
$errormessage = "Cannot write to <code>" . __CONFIG_FILE . "</code>! Please check the file/directory permissions";
|
||||
} else {
|
||||
// redirect to next step on success
|
||||
header("Location: ?step=" . ($stepNumber + 1));
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$errormessage = htmlspecialchars("Error " . $e->getCode() . ": " . $e->getMessage());
|
||||
|
||||
@@ -13,6 +13,7 @@ if(!empty($_COOKIE["tsw_allow_metrics"])) {
|
||||
|
||||
$data = [
|
||||
"tswVersion" => __TSWEBSITE_VERSION,
|
||||
"tswCommit" => __TSWEBSITE_COMMIT,
|
||||
"phpVersion" => PHP_VERSION,
|
||||
"os" => sprintf("%s %s %s %s", php_uname("s"), php_uname("r"), php_uname("v"), php_uname("m")), // no hostname
|
||||
"webServer" => $_SERVER["SERVER_SOFTWARE"],
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
deny from all
|
||||
Vendored
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Wruczek\TSWebsite\Utils\Language;
|
||||
|
||||
use function htmlspecialchars;
|
||||
use Wruczek\PhpFileCache\PhpFileCache;
|
||||
use Wruczek\TSWebsite\Utils\DatabaseUtils;
|
||||
use Wruczek\TSWebsite\Utils\SingletonTait;
|
||||
|
||||
@@ -165,13 +165,13 @@ class TemplateUtils {
|
||||
}
|
||||
} else if (is_string($parameter)) {
|
||||
// NEEDS to start with a space!
|
||||
$attributes = ' integrity="' . htmlspecialchars($parameter) . '" crossorigin="anonymous"';
|
||||
$attributes = ' integrity="' . Utils::escape($parameter) . '" crossorigin="anonymous"';
|
||||
}
|
||||
|
||||
if ($resourceType === "stylesheet") {
|
||||
echo '<link rel="stylesheet" href="' . htmlspecialchars($url) . '"' . $attributes . '>';
|
||||
echo '<link rel="stylesheet" href="' . Utils::escape($url) . '"' . $attributes . '>';
|
||||
} else if ($resourceType === "script") {
|
||||
echo '<script src="' . htmlspecialchars($url) . '"' . $attributes . '></script>';
|
||||
echo '<script src="' . Utils::escape($url) . '"' . $attributes . '></script>';
|
||||
} else {
|
||||
throw new \InvalidArgumentException("$resourceType is not a valid resource type");
|
||||
}
|
||||
|
||||
@@ -9,12 +9,21 @@ use Wruczek\TSWebsite\News\INewsStore;
|
||||
/**
|
||||
* Class Utils
|
||||
* @package Wruczek\TSWebsite\Utils
|
||||
* @author Wruczek 2017
|
||||
* @author Wruczek 2017 - 2019
|
||||
*/
|
||||
class Utils {
|
||||
|
||||
private function __construct() {}
|
||||
|
||||
/**
|
||||
* Escapes HTML characters with htmlspecialchars
|
||||
* @param $string string String to be escaped
|
||||
* @return string escaped string
|
||||
*/
|
||||
public static function escape($string) {
|
||||
return htmlspecialchars((string) $string, ENT_QUOTES, "UTF-8");
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips the first line from string
|
||||
* https://stackoverflow.com/a/7740485
|
||||
@@ -100,7 +109,7 @@ class Utils {
|
||||
*/
|
||||
public static function getClientIp($useCfip = null) {
|
||||
if ($useCfip === null) {
|
||||
$useCfip = (bool) Config::get("usingcloudflare");
|
||||
$useCfip = Config::get("usingcloudflare");
|
||||
}
|
||||
|
||||
// If IPv6 localhost, return IPv4 localhost
|
||||
@@ -108,7 +117,7 @@ class Utils {
|
||||
return "127.0.0.1";
|
||||
}
|
||||
|
||||
if (!empty($_SERVER["HTTP_CF_CONNECTING_IP"]) && $useCfip) {
|
||||
if ($useCfip && !empty($_SERVER["HTTP_CF_CONNECTING_IP"])) {
|
||||
return $_SERVER["HTTP_CF_CONNECTING_IP"];
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace Wruczek\TSWebsite;
|
||||
|
||||
use function __get;
|
||||
use TeamSpeak3;
|
||||
use Wruczek\TSWebsite\Utils\Utils;
|
||||
|
||||
class ViewerRenderer {
|
||||
|
||||
@@ -77,7 +78,7 @@ EOD;
|
||||
$this->add(
|
||||
$html,
|
||||
$this->getIcon("server_green.svg"),
|
||||
htmlspecialchars($this->serverInfo["virtualserver_name"]),
|
||||
Utils::escape($this->serverInfo["virtualserver_name"]),
|
||||
$suffixIcons
|
||||
);
|
||||
|
||||
@@ -99,8 +100,8 @@ EOD;
|
||||
$path = "api/geticon.php?iconid=" . (int) $name;
|
||||
}
|
||||
|
||||
$ttip = $tooltip ? ' data-toggle="tooltip" title="' . htmlspecialchars($tooltip) . '"' : "";
|
||||
return '<img class="icon" src="' . $path . '" alt="' . htmlspecialchars($alt) . '"' . $ttip . '>';
|
||||
$ttip = $tooltip ? ' data-toggle="tooltip" title="' . Utils::escape($tooltip) . '"' : "";
|
||||
return '<img class="icon" src="' . $path . '" alt="' . Utils::escape($alt) . '"' . $ttip . '>';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -162,7 +163,7 @@ EOD;
|
||||
$channel->getId(),
|
||||
$channel->isSpacer() ? "" : ' tabindex="0"',
|
||||
$channelIcon,
|
||||
htmlspecialchars($channelDisplayName),
|
||||
Utils::escape($channelDisplayName),
|
||||
$suffixIcons
|
||||
);
|
||||
|
||||
@@ -222,7 +223,7 @@ EOD;
|
||||
$clientName = implode(" ", $beforeName); // prefix groups
|
||||
$clientName .= " {$client["client_nickname"]} "; // nickname
|
||||
$clientName .= implode(" ", $afterName); // suffix groups
|
||||
$clientName = htmlspecialchars(trim($clientName)); // trim and sanitize
|
||||
$clientName = Utils::escape(trim($clientName)); // trim and sanitize
|
||||
|
||||
$this->add(
|
||||
$html,
|
||||
@@ -286,7 +287,7 @@ EOD;
|
||||
}
|
||||
|
||||
if($client["client_away"]) {
|
||||
return $this->getIcon("away.svg", htmlspecialchars($client["client_away_message"]) ?: __get("VIEWER_CLIENT_AWAY"));
|
||||
return $this->getIcon("away.svg", Utils::escape($client["client_away_message"]) ?: __get("VIEWER_CLIENT_AWAY"));
|
||||
}
|
||||
|
||||
if(!$client["client_output_hardware"]) {
|
||||
@@ -340,7 +341,7 @@ EOD;
|
||||
// to show the group with a "broken-image" icons.
|
||||
}
|
||||
|
||||
$html .= $this->getIcon($icon, htmlspecialchars($group["name"]));
|
||||
$html .= $this->getIcon($icon, Utils::escape($group["name"]));
|
||||
}
|
||||
|
||||
if($client["client_icon_id"]) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?php
|
||||
define("__TSWEBSITE_VERSION", "dev-2.0.0");
|
||||
define("__TSWEBSITE_VERSION", "dev-2.0.1");
|
||||
define("__TSWEBSITE_COMMIT", "no-commit");
|
||||
define("__BASE_DIR", __DIR__ . "/../..");
|
||||
define("__PRIVATE_DIR", __BASE_DIR . "/private");
|
||||
define("__CACHE_DIR", __PRIVATE_DIR . "/cache");
|
||||
|
||||
@@ -4,6 +4,7 @@ use Wruczek\TSWebsite\Config;
|
||||
use Wruczek\TSWebsite\ServerIconCache;
|
||||
use Wruczek\TSWebsite\Utils\CsrfUtils;
|
||||
use Wruczek\TSWebsite\Utils\Language\LanguageUtils;
|
||||
use Wruczek\TSWebsite\Utils\Utils;
|
||||
|
||||
session_name("tswebsite_sessionid");
|
||||
|
||||
@@ -71,7 +72,7 @@ if(!isset($_SESSION["userlanguageid"])) {
|
||||
try {
|
||||
return LanguageUtils::i()->translate($identifier, $args);
|
||||
} catch (\Exception $e) {
|
||||
return "(unknown translation for " . htmlspecialchars($identifier) . ")";
|
||||
return "(unknown translation for " . Utils::escape($identifier) . ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,10 +35,10 @@
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<table id="banlist" class="table table-responsive">
|
||||
<table id="banlist" class="table display dt-responsive no-wrap" width="100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-priority="1">{_"BANS_HEADER_NAME"}</th>
|
||||
<th data-priority="1">{_"BANS_HEADER_TARGET"}</th>
|
||||
<th data-priority="3">{_"BANS_HEADER_REASON"}</th>
|
||||
<th>{_"BANS_HEADER_INVOKER"}</th>
|
||||
<th>{_"BANS_HEADER_BANDATE"}</th>
|
||||
@@ -49,8 +49,14 @@
|
||||
{foreach $banlist as $ban}
|
||||
{var $expiretime = $ban["created"] + $ban["duration"]}
|
||||
<tr>
|
||||
<td>{$ban["name"]}</td>
|
||||
<td>{$ban["reason"]}</td>
|
||||
<td data-filter="{$ban["filter"]}">{$ban["target"]}</td>
|
||||
<td>
|
||||
{if $ban["reason"]}
|
||||
{$ban["reason"]}
|
||||
{else}
|
||||
{_"NO_REASON_SET"|noescape}
|
||||
{/if}
|
||||
</td>
|
||||
<td>{$ban["invoker"]}</td>
|
||||
<td data-order="{$ban["created"]}">{$ban["created"]|fullDate}</td>
|
||||
<td data-order="{$ban["duration"]}">{$ban["duration"] ? ($expiretime|fuzzyDateAbbr) : ("BANS_NEVEREXPIRES"|translate)}</td>
|
||||
|
||||
@@ -12,6 +12,7 @@ $navActiveIndex = isset($navActiveIndex) ? (int) $navActiveIndex : 0;
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="generator" content="TS-website {\__TSWEBSITE_VERSION} by Wruczek / https://github.com/Wruczek/ts-website">
|
||||
<meta name="csrf-token" content="{$csrfToken}">
|
||||
<link rel="shortcut icon" href="img/icons/defaulticon-16.png">
|
||||
|
||||
<!-- TODO make it use the language variable "WEBSITE_TITLE" after the ACP update -->
|
||||
<title>{$title} | {$config["website_title"]}</title>
|
||||
@@ -146,9 +147,9 @@ $navActiveIndex = isset($navActiveIndex) ? (int) $navActiveIndex : 0;
|
||||
|
||||
<footer class="footer d-md-flex">
|
||||
<div>
|
||||
© WebsiteTitle.tech {date("Y")}
|
||||
© {$config["website_title"]} {date("Y")}
|
||||
|
||||
{if $config["imprint_enabled"]}3
|
||||
{if $config["imprint_enabled"]}
|
||||
— <a href="{$config["imprint_url"]}">imprint</a>
|
||||
{/if}
|
||||
</div>
|
||||
@@ -210,7 +211,7 @@ $navActiveIndex = isset($navActiveIndex) ? (int) $navActiveIndex : 0;
|
||||
{block footerbottom}{/block}
|
||||
|
||||
<!--
|
||||
TS-website {\__TSWEBSITE_VERSION} by Wruczek
|
||||
TS-website {\__TSWEBSITE_VERSION} ({\__TSWEBSITE_COMMIT}) by Wruczek
|
||||
Generated in {@$tplutils::getRenderTime()} s
|
||||
MySQL queries: {$sqlCount}
|
||||
-->
|
||||
|
||||
Reference in New Issue
Block a user