diff --git a/.github/workflows/phpcsfixer.yml b/.github/workflows/phpcsfixer.yml
new file mode 100644
index 0000000..251dc51
--- /dev/null
+++ b/.github/workflows/phpcsfixer.yml
@@ -0,0 +1,32 @@
+name: "PHP-CS-Fixer"
+
+on:
+ push:
+ branches:
+ - master
+ pull_request:
+ schedule:
+ - cron: '0 15 * * 2'
+
+jobs:
+ code-style:
+ strategy:
+ fail-fast: false
+ matrix:
+ php_versions: [
+ '8.1', # PHP 8.2 is currently not (fully) supported by PHP-CS-Fixer
+ ]
+ name: PHP ${{ matrix.php_versions }}
+ runs-on: ubuntu-latest
+ steps:
+ - name: checkout repository
+ uses: actions/checkout@v3
+
+ - name: install dependencies
+ uses: php-actions/composer@v6
+ with:
+ dev: yes
+ php_version: ${{ matrix.php_versions }}
+
+ - name: run php-cs-fixer
+ run: ./vendor/bin/php-cs-fixer fix --config .php-cs-fixer.php --diff --dry-run
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..6d0b1b1
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+vendor/
+.php-cs-fixer.cache
diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php
new file mode 100644
index 0000000..0868a80
--- /dev/null
+++ b/.php-cs-fixer.php
@@ -0,0 +1,167 @@
+ true,
+ 'array_syntax' => ['syntax' => 'short'],
+ 'binary_operator_spaces' => [
+ 'default' => 'single_space',
+ 'operators' => ['=>' => null],
+ ],
+ 'blank_line_after_namespace' => true,
+ 'blank_line_after_opening_tag' => true,
+ 'blank_line_before_statement' => [
+ 'statements' => ['return'],
+ ],
+ 'braces' => true,
+ 'cast_spaces' => true,
+ 'class_attributes_separation' => [
+ 'elements' => [
+ 'const' => 'one',
+ 'method' => 'one',
+ 'property' => 'one',
+ 'trait_import' => 'none',
+ ],
+ ],
+ 'class_definition' => [
+ 'multi_line_extends_each_single_line' => true,
+ 'single_item_single_line' => true,
+ 'single_line' => true,
+ ],
+ 'curly_braces_position' => [
+ 'anonymous_classes_opening_brace' => 'next_line_unless_newline_at_signature_end',
+ ],
+ 'concat_space' => [
+ 'spacing' => 'none',
+ ],
+ 'constant_case' => ['case' => 'lower'],
+ 'declare_equal_normalize' => true,
+ 'elseif' => true,
+ 'encoding' => true,
+ 'full_opening_tag' => true,
+ 'fully_qualified_strict_types' => true, // added by Shift
+ 'function_declaration' => true,
+ 'function_typehint_space' => true,
+ 'general_phpdoc_tag_rename' => true,
+ 'heredoc_to_nowdoc' => true,
+ 'include' => true,
+ 'increment_style' => ['style' => 'post'],
+ 'indentation_type' => true,
+ 'linebreak_after_opening_tag' => true,
+ 'line_ending' => true,
+ 'lowercase_cast' => true,
+ 'lowercase_keywords' => true,
+ 'lowercase_static_reference' => true, // added from Symfony
+ 'magic_method_casing' => true, // added from Symfony
+ 'magic_constant_casing' => true,
+ 'method_argument_space' => [
+ 'on_multiline' => 'ignore',
+ ],
+ 'multiline_whitespace_before_semicolons' => [
+ 'strategy' => 'no_multi_line',
+ ],
+ 'native_function_casing' => true,
+ 'no_alias_functions' => true,
+ 'no_extra_blank_lines' => [
+ 'tokens' => [
+ 'extra',
+ 'throw',
+ 'use',
+ ],
+ ],
+ 'no_blank_lines_after_class_opening' => true,
+ 'no_blank_lines_after_phpdoc' => true,
+ 'no_closing_tag' => true,
+ 'no_empty_phpdoc' => true,
+ 'no_empty_statement' => true,
+ 'no_leading_import_slash' => true,
+ 'no_leading_namespace_whitespace' => true,
+ 'no_mixed_echo_print' => [
+ 'use' => 'echo',
+ ],
+ 'no_multiline_whitespace_around_double_arrow' => true,
+ 'no_short_bool_cast' => true,
+ 'no_singleline_whitespace_before_semicolons' => true,
+ 'no_spaces_after_function_name' => true,
+ 'no_spaces_around_offset' => [
+ 'positions' => ['inside', 'outside'],
+ ],
+ 'no_spaces_inside_parenthesis' => true,
+ 'no_trailing_comma_in_list_call' => true,
+ 'no_trailing_comma_in_singleline_array' => true,
+ 'no_trailing_whitespace' => true,
+ 'no_trailing_whitespace_in_comment' => true,
+ 'no_unneeded_control_parentheses' => [
+ 'statements' => ['break', 'clone', 'continue', 'echo_print', 'return', 'switch_case', 'yield'],
+ ],
+ 'no_unreachable_default_argument_value' => true,
+ 'no_useless_return' => true,
+ 'no_whitespace_before_comma_in_array' => true,
+ 'no_whitespace_in_blank_line' => true,
+ 'normalize_index_brace' => true,
+ 'not_operator_with_successor_space' => true,
+ 'object_operator_without_whitespace' => true,
+ 'ordered_imports' => ['sort_algorithm' => 'alpha'],
+ 'psr_autoloading' => true,
+ 'phpdoc_indent' => true,
+ 'phpdoc_inline_tag_normalizer' => true,
+ 'phpdoc_no_access' => true,
+ 'phpdoc_no_package' => true,
+ 'phpdoc_no_useless_inheritdoc' => true,
+ 'phpdoc_scalar' => true,
+ 'phpdoc_single_line_var_spacing' => true,
+ 'phpdoc_summary' => false,
+ 'phpdoc_to_comment' => false, // override to preserve user preference
+ 'phpdoc_tag_type' => true,
+ 'phpdoc_trim' => true,
+ 'phpdoc_types' => true,
+ 'phpdoc_var_without_name' => true,
+ 'self_accessor' => true,
+ 'short_scalar_cast' => true,
+ 'simplified_null_return' => false, // disabled as "risky"
+ 'single_blank_line_at_eof' => true,
+ 'single_blank_line_before_namespace' => true,
+ 'single_class_element_per_statement' => [
+ 'elements' => ['const', 'property'],
+ ],
+ 'single_import_per_statement' => true,
+ 'single_line_after_imports' => true,
+ 'single_line_comment_style' => [
+ 'comment_types' => ['hash'],
+ ],
+ 'single_quote' => true,
+ 'space_after_semicolon' => true,
+ 'standardize_not_equals' => true,
+ 'switch_case_semicolon_to_colon' => true,
+ 'switch_case_space' => true,
+ 'ternary_operator_spaces' => true,
+ 'trailing_comma_in_multiline' => ['elements' => ['arrays']],
+ 'trim_array_spaces' => true,
+ 'unary_operator_spaces' => true,
+ 'visibility_required' => [
+ 'elements' => ['method', 'property'],
+ ],
+ 'whitespace_after_comma_in_array' => true,
+];
+
+
+$finder = Finder::create()
+ ->in([
+ __DIR__ . '/api',
+ __DIR__ . '/jobs',
+ __DIR__ . '/languages',
+ __DIR__ . '/other',
+ __DIR__ . '/stats',
+ __DIR__ . '/webinterface',
+ ])
+ ->name('*.php')
+ ->ignoreDotFiles(true)
+ ->ignoreVCS(true);
+
+return (new Config)
+ ->setFinder($finder)
+ ->setRules($rules)
+ ->setRiskyAllowed(true)
+ ->setUsingCache(true);
diff --git a/README.md b/README.md
index 34f49a8..966201b 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,28 @@
# TSN-Ranksystem
   [](https://github.com/Newcomer1989/TSN-Ranksystem/issues)
+[](https://github.com/Newcomer1989/TSN-Ranksystem/actions/workflows/phpcsfixer.yml?branch=master)
The TSN Ranksystem is an easy to handle Level System to automatically grant ranks (servergroups) to users on a TeamSpeak Server for online time or online activity. You can create your own servergroups, with permissions, icons etc. of your choice, and define these for the Ranksystem. Its open source and so its free to use under the GNU license with version 3.
#### Official website: [TS-Ranksystem.com](https://ts-ranksystem.com)
+
+
+## Contributions / Development
+
+This section is only relevant, if you want to contribute to this project with code changes.
+
+
+### Code Style
+
+Please ensure, that you apply the current PHP-CS-Fixer rules for a standard coding style.
+
+This can be easily done using composer:
+
+```shell
+composer install
+```
+
+```shell
+composer run code-style
+```
diff --git a/api/index.php b/api/index.php
index 7644ae5..5996e17 100644
--- a/api/index.php
+++ b/api/index.php
@@ -1,588 +1,660 @@
- $desc) {
- if (hash_equals($apikey, $_GET['apikey'])) $matchkey = 1;
- }
- if ($matchkey == 0) {
- $json = array(
- "Error" => array(
- "invalid" => array(
- "apikey" => "API Key is invalid"
- )
- )
- );
- echo json_encode($json);
- exit;
- }
-} else {
- $json = array(
- "Error" => array(
- "required" => array(
- "apikey" => array(
- "desc" => "API Key for authentification. API keys can be created inside the Ranksystem Webinterface",
- "usage" => "Use \$_GET parameter 'apikey' and add as value a valid API key",
- "example" => "/api/?apikey=XXXXX"
- )
- )
- )
- );
- echo json_encode($json);
- exit;
-}
-
-$limit = (isset($_GET['limit']) && is_numeric($_GET['limit']) && $_GET['limit'] > 0 && $_GET['limit'] <= 1000) ? $_GET['limit'] : 100;
-$sort = (isset($_GET['sort'])) ? htmlspecialchars_decode($_GET['sort']) : '1';
-$order = (isset($_GET['order']) && strtolower($_GET['order']) == 'desc') ? 'DESC' : 'ASC';
-$part = (isset($_GET['part']) && is_numeric($_GET['part']) && $_GET['part'] > 0) ? (($_GET['part'] - 1) * $limit) : 0;
-
-if (isset($_GET['bot'])) {
- if(!isset($_GET['check']) && !isset($_GET['restart']) && !isset($_GET['start']) && !isset($_GET['stop'])) {
- $json = array(
- "usage" => array(
- "_desc" => array(
- "0" => "You are able to use bot commands with this function (start, stop, ..).",
- "1" => "Use the Parameter, which are described below!",
- "2" => "",
- "3" => "Return values are:",
- "4" => "- 'rc'",
- "5" => "- 'msg'",
- "6" => "- 'ranksystemlog'",
- "7" => "",
- "8" => "# RC",
- "9" => "The return Code of the transaction (i.e. start process):",
- "10" => "0 - EXIT_SUCCESS",
- "11" => "1 - EXIT_FAILURE",
- "12" => "",
- "13" => "# MSG",
- "14" => "An additional message of the process. In case of EXIT_FAILURE, you will receive here an error message.",
- "15" => "",
- "16" => "# RANKSYSTEMLOG",
- "17" => "A short log extract of the last rows of the Ranksystem logfile to get more information about the Bot itself.",
- ),
- "check" => array(
- "desc" => "Check the Ranksystem Bot is running. If not, it will be started with this.",
- "usage" => "Use \$_GET parameter 'check' without any value",
- "example" => "/api/?bot&check"
- ),
- "restart" => array(
- "desc" => "Restarts the Ranksystem Bot.",
- "usage" => "Use \$_GET parameter 'restart' without any value",
- "example" => "/api/?bot&restart"
- ),
- "start" => array(
- "desc" => "Starts the Ranksystem Bot.",
- "usage" => "Use \$_GET parameter 'start' without any value",
- "example" => "/api/?bot&start"
- ),
- "stop" => array(
- "desc" => "Stops the Ranksystem Bot",
- "usage" => "Use \$_GET parameter 'stop' without any value",
- "example" => "/api/?bot&stop"
- )
- )
- );
- } else {
- $check_permission = 0;
- foreach($cfg['stats_api_keys'] as $apikey => $desc) {
- if (hash_equals($apikey, $_GET['apikey']) && $desc['perm_bot'] == 1) {
- $check_permission = 1;
- break;
- }
- }
- if ($check_permission == 1) {
- if(isset($_GET['check'])) {
- $result = bot_check();
- } elseif(isset($_GET['restart'])) {
- $result = bot_restart();
- } elseif(isset($_GET['start'])) {
- $result = bot_start();
- } elseif(isset($_GET['stop'])) {
- $result = bot_stop();
- }
- if(isset($result['log']) && $result['log'] != NULL) {
- $ranksystemlog = $result['log'];
- } else {
- $ranksystemlog = "NULL";
- }
- $json = array(
- "rc" => $result['rc'],
- "msg" => $result['msg'],
- "ranksystemlog" => $ranksystemlog
- );
- } else {
- $json = array(
- "Error" => array(
- "invalid" => array(
- "permissions" => "API Key is not permitted to start/stop the Ranksystem Bot"
- )
- )
- );
- echo json_encode($json);
- exit;
- }
- }
-} elseif (isset($_GET['groups'])) {
- $sgidname = $all = '----------_none_selected_----------';
- $sgid = -1;
- if(isset($_GET['all'])) $all = 1;
- if(isset($_GET['sgid'])) $sgid = htmlspecialchars_decode($_GET['sgid']);
- if(isset($_GET['sgidname'])) $sgidname = htmlspecialchars_decode($_GET['sgidname']);
-
- if($sgid == -1 && $sgidname == '----------_none_selected_----------' && $all == '----------_none_selected_----------') {
- $json = array(
- "usage" => array(
- "all" => array(
- "desc" => "Get details about all TeamSpeak servergroups",
- "usage" => "Use \$_GET parameter 'all' without any value",
- "example" => "/api/?groups&all"
- ),
- "limit" => array(
- "desc" => "Define a number that limits the number of results. Maximum value is 1000. Default is 100.",
- "usage" => "Use \$_GET parameter 'limit' and add as value a number above 1",
- "example" => "/api/?groups&limit=10"
- ),
- "order" => array(
- "desc" => "Define a sorting order. Value of 'sort' param is necessary.",
- "usage" => "Use \$_GET parameter 'order' and add as value 'asc' for ascending or 'desc' for descending",
- "example" => "/api/?groups&all&sort=sgid&order=asc"
- ),
- "sgid" => array(
- "desc" => "Get details about TeamSpeak servergroups by the servergroup TS-database-ID",
- "usage" => "Use \$_GET parameter 'sgid' and add as value the servergroup TS-database-ID",
- "example" => "/api/?groups&sgid=123"
- ),
- "sgidname" => array(
- "desc" => "Get details about TeamSpeak servergroups by servergroup name or a part of it",
- "usage" => "Use \$_GET parameter 'sgidname' and add as value a name or a part of it",
- "example" => array(
- "1" => array(
- "desc" => "Filter by servergroup name",
- "url" => "/api/?groups&sgidname=Level01"
- ),
- "2" => array(
- "desc" => "Filter by servergroup name with a percent sign as placeholder",
- "url" => "/api/?groups&sgidname=Level%"
- )
- )
- ),
- "sort" => array(
- "desc" => "Define a sorting. Available is each column name, which is given back as a result.",
- "usage" => "Use \$_GET parameter 'sort' and add as value a column name",
- "example" => array(
- "1" => array(
- "desc" => "Sort by servergroup name",
- "url" => "/api/?groups&all&sort=sgidname"
- ),
- "2" => array(
- "desc" => "Sort by TeamSpeak sort-ID",
- "url" => "/api/?groups&all&sort=sortid"
- )
- )
- )
- )
- );
- } else {
- if ($all == 1) {
- $dbdata = $mysqlcon->prepare("SELECT * FROM `$dbname`.`groups` ORDER BY {$sort} {$order} LIMIT :start, :limit");
- } else {
- $dbdata = $mysqlcon->prepare("SELECT * FROM `$dbname`.`groups` WHERE (`sgidname` LIKE :sgidname OR `sgid` LIKE :sgid) ORDER BY {$sort} {$order} LIMIT :start, :limit");
- $dbdata->bindValue(':sgidname', '%'.$sgidname.'%', PDO::PARAM_STR);
- $dbdata->bindValue(':sgid', (int) $sgid, PDO::PARAM_INT);
- }
- $dbdata->bindValue(':start', (int) $part, PDO::PARAM_INT);
- $dbdata->bindValue(':limit', (int) $limit, PDO::PARAM_INT);
- $dbdata->execute();
- $json = $dbdata->fetchAll(PDO::FETCH_ASSOC|PDO::FETCH_UNIQUE);
- foreach ($json as $sgid => $sqlpart) {
- if ($sqlpart['icondate'] != 0 && $sqlpart['sgidname'] == 'ServerIcon') {
- $json[$sgid]['iconpath'] = './tsicons/servericon.'.$sqlpart['ext'];
- } elseif ($sqlpart['icondate'] == 0 && $sqlpart['iconid'] > 0 && $sqlpart['iconid'] < 601) {
- $json[$sgid]['iconpath'] = './tsicons/'.$sqlpart['iconid'].'.'.$sqlpart['ext'];
- } elseif ($sqlpart['icondate'] != 0) {
- $json[$sgid]['iconpath'] = './tsicons/'.$sgid.'.'.$sqlpart['ext'];
- } else {
- $json[$sgid]['iconpath'] = '';
- }
- }
- }
-} elseif (isset($_GET['rankconfig'])) {
- $dbdata = $mysqlcon->prepare("SELECT * FROM `$dbname`.`cfg_params` WHERE `param` in ('rankup_definition', 'rankup_time_assess_mode')");
- $dbdata->execute();
- $sql = $dbdata->fetchAll(PDO::FETCH_KEY_PAIR);
- $json = array();
- if ($sql['rankup_time_assess_mode'] == 1) {
- $modedesc = "active time";
- } else {
- $modedesc = "online time";
- }
- $json['rankup_time_assess_mode'] = array (
- "mode" => $sql['rankup_time_assess_mode'],
- "mode_desc" => $modedesc
- );
- $count = 0;
- foreach (explode(',', $sql['rankup_definition']) as $entry) {
- list($key, $value) = explode('=>', $entry);
- $addnewvalue1[$count] = array(
- "grpid" => $value,
- "seconds" => $key
- );
- $count++;
- $json['rankup_definition'] = $addnewvalue1;
- }
-} elseif (isset($_GET['server'])) {
- $dbdata = $mysqlcon->prepare("SELECT 0 as `row`, `$dbname`.`stats_server`.* FROM `$dbname`.`stats_server`");
- $dbdata->execute();
- $json = $dbdata->fetchAll(PDO::FETCH_ASSOC|PDO::FETCH_UNIQUE);
-} elseif (isset($_GET['user'])) {
- $filter = ' WHERE';
- if(isset($_GET['cldbid'])) {
- $cldbid = htmlspecialchars_decode($_GET['cldbid']);
- if($filter != ' WHERE') $filter .= " AND";
- $filter .= ' `cldbid` LIKE :cldbid';
- }
- if(isset($_GET['groupid'])) {
- $groupid = htmlspecialchars_decode($_GET['groupid']);
- $explode_groupid = explode(',', $groupid);
- if($filter != ' WHERE') $filter .= " AND";
- $filter .= " (";
- $cnt = 0;
- foreach($explode_groupid as $groupid) {
- if($cnt > 0) $filter .= " OR ";
- $filter .= "`cldgroup` = :groupid".$cnt; $cnt++;
- $filter .= " OR `cldgroup` LIKE (:groupid".$cnt.")"; $cnt++;
- $filter .= " OR `cldgroup` LIKE (:groupid".$cnt.")"; $cnt++;
- $filter .= " OR `cldgroup` LIKE (:groupid".$cnt.")"; $cnt++;
- }
- $filter .= ")";
- }
- if(isset($_GET['name'])) {
- $name = htmlspecialchars_decode($_GET['name']);
- if($filter != ' WHERE') $filter .= " AND";
- $filter .= ' `name` LIKE :name';
- }
- if(!isset($_GET['sort'])) $sort = '`rank`';
- if(isset($_GET['status']) && $_GET['status'] == strtolower('online')) {
- if($filter != ' WHERE') $filter .= " AND";
- $filter .= " `online`=1";
- } elseif(isset($_GET['status']) && $_GET['status'] == strtolower('offline')) {
- if($filter != ' WHERE') $filter .= " AND";
- $filter .= " `online`=0";
- }
- if(isset($_GET['uuid'])) {
- $uuid = htmlspecialchars_decode($_GET['uuid']);
- if($filter != ' WHERE') $filter .= " AND";
- $filter .= ' `uuid` LIKE :uuid';
- }
- if($filter == ' WHERE') $filter = '';
-
- if($filter == '' && !isset($_GET['all']) && !isset($_GET['cldbid']) && !isset($_GET['name']) && !isset($_GET['uuid'])) {
- $json = array(
- "usage" => array(
- "all" => array(
- "desc" => "Get details about all TeamSpeak user. Result is limited by 100 entries.",
- "usage" => "Use \$_GET parameter 'all' without any value",
- "example" => "/api/?user&all"
- ),
- "cldbid" => array(
- "desc" => "Get details about TeamSpeak user by client TS-database ID",
- "usage" => "Use \$_GET parameter 'cldbid' and add as value a single client TS-database ID",
- "example" => "/api/?user&cldbid=7775"
- ),
- "groupid" => array(
- "desc" => "Get only user, which are in the given servergroup database ID",
- "usage" => "Use \$_GET parameter 'groupid' and add as value a database ID of a servergroup. Multiple servergroups can be specified comma-separated.",
- "example" => array(
- "1" => array(
- "desc" => "Filter by a single servergroup database ID",
- "url" => "/api/?userstats&groupid=6"
- ),
- "2" => array(
- "desc" => "Filter by multiple servergroup database IDs. Only one of the specified groups must apply to get the concerned user.",
- "url" => "/api/?userstats&groupid=6,9,48"
- )
- )
- ),
- "limit" => array(
- "desc" => "Define a number that limits the number of results. Maximum value is 1000. Default is 100.",
- "usage" => "Use \$_GET parameter 'limit' and add as value a number above 1",
- "example" => "/api/?user&all&limit=10"
- ),
- "name" => array(
- "desc" => "Get details about TeamSpeak user by client nickname",
- "usage" => "Use \$_GET parameter 'name' and add as value a name or a part of it",
- "example" => array(
- "1" => array(
- "desc" => "Filter by client nickname",
- "url" => "/api/?user&name=Newcomer1989"
- ),
- "2" => array(
- "desc" => "Filter by client nickname with a percent sign as placeholder",
- "url" => "/api/?user&name=%user%"
- )
- )
- ),
- "order" => array(
- "desc" => "Define a sorting order.",
- "usage" => "Use \$_GET parameter 'order' and add as value 'asc' for ascending or 'desc' for descending",
- "example" => "/api/?user&all&order=asc"
- ),
- "part" => array(
- "desc" => "Define, which part of the result you want to get. This is needed, when more then 100 clients are inside the result. At default you will get the first 100 clients. To get the next 100 clients, you will need to ask for part 2.",
- "usage" => "Use \$_GET parameter 'part' and add as value a number above 1",
- "example" => "/api/?user&name=TeamSpeakUser&part=2"
- ),
- "sort" => array(
- "desc" => "Define a sorting. Available is each column name, which is given back as a result.",
- "usage" => "Use \$_GET parameter 'sort' and add as value a column name",
- "example" => array(
- "1" => array(
- "desc" => "Sort by online time",
- "url" => "/api/?user&all&sort=count"
- ),
- "2" => array(
- "desc" => "Sort by active time",
- "url" => "/api/?user&all&sort=(count-idle)"
- ),
- "3" => array(
- "desc" => "Sort by rank",
- "url" => "/api/?user&all&sort=rank"
- )
- )
- ),
- "status" => array(
- "desc" => "List only clients, which status is online or offline.",
- "usage" => "Use \$_GET parameter 'status' and add as value 'online' or 'offline'",
- "example" => "/api/?userstats&status=online"
- ),
- "uuid" => array(
- "desc" => "Get details about TeamSpeak user by unique client ID",
- "usage" => "Use \$_GET parameter 'uuid' and add as value one unique client ID or a part of it",
- "example" => "/api/?user&uuid=xrTKhT/HDl4ea0WoFDQH2zOpmKg="
- )
- )
- );
- } else {
- $dbdata = $mysqlcon->prepare("SELECT * FROM `$dbname`.`user` {$filter} ORDER BY {$sort} {$order} LIMIT :start, :limit");
- if(isset($_GET['cldbid'])) $dbdata->bindValue(':cldbid', (int) $cldbid, PDO::PARAM_INT);
- if(isset($_GET['groupid'])) {
- $groupid = htmlspecialchars_decode($_GET['groupid']);
- $explode_groupid = explode(',', $groupid);
- $cnt = 0;
- foreach($explode_groupid as $groupid) {
- $dbdata->bindValue(':groupid'.$cnt, $groupid, PDO::PARAM_STR); $cnt++;
- $dbdata->bindValue(':groupid'.$cnt, $groupid.',%', PDO::PARAM_STR); $cnt++;
- $dbdata->bindValue(':groupid'.$cnt, '%,'.$groupid.',%', PDO::PARAM_STR); $cnt++;
- $dbdata->bindValue(':groupid'.$cnt, '%,'.$groupid, PDO::PARAM_STR); $cnt++;
- }
- }
- if(isset($_GET['name'])) $dbdata->bindValue(':name', '%'.$name.'%', PDO::PARAM_STR);
- if(isset($_GET['uuid'])) $dbdata->bindValue(':uuid', '%'.$uuid.'%', PDO::PARAM_STR);
-
- $dbdata->bindValue(':start', (int) $part, PDO::PARAM_INT);
- $dbdata->bindValue(':limit', (int) $limit, PDO::PARAM_INT);
- $dbdata->execute();
- $json = $dbdata->fetchAll(PDO::FETCH_ASSOC|PDO::FETCH_UNIQUE);
- }
-} elseif (isset($_GET['userstats'])) {
- $filter = ' WHERE';
- if(isset($_GET['cldbid'])) {
- $cldbid = htmlspecialchars_decode($_GET['cldbid']);
- if($filter != ' WHERE') $filter .= " AND";
- $filter .= ' `cldbid` LIKE :cldbid';
- }
- if(isset($_GET['groupid'])) {
- $groupid = htmlspecialchars_decode($_GET['groupid']);
- $explode_groupid = explode(',', $groupid);
- if($filter != ' WHERE') $filter .= " AND";
- $filter .= " (";
- $cnt = 0;
- foreach($explode_groupid as $groupid) {
- if($cnt > 0) $filter .= " OR ";
- $filter .= "`user`.`cldgroup` = :groupid".$cnt; $cnt++;
- $filter .= " OR `user`.`cldgroup` LIKE (:groupid".$cnt.")"; $cnt++;
- $filter .= " OR `user`.`cldgroup` LIKE (:groupid".$cnt.")"; $cnt++;
- $filter .= " OR `user`.`cldgroup` LIKE (:groupid".$cnt.")"; $cnt++;
- }
- $filter .= ")";
- }
- if(isset($_GET['name'])) {
- $name = htmlspecialchars_decode($_GET['name']);
- if($filter != ' WHERE') $filter .= " AND";
- $filter .= ' `user`.`name` LIKE :name';
- }
- if(!isset($_GET['sort'])) $sort = '`count_week`';
- if(isset($_GET['status']) && $_GET['status'] == strtolower('online')) {
- if($filter != ' WHERE') $filter .= " AND";
- $filter .= " `user`.`online`=1";
- } elseif(isset($_GET['status']) && $_GET['status'] == strtolower('offline')) {
- if($filter != ' WHERE') $filter .= " AND";
- $filter .= " `user`.`online`=0";
- }
- if(isset($_GET['uuid'])) {
- $uuid = htmlspecialchars_decode($_GET['uuid']);
- if($filter != ' WHERE') $filter .= " AND";
- $filter .= ' `user`.`uuid` LIKE :uuid';
- }
- if($filter == ' WHERE') $filter = '';
-
- if($filter == '' && !isset($_GET['all']) && !isset($_GET['cldbid']) && !isset($_GET['name']) && !isset($_GET['uuid'])) {
- $json = array(
- "usage" => array(
- "all" => array(
- "desc" => "Get additional statistics about all TeamSpeak user. Result is limited by 100 entries.",
- "usage" => "Use \$_GET parameter 'all' without any value",
- "example" => "/api/?userstats&all"
- ),
- "cldbid" => array(
- "desc" => "Get details about TeamSpeak user by client TS-database ID",
- "usage" => "Use \$_GET parameter 'cldbid' and add as value a single client TS-database ID",
- "example" => "/api/?userstats&cldbid=7775"
- ),
- "groupid" => array(
- "desc" => "Get only user, which are in the given servergroup database ID",
- "usage" => "Use \$_GET parameter 'groupid' and add as value a database ID of a servergroup. Multiple servergroups can be specified comma-separated.",
- "example" => array(
- "1" => array(
- "desc" => "Filter by a single servergroup database ID",
- "url" => "/api/?userstats&groupid=6"
- ),
- "2" => array(
- "desc" => "Filter by multiple servergroup database IDs. Only one of the specified groups must apply to get the concerned user.",
- "url" => "/api/?userstats&groupid=6,9,48"
- )
- )
- ),
- "limit" => array(
- "desc" => "Define a number that limits the number of results. Maximum value is 1000. Default is 100.",
- "usage" => "Use \$_GET parameter 'limit' and add as value a number above 1",
- "example" => "/api/?userstats&limit=10"
- ),
- "name" => array(
- "desc" => "Get details about TeamSpeak user by client nickname",
- "usage" => "Use \$_GET parameter 'name' and add as value a name or a part of it",
- "example" => array(
- "1" => array(
- "desc" => "Filter by client nickname",
- "url" => "/api/?userstats&name=Newcomer1989"
- ),
- "2" => array(
- "desc" => "Filter by client nickname with a percent sign as placeholder",
- "url" => "/api/?userstats&name=%user%"
- )
- )
- ),
- "order" => array(
- "desc" => "Define a sorting order.",
- "usage" => "Use \$_GET parameter 'order' and add as value 'asc' for ascending or 'desc' for descending",
- "example" => "/api/?userstats&all&order=asc"
- ),
- "part" => array(
- "desc" => "Define, which part of the result you want to get. This is needed, when more then 100 clients are inside the result. At default you will get the first 100 clients. To get the next 100 clients, you will need to ask for part 2.",
- "usage" => "Use \$_GET parameter 'part' and add as value a number above 1",
- "example" => "/api/?userstats&all&part=2"
- ),
- "sort" => array(
- "desc" => "Define a sorting. Available is each column name, which is given back as a result.",
- "usage" => "Use \$_GET parameter 'sort' and add as value a column name",
- "example" => array(
- "1" => array(
- "desc" => "Sort by online time of the week",
- "url" => "/api/?userstats&all&sort=count_week"
- ),
- "2" => array(
- "desc" => "Sort by active time of the week",
- "url" => "/api/?userstats&all&sort=(count_week-idle_week)"
- ),
- "3" => array(
- "desc" => "Sort by online time of the month",
- "url" => "/api/?userstats&all&sort=count_month"
- )
- )
- ),
- "status" => array(
- "desc" => "List only clients, which status is online or offline.",
- "usage" => "Use \$_GET parameter 'status' and add as value 'online' or 'offline'",
- "example" => "/api/?userstats&status=online"
- ),
- "uuid" => array(
- "desc" => "Get additional statistics about TeamSpeak user by unique client ID",
- "usage" => "Use \$_GET parameter 'uuid' and add as value one unique client ID or a part of it",
- "example" => "/api/?userstats&uuid=xrTKhT/HDl4ea0WoFDQH2zOpmKg="
- )
- )
- );
- } else {
- $dbdata = $mysqlcon->prepare("SELECT * FROM `$dbname`.`stats_user` INNER JOIN `$dbname`.`user` ON `user`.`uuid` = `stats_user`.`uuid` {$filter} ORDER BY {$sort} {$order} LIMIT :start, :limit");
- if(isset($_GET['cldbid'])) $dbdata->bindValue(':cldbid', (int) $cldbid, PDO::PARAM_INT);
- if(isset($_GET['groupid'])) {
- $groupid = htmlspecialchars_decode($_GET['groupid']);
- $explode_groupid = explode(',', $groupid);
- $cnt = 0;
- foreach($explode_groupid as $groupid) {
- $dbdata->bindValue(':groupid'.$cnt, $groupid, PDO::PARAM_STR); $cnt++;
- $dbdata->bindValue(':groupid'.$cnt, $groupid.',%', PDO::PARAM_STR); $cnt++;
- $dbdata->bindValue(':groupid'.$cnt, '%,'.$groupid.',%', PDO::PARAM_STR); $cnt++;
- $dbdata->bindValue(':groupid'.$cnt, '%,'.$groupid, PDO::PARAM_STR); $cnt++;
- }
- }
- if(isset($_GET['name'])) $dbdata->bindValue(':name', '%'.$name.'%', PDO::PARAM_STR);
- if(isset($_GET['uuid'])) $dbdata->bindValue(':uuid', '%'.$uuid.'%', PDO::PARAM_STR);
-
- $dbdata->bindValue(':start', (int) $part, PDO::PARAM_INT);
- $dbdata->bindValue(':limit', (int) $limit, PDO::PARAM_INT);
- $dbdata->execute();
- $json = $dbdata->fetchAll(PDO::FETCH_ASSOC|PDO::FETCH_UNIQUE);
- }
-} else {
- $json = array(
- "usage" => array(
- "bot" => array(
- "desc" => "Use this to trigger Bot commands as starting or stopping the Ranksystem Bot.",
- "usage" => "Use \$_GET parameter 'bot'",
- "example" => "/api/?bot"
- ),
- "groups" => array(
- "desc" => "Get details about the TeamSpeak servergroups",
- "usage" => "Use \$_GET parameter 'groups'",
- "example" => "/api/?groups"
- ),
- "rankconfig" => array(
- "desc" => "Get the rankup definition, which contains the assignment of (needed) time to servergroup",
- "usage" => "Use \$_GET parameter 'rankconfig'",
- "example" => "/api/?rankconfig"
- ),
- "server" => array(
- "desc" => "Get details about the TeamSpeak server",
- "usage" => "Use \$_GET parameter 'server'",
- "example" => "/api/?server"
- ),
- "user" => array(
- "desc" => "Get details about the TeamSpeak user",
- "usage" => "Use \$_GET parameter 'user'",
- "example" => "/api/?user"
- ),
- "userstats" => array(
- "desc" => "Get additional statistics about the TeamSpeak user",
- "usage" => "Use \$_GET parameter 'userstats'",
- "example" => "/api/?userstats"
- )
- )
- );
-}
-
-echo json_encode($json);
-?>
\ No newline at end of file
+ $desc) {
+ if (hash_equals($apikey, $_GET['apikey'])) {
+ $matchkey = 1;
+ }
+ }
+ if ($matchkey == 0) {
+ $json = [
+ 'Error' => [
+ 'invalid' => [
+ 'apikey' => 'API Key is invalid',
+ ],
+ ],
+ ];
+ echo json_encode($json);
+ exit;
+ }
+} else {
+ $json = [
+ 'Error' => [
+ 'required' => [
+ 'apikey' => [
+ 'desc' => 'API Key for authentification. API keys can be created inside the Ranksystem Webinterface',
+ 'usage' => "Use \$_GET parameter 'apikey' and add as value a valid API key",
+ 'example' => '/api/?apikey=XXXXX',
+ ],
+ ],
+ ],
+ ];
+ echo json_encode($json);
+ exit;
+}
+
+$limit = (isset($_GET['limit']) && is_numeric($_GET['limit']) && $_GET['limit'] > 0 && $_GET['limit'] <= 1000) ? $_GET['limit'] : 100;
+$sort = (isset($_GET['sort'])) ? htmlspecialchars_decode($_GET['sort']) : '1';
+$order = (isset($_GET['order']) && strtolower($_GET['order']) == 'desc') ? 'DESC' : 'ASC';
+$part = (isset($_GET['part']) && is_numeric($_GET['part']) && $_GET['part'] > 0) ? (($_GET['part'] - 1) * $limit) : 0;
+
+if (isset($_GET['bot'])) {
+ if (! isset($_GET['check']) && ! isset($_GET['restart']) && ! isset($_GET['start']) && ! isset($_GET['stop'])) {
+ $json = [
+ 'usage' => [
+ '_desc' => [
+ '0' => 'You are able to use bot commands with this function (start, stop, ..).',
+ '1' => 'Use the Parameter, which are described below!',
+ '2' => '',
+ '3' => 'Return values are:',
+ '4' => "- 'rc'",
+ '5' => "- 'msg'",
+ '6' => "- 'ranksystemlog'",
+ '7' => '',
+ '8' => '# RC',
+ '9' => 'The return Code of the transaction (i.e. start process):',
+ '10' => '0 - EXIT_SUCCESS',
+ '11' => '1 - EXIT_FAILURE',
+ '12' => '',
+ '13' => '# MSG',
+ '14' => 'An additional message of the process. In case of EXIT_FAILURE, you will receive here an error message.',
+ '15' => '',
+ '16' => '# RANKSYSTEMLOG',
+ '17' => 'A short log extract of the last rows of the Ranksystem logfile to get more information about the Bot itself.',
+ ],
+ 'check' => [
+ 'desc' => 'Check the Ranksystem Bot is running. If not, it will be started with this.',
+ 'usage' => "Use \$_GET parameter 'check' without any value",
+ 'example' => '/api/?bot&check',
+ ],
+ 'restart' => [
+ 'desc' => 'Restarts the Ranksystem Bot.',
+ 'usage' => "Use \$_GET parameter 'restart' without any value",
+ 'example' => '/api/?bot&restart',
+ ],
+ 'start' => [
+ 'desc' => 'Starts the Ranksystem Bot.',
+ 'usage' => "Use \$_GET parameter 'start' without any value",
+ 'example' => '/api/?bot&start',
+ ],
+ 'stop' => [
+ 'desc' => 'Stops the Ranksystem Bot',
+ 'usage' => "Use \$_GET parameter 'stop' without any value",
+ 'example' => '/api/?bot&stop',
+ ],
+ ],
+ ];
+ } else {
+ $check_permission = 0;
+ foreach ($cfg['stats_api_keys'] as $apikey => $desc) {
+ if (hash_equals($apikey, $_GET['apikey']) && $desc['perm_bot'] == 1) {
+ $check_permission = 1;
+ break;
+ }
+ }
+ if ($check_permission == 1) {
+ if (isset($_GET['check'])) {
+ $result = bot_check();
+ } elseif (isset($_GET['restart'])) {
+ $result = bot_restart();
+ } elseif (isset($_GET['start'])) {
+ $result = bot_start();
+ } elseif (isset($_GET['stop'])) {
+ $result = bot_stop();
+ }
+ if (isset($result['log']) && $result['log'] != null) {
+ $ranksystemlog = $result['log'];
+ } else {
+ $ranksystemlog = 'NULL';
+ }
+ $json = [
+ 'rc' => $result['rc'],
+ 'msg' => $result['msg'],
+ 'ranksystemlog' => $ranksystemlog,
+ ];
+ } else {
+ $json = [
+ 'Error' => [
+ 'invalid' => [
+ 'permissions' => 'API Key is not permitted to start/stop the Ranksystem Bot',
+ ],
+ ],
+ ];
+ echo json_encode($json);
+ exit;
+ }
+ }
+} elseif (isset($_GET['groups'])) {
+ $sgidname = $all = '----------_none_selected_----------';
+ $sgid = -1;
+ if (isset($_GET['all'])) {
+ $all = 1;
+ }
+ if (isset($_GET['sgid'])) {
+ $sgid = htmlspecialchars_decode($_GET['sgid']);
+ }
+ if (isset($_GET['sgidname'])) {
+ $sgidname = htmlspecialchars_decode($_GET['sgidname']);
+ }
+
+ if ($sgid == -1 && $sgidname == '----------_none_selected_----------' && $all == '----------_none_selected_----------') {
+ $json = [
+ 'usage' => [
+ 'all' => [
+ 'desc' => 'Get details about all TeamSpeak servergroups',
+ 'usage' => "Use \$_GET parameter 'all' without any value",
+ 'example' => '/api/?groups&all',
+ ],
+ 'limit' => [
+ 'desc' => 'Define a number that limits the number of results. Maximum value is 1000. Default is 100.',
+ 'usage' => "Use \$_GET parameter 'limit' and add as value a number above 1",
+ 'example' => '/api/?groups&limit=10',
+ ],
+ 'order' => [
+ 'desc' => "Define a sorting order. Value of 'sort' param is necessary.",
+ 'usage' => "Use \$_GET parameter 'order' and add as value 'asc' for ascending or 'desc' for descending",
+ 'example' => '/api/?groups&all&sort=sgid&order=asc',
+ ],
+ 'sgid' => [
+ 'desc' => 'Get details about TeamSpeak servergroups by the servergroup TS-database-ID',
+ 'usage' => "Use \$_GET parameter 'sgid' and add as value the servergroup TS-database-ID",
+ 'example' => '/api/?groups&sgid=123',
+ ],
+ 'sgidname' => [
+ 'desc' => 'Get details about TeamSpeak servergroups by servergroup name or a part of it',
+ 'usage' => "Use \$_GET parameter 'sgidname' and add as value a name or a part of it",
+ 'example' => [
+ '1' => [
+ 'desc' => 'Filter by servergroup name',
+ 'url' => '/api/?groups&sgidname=Level01',
+ ],
+ '2' => [
+ 'desc' => 'Filter by servergroup name with a percent sign as placeholder',
+ 'url' => '/api/?groups&sgidname=Level%',
+ ],
+ ],
+ ],
+ 'sort' => [
+ 'desc' => 'Define a sorting. Available is each column name, which is given back as a result.',
+ 'usage' => "Use \$_GET parameter 'sort' and add as value a column name",
+ 'example' => [
+ '1' => [
+ 'desc' => 'Sort by servergroup name',
+ 'url' => '/api/?groups&all&sort=sgidname',
+ ],
+ '2' => [
+ 'desc' => 'Sort by TeamSpeak sort-ID',
+ 'url' => '/api/?groups&all&sort=sortid',
+ ],
+ ],
+ ],
+ ],
+ ];
+ } else {
+ if ($all == 1) {
+ $dbdata = $mysqlcon->prepare("SELECT * FROM `$dbname`.`groups` ORDER BY {$sort} {$order} LIMIT :start, :limit");
+ } else {
+ $dbdata = $mysqlcon->prepare("SELECT * FROM `$dbname`.`groups` WHERE (`sgidname` LIKE :sgidname OR `sgid` LIKE :sgid) ORDER BY {$sort} {$order} LIMIT :start, :limit");
+ $dbdata->bindValue(':sgidname', '%'.$sgidname.'%', PDO::PARAM_STR);
+ $dbdata->bindValue(':sgid', (int) $sgid, PDO::PARAM_INT);
+ }
+ $dbdata->bindValue(':start', (int) $part, PDO::PARAM_INT);
+ $dbdata->bindValue(':limit', (int) $limit, PDO::PARAM_INT);
+ $dbdata->execute();
+ $json = $dbdata->fetchAll(PDO::FETCH_ASSOC | PDO::FETCH_UNIQUE);
+ foreach ($json as $sgid => $sqlpart) {
+ if ($sqlpart['icondate'] != 0 && $sqlpart['sgidname'] == 'ServerIcon') {
+ $json[$sgid]['iconpath'] = './tsicons/servericon.'.$sqlpart['ext'];
+ } elseif ($sqlpart['icondate'] == 0 && $sqlpart['iconid'] > 0 && $sqlpart['iconid'] < 601) {
+ $json[$sgid]['iconpath'] = './tsicons/'.$sqlpart['iconid'].'.'.$sqlpart['ext'];
+ } elseif ($sqlpart['icondate'] != 0) {
+ $json[$sgid]['iconpath'] = './tsicons/'.$sgid.'.'.$sqlpart['ext'];
+ } else {
+ $json[$sgid]['iconpath'] = '';
+ }
+ }
+ }
+} elseif (isset($_GET['rankconfig'])) {
+ $dbdata = $mysqlcon->prepare("SELECT * FROM `$dbname`.`cfg_params` WHERE `param` in ('rankup_definition', 'rankup_time_assess_mode')");
+ $dbdata->execute();
+ $sql = $dbdata->fetchAll(PDO::FETCH_KEY_PAIR);
+ $json = [];
+ if ($sql['rankup_time_assess_mode'] == 1) {
+ $modedesc = 'active time';
+ } else {
+ $modedesc = 'online time';
+ }
+ $json['rankup_time_assess_mode'] = [
+ 'mode' => $sql['rankup_time_assess_mode'],
+ 'mode_desc' => $modedesc,
+ ];
+ $count = 0;
+ foreach (explode(',', $sql['rankup_definition']) as $entry) {
+ list($key, $value) = explode('=>', $entry);
+ $addnewvalue1[$count] = [
+ 'grpid' => $value,
+ 'seconds' => $key,
+ ];
+ $count++;
+ $json['rankup_definition'] = $addnewvalue1;
+ }
+} elseif (isset($_GET['server'])) {
+ $dbdata = $mysqlcon->prepare("SELECT 0 as `row`, `$dbname`.`stats_server`.* FROM `$dbname`.`stats_server`");
+ $dbdata->execute();
+ $json = $dbdata->fetchAll(PDO::FETCH_ASSOC | PDO::FETCH_UNIQUE);
+} elseif (isset($_GET['user'])) {
+ $filter = ' WHERE';
+ if (isset($_GET['cldbid'])) {
+ $cldbid = htmlspecialchars_decode($_GET['cldbid']);
+ if ($filter != ' WHERE') {
+ $filter .= ' AND';
+ }
+ $filter .= ' `cldbid` LIKE :cldbid';
+ }
+ if (isset($_GET['groupid'])) {
+ $groupid = htmlspecialchars_decode($_GET['groupid']);
+ $explode_groupid = explode(',', $groupid);
+ if ($filter != ' WHERE') {
+ $filter .= ' AND';
+ }
+ $filter .= ' (';
+ $cnt = 0;
+ foreach ($explode_groupid as $groupid) {
+ if ($cnt > 0) {
+ $filter .= ' OR ';
+ }
+ $filter .= '`cldgroup` = :groupid'.$cnt;
+ $cnt++;
+ $filter .= ' OR `cldgroup` LIKE (:groupid'.$cnt.')';
+ $cnt++;
+ $filter .= ' OR `cldgroup` LIKE (:groupid'.$cnt.')';
+ $cnt++;
+ $filter .= ' OR `cldgroup` LIKE (:groupid'.$cnt.')';
+ $cnt++;
+ }
+ $filter .= ')';
+ }
+ if (isset($_GET['name'])) {
+ $name = htmlspecialchars_decode($_GET['name']);
+ if ($filter != ' WHERE') {
+ $filter .= ' AND';
+ }
+ $filter .= ' `name` LIKE :name';
+ }
+ if (! isset($_GET['sort'])) {
+ $sort = '`rank`';
+ }
+ if (isset($_GET['status']) && $_GET['status'] == strtolower('online')) {
+ if ($filter != ' WHERE') {
+ $filter .= ' AND';
+ }
+ $filter .= ' `online`=1';
+ } elseif (isset($_GET['status']) && $_GET['status'] == strtolower('offline')) {
+ if ($filter != ' WHERE') {
+ $filter .= ' AND';
+ }
+ $filter .= ' `online`=0';
+ }
+ if (isset($_GET['uuid'])) {
+ $uuid = htmlspecialchars_decode($_GET['uuid']);
+ if ($filter != ' WHERE') {
+ $filter .= ' AND';
+ }
+ $filter .= ' `uuid` LIKE :uuid';
+ }
+ if ($filter == ' WHERE') {
+ $filter = '';
+ }
+
+ if ($filter == '' && ! isset($_GET['all']) && ! isset($_GET['cldbid']) && ! isset($_GET['name']) && ! isset($_GET['uuid'])) {
+ $json = [
+ 'usage' => [
+ 'all' => [
+ 'desc' => 'Get details about all TeamSpeak user. Result is limited by 100 entries.',
+ 'usage' => "Use \$_GET parameter 'all' without any value",
+ 'example' => '/api/?user&all',
+ ],
+ 'cldbid' => [
+ 'desc' => 'Get details about TeamSpeak user by client TS-database ID',
+ 'usage' => "Use \$_GET parameter 'cldbid' and add as value a single client TS-database ID",
+ 'example' => '/api/?user&cldbid=7775',
+ ],
+ 'groupid' => [
+ 'desc' => 'Get only user, which are in the given servergroup database ID',
+ 'usage' => "Use \$_GET parameter 'groupid' and add as value a database ID of a servergroup. Multiple servergroups can be specified comma-separated.",
+ 'example' => [
+ '1' => [
+ 'desc' => 'Filter by a single servergroup database ID',
+ 'url' => '/api/?userstats&groupid=6',
+ ],
+ '2' => [
+ 'desc' => 'Filter by multiple servergroup database IDs. Only one of the specified groups must apply to get the concerned user.',
+ 'url' => '/api/?userstats&groupid=6,9,48',
+ ],
+ ],
+ ],
+ 'limit' => [
+ 'desc' => 'Define a number that limits the number of results. Maximum value is 1000. Default is 100.',
+ 'usage' => "Use \$_GET parameter 'limit' and add as value a number above 1",
+ 'example' => '/api/?user&all&limit=10',
+ ],
+ 'name' => [
+ 'desc' => 'Get details about TeamSpeak user by client nickname',
+ 'usage' => "Use \$_GET parameter 'name' and add as value a name or a part of it",
+ 'example' => [
+ '1' => [
+ 'desc' => 'Filter by client nickname',
+ 'url' => '/api/?user&name=Newcomer1989',
+ ],
+ '2' => [
+ 'desc' => 'Filter by client nickname with a percent sign as placeholder',
+ 'url' => '/api/?user&name=%user%',
+ ],
+ ],
+ ],
+ 'order' => [
+ 'desc' => 'Define a sorting order.',
+ 'usage' => "Use \$_GET parameter 'order' and add as value 'asc' for ascending or 'desc' for descending",
+ 'example' => '/api/?user&all&order=asc',
+ ],
+ 'part' => [
+ 'desc' => 'Define, which part of the result you want to get. This is needed, when more then 100 clients are inside the result. At default you will get the first 100 clients. To get the next 100 clients, you will need to ask for part 2.',
+ 'usage' => "Use \$_GET parameter 'part' and add as value a number above 1",
+ 'example' => '/api/?user&name=TeamSpeakUser&part=2',
+ ],
+ 'sort' => [
+ 'desc' => 'Define a sorting. Available is each column name, which is given back as a result.',
+ 'usage' => "Use \$_GET parameter 'sort' and add as value a column name",
+ 'example' => [
+ '1' => [
+ 'desc' => 'Sort by online time',
+ 'url' => '/api/?user&all&sort=count',
+ ],
+ '2' => [
+ 'desc' => 'Sort by active time',
+ 'url' => '/api/?user&all&sort=(count-idle)',
+ ],
+ '3' => [
+ 'desc' => 'Sort by rank',
+ 'url' => '/api/?user&all&sort=rank',
+ ],
+ ],
+ ],
+ 'status' => [
+ 'desc' => 'List only clients, which status is online or offline.',
+ 'usage' => "Use \$_GET parameter 'status' and add as value 'online' or 'offline'",
+ 'example' => '/api/?userstats&status=online',
+ ],
+ 'uuid' => [
+ 'desc' => 'Get details about TeamSpeak user by unique client ID',
+ 'usage' => "Use \$_GET parameter 'uuid' and add as value one unique client ID or a part of it",
+ 'example' => '/api/?user&uuid=xrTKhT/HDl4ea0WoFDQH2zOpmKg=',
+ ],
+ ],
+ ];
+ } else {
+ $dbdata = $mysqlcon->prepare("SELECT * FROM `$dbname`.`user` {$filter} ORDER BY {$sort} {$order} LIMIT :start, :limit");
+ if (isset($_GET['cldbid'])) {
+ $dbdata->bindValue(':cldbid', (int) $cldbid, PDO::PARAM_INT);
+ }
+ if (isset($_GET['groupid'])) {
+ $groupid = htmlspecialchars_decode($_GET['groupid']);
+ $explode_groupid = explode(',', $groupid);
+ $cnt = 0;
+ foreach ($explode_groupid as $groupid) {
+ $dbdata->bindValue(':groupid'.$cnt, $groupid, PDO::PARAM_STR);
+ $cnt++;
+ $dbdata->bindValue(':groupid'.$cnt, $groupid.',%', PDO::PARAM_STR);
+ $cnt++;
+ $dbdata->bindValue(':groupid'.$cnt, '%,'.$groupid.',%', PDO::PARAM_STR);
+ $cnt++;
+ $dbdata->bindValue(':groupid'.$cnt, '%,'.$groupid, PDO::PARAM_STR);
+ $cnt++;
+ }
+ }
+ if (isset($_GET['name'])) {
+ $dbdata->bindValue(':name', '%'.$name.'%', PDO::PARAM_STR);
+ }
+ if (isset($_GET['uuid'])) {
+ $dbdata->bindValue(':uuid', '%'.$uuid.'%', PDO::PARAM_STR);
+ }
+
+ $dbdata->bindValue(':start', (int) $part, PDO::PARAM_INT);
+ $dbdata->bindValue(':limit', (int) $limit, PDO::PARAM_INT);
+ $dbdata->execute();
+ $json = $dbdata->fetchAll(PDO::FETCH_ASSOC | PDO::FETCH_UNIQUE);
+ }
+} elseif (isset($_GET['userstats'])) {
+ $filter = ' WHERE';
+ if (isset($_GET['cldbid'])) {
+ $cldbid = htmlspecialchars_decode($_GET['cldbid']);
+ if ($filter != ' WHERE') {
+ $filter .= ' AND';
+ }
+ $filter .= ' `cldbid` LIKE :cldbid';
+ }
+ if (isset($_GET['groupid'])) {
+ $groupid = htmlspecialchars_decode($_GET['groupid']);
+ $explode_groupid = explode(',', $groupid);
+ if ($filter != ' WHERE') {
+ $filter .= ' AND';
+ }
+ $filter .= ' (';
+ $cnt = 0;
+ foreach ($explode_groupid as $groupid) {
+ if ($cnt > 0) {
+ $filter .= ' OR ';
+ }
+ $filter .= '`user`.`cldgroup` = :groupid'.$cnt;
+ $cnt++;
+ $filter .= ' OR `user`.`cldgroup` LIKE (:groupid'.$cnt.')';
+ $cnt++;
+ $filter .= ' OR `user`.`cldgroup` LIKE (:groupid'.$cnt.')';
+ $cnt++;
+ $filter .= ' OR `user`.`cldgroup` LIKE (:groupid'.$cnt.')';
+ $cnt++;
+ }
+ $filter .= ')';
+ }
+ if (isset($_GET['name'])) {
+ $name = htmlspecialchars_decode($_GET['name']);
+ if ($filter != ' WHERE') {
+ $filter .= ' AND';
+ }
+ $filter .= ' `user`.`name` LIKE :name';
+ }
+ if (! isset($_GET['sort'])) {
+ $sort = '`count_week`';
+ }
+ if (isset($_GET['status']) && $_GET['status'] == strtolower('online')) {
+ if ($filter != ' WHERE') {
+ $filter .= ' AND';
+ }
+ $filter .= ' `user`.`online`=1';
+ } elseif (isset($_GET['status']) && $_GET['status'] == strtolower('offline')) {
+ if ($filter != ' WHERE') {
+ $filter .= ' AND';
+ }
+ $filter .= ' `user`.`online`=0';
+ }
+ if (isset($_GET['uuid'])) {
+ $uuid = htmlspecialchars_decode($_GET['uuid']);
+ if ($filter != ' WHERE') {
+ $filter .= ' AND';
+ }
+ $filter .= ' `user`.`uuid` LIKE :uuid';
+ }
+ if ($filter == ' WHERE') {
+ $filter = '';
+ }
+
+ if ($filter == '' && ! isset($_GET['all']) && ! isset($_GET['cldbid']) && ! isset($_GET['name']) && ! isset($_GET['uuid'])) {
+ $json = [
+ 'usage' => [
+ 'all' => [
+ 'desc' => 'Get additional statistics about all TeamSpeak user. Result is limited by 100 entries.',
+ 'usage' => "Use \$_GET parameter 'all' without any value",
+ 'example' => '/api/?userstats&all',
+ ],
+ 'cldbid' => [
+ 'desc' => 'Get details about TeamSpeak user by client TS-database ID',
+ 'usage' => "Use \$_GET parameter 'cldbid' and add as value a single client TS-database ID",
+ 'example' => '/api/?userstats&cldbid=7775',
+ ],
+ 'groupid' => [
+ 'desc' => 'Get only user, which are in the given servergroup database ID',
+ 'usage' => "Use \$_GET parameter 'groupid' and add as value a database ID of a servergroup. Multiple servergroups can be specified comma-separated.",
+ 'example' => [
+ '1' => [
+ 'desc' => 'Filter by a single servergroup database ID',
+ 'url' => '/api/?userstats&groupid=6',
+ ],
+ '2' => [
+ 'desc' => 'Filter by multiple servergroup database IDs. Only one of the specified groups must apply to get the concerned user.',
+ 'url' => '/api/?userstats&groupid=6,9,48',
+ ],
+ ],
+ ],
+ 'limit' => [
+ 'desc' => 'Define a number that limits the number of results. Maximum value is 1000. Default is 100.',
+ 'usage' => "Use \$_GET parameter 'limit' and add as value a number above 1",
+ 'example' => '/api/?userstats&limit=10',
+ ],
+ 'name' => [
+ 'desc' => 'Get details about TeamSpeak user by client nickname',
+ 'usage' => "Use \$_GET parameter 'name' and add as value a name or a part of it",
+ 'example' => [
+ '1' => [
+ 'desc' => 'Filter by client nickname',
+ 'url' => '/api/?userstats&name=Newcomer1989',
+ ],
+ '2' => [
+ 'desc' => 'Filter by client nickname with a percent sign as placeholder',
+ 'url' => '/api/?userstats&name=%user%',
+ ],
+ ],
+ ],
+ 'order' => [
+ 'desc' => 'Define a sorting order.',
+ 'usage' => "Use \$_GET parameter 'order' and add as value 'asc' for ascending or 'desc' for descending",
+ 'example' => '/api/?userstats&all&order=asc',
+ ],
+ 'part' => [
+ 'desc' => 'Define, which part of the result you want to get. This is needed, when more then 100 clients are inside the result. At default you will get the first 100 clients. To get the next 100 clients, you will need to ask for part 2.',
+ 'usage' => "Use \$_GET parameter 'part' and add as value a number above 1",
+ 'example' => '/api/?userstats&all&part=2',
+ ],
+ 'sort' => [
+ 'desc' => 'Define a sorting. Available is each column name, which is given back as a result.',
+ 'usage' => "Use \$_GET parameter 'sort' and add as value a column name",
+ 'example' => [
+ '1' => [
+ 'desc' => 'Sort by online time of the week',
+ 'url' => '/api/?userstats&all&sort=count_week',
+ ],
+ '2' => [
+ 'desc' => 'Sort by active time of the week',
+ 'url' => '/api/?userstats&all&sort=(count_week-idle_week)',
+ ],
+ '3' => [
+ 'desc' => 'Sort by online time of the month',
+ 'url' => '/api/?userstats&all&sort=count_month',
+ ],
+ ],
+ ],
+ 'status' => [
+ 'desc' => 'List only clients, which status is online or offline.',
+ 'usage' => "Use \$_GET parameter 'status' and add as value 'online' or 'offline'",
+ 'example' => '/api/?userstats&status=online',
+ ],
+ 'uuid' => [
+ 'desc' => 'Get additional statistics about TeamSpeak user by unique client ID',
+ 'usage' => "Use \$_GET parameter 'uuid' and add as value one unique client ID or a part of it",
+ 'example' => '/api/?userstats&uuid=xrTKhT/HDl4ea0WoFDQH2zOpmKg=',
+ ],
+ ],
+ ];
+ } else {
+ $dbdata = $mysqlcon->prepare("SELECT * FROM `$dbname`.`stats_user` INNER JOIN `$dbname`.`user` ON `user`.`uuid` = `stats_user`.`uuid` {$filter} ORDER BY {$sort} {$order} LIMIT :start, :limit");
+ if (isset($_GET['cldbid'])) {
+ $dbdata->bindValue(':cldbid', (int) $cldbid, PDO::PARAM_INT);
+ }
+ if (isset($_GET['groupid'])) {
+ $groupid = htmlspecialchars_decode($_GET['groupid']);
+ $explode_groupid = explode(',', $groupid);
+ $cnt = 0;
+ foreach ($explode_groupid as $groupid) {
+ $dbdata->bindValue(':groupid'.$cnt, $groupid, PDO::PARAM_STR);
+ $cnt++;
+ $dbdata->bindValue(':groupid'.$cnt, $groupid.',%', PDO::PARAM_STR);
+ $cnt++;
+ $dbdata->bindValue(':groupid'.$cnt, '%,'.$groupid.',%', PDO::PARAM_STR);
+ $cnt++;
+ $dbdata->bindValue(':groupid'.$cnt, '%,'.$groupid, PDO::PARAM_STR);
+ $cnt++;
+ }
+ }
+ if (isset($_GET['name'])) {
+ $dbdata->bindValue(':name', '%'.$name.'%', PDO::PARAM_STR);
+ }
+ if (isset($_GET['uuid'])) {
+ $dbdata->bindValue(':uuid', '%'.$uuid.'%', PDO::PARAM_STR);
+ }
+
+ $dbdata->bindValue(':start', (int) $part, PDO::PARAM_INT);
+ $dbdata->bindValue(':limit', (int) $limit, PDO::PARAM_INT);
+ $dbdata->execute();
+ $json = $dbdata->fetchAll(PDO::FETCH_ASSOC | PDO::FETCH_UNIQUE);
+ }
+} else {
+ $json = [
+ 'usage' => [
+ 'bot' => [
+ 'desc' => 'Use this to trigger Bot commands as starting or stopping the Ranksystem Bot.',
+ 'usage' => "Use \$_GET parameter 'bot'",
+ 'example' => '/api/?bot',
+ ],
+ 'groups' => [
+ 'desc' => 'Get details about the TeamSpeak servergroups',
+ 'usage' => "Use \$_GET parameter 'groups'",
+ 'example' => '/api/?groups',
+ ],
+ 'rankconfig' => [
+ 'desc' => 'Get the rankup definition, which contains the assignment of (needed) time to servergroup',
+ 'usage' => "Use \$_GET parameter 'rankconfig'",
+ 'example' => '/api/?rankconfig',
+ ],
+ 'server' => [
+ 'desc' => 'Get details about the TeamSpeak server',
+ 'usage' => "Use \$_GET parameter 'server'",
+ 'example' => '/api/?server',
+ ],
+ 'user' => [
+ 'desc' => 'Get details about the TeamSpeak user',
+ 'usage' => "Use \$_GET parameter 'user'",
+ 'example' => '/api/?user',
+ ],
+ 'userstats' => [
+ 'desc' => 'Get additional statistics about the TeamSpeak user',
+ 'usage' => "Use \$_GET parameter 'userstats'",
+ 'example' => '/api/?userstats',
+ ],
+ ],
+ ];
+}
+
+echo json_encode($json);
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..ffecd44
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,10 @@
+{
+ "require-dev": {
+ "friendsofphp/php-cs-fixer": "^3.21"
+ },
+ "scripts": {
+ "code-style": [
+ "\"vendor/bin/php-cs-fixer\" fix --config .php-cs-fixer.php --diff"
+ ]
+ }
+}
diff --git a/composer.lock b/composer.lock
new file mode 100644
index 0000000..8adc487
--- /dev/null
+++ b/composer.lock
@@ -0,0 +1,2045 @@
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
+ "This file is @generated automatically"
+ ],
+ "content-hash": "9c0a435b6b08561c362b45df3d7d7cb1",
+ "packages": [],
+ "packages-dev": [
+ {
+ "name": "composer/pcre",
+ "version": "3.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/composer/pcre.git",
+ "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/composer/pcre/zipball/4bff79ddd77851fe3cdd11616ed3f92841ba5bd2",
+ "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.4 || ^8.0"
+ },
+ "require-dev": {
+ "phpstan/phpstan": "^1.3",
+ "phpstan/phpstan-strict-rules": "^1.1",
+ "symfony/phpunit-bridge": "^5"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Composer\\Pcre\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jordi Boggiano",
+ "email": "j.boggiano@seld.be",
+ "homepage": "http://seld.be"
+ }
+ ],
+ "description": "PCRE wrapping library that offers type-safe preg_* replacements.",
+ "keywords": [
+ "PCRE",
+ "preg",
+ "regex",
+ "regular expression"
+ ],
+ "support": {
+ "issues": "https://github.com/composer/pcre/issues",
+ "source": "https://github.com/composer/pcre/tree/3.1.0"
+ },
+ "funding": [
+ {
+ "url": "https://packagist.com",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/composer",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-11-17T09:50:14+00:00"
+ },
+ {
+ "name": "composer/semver",
+ "version": "3.3.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/composer/semver.git",
+ "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/composer/semver/zipball/3953f23262f2bff1919fc82183ad9acb13ff62c9",
+ "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.3.2 || ^7.0 || ^8.0"
+ },
+ "require-dev": {
+ "phpstan/phpstan": "^1.4",
+ "symfony/phpunit-bridge": "^4.2 || ^5"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Composer\\Semver\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nils Adermann",
+ "email": "naderman@naderman.de",
+ "homepage": "http://www.naderman.de"
+ },
+ {
+ "name": "Jordi Boggiano",
+ "email": "j.boggiano@seld.be",
+ "homepage": "http://seld.be"
+ },
+ {
+ "name": "Rob Bast",
+ "email": "rob.bast@gmail.com",
+ "homepage": "http://robbast.nl"
+ }
+ ],
+ "description": "Semver library that offers utilities, version constraint parsing and validation.",
+ "keywords": [
+ "semantic",
+ "semver",
+ "validation",
+ "versioning"
+ ],
+ "support": {
+ "irc": "irc://irc.freenode.org/composer",
+ "issues": "https://github.com/composer/semver/issues",
+ "source": "https://github.com/composer/semver/tree/3.3.2"
+ },
+ "funding": [
+ {
+ "url": "https://packagist.com",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/composer",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-04-01T19:23:25+00:00"
+ },
+ {
+ "name": "composer/xdebug-handler",
+ "version": "3.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/composer/xdebug-handler.git",
+ "reference": "ced299686f41dce890debac69273b47ffe98a40c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c",
+ "reference": "ced299686f41dce890debac69273b47ffe98a40c",
+ "shasum": ""
+ },
+ "require": {
+ "composer/pcre": "^1 || ^2 || ^3",
+ "php": "^7.2.5 || ^8.0",
+ "psr/log": "^1 || ^2 || ^3"
+ },
+ "require-dev": {
+ "phpstan/phpstan": "^1.0",
+ "phpstan/phpstan-strict-rules": "^1.1",
+ "symfony/phpunit-bridge": "^6.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Composer\\XdebugHandler\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "John Stevenson",
+ "email": "john-stevenson@blueyonder.co.uk"
+ }
+ ],
+ "description": "Restarts a process without Xdebug.",
+ "keywords": [
+ "Xdebug",
+ "performance"
+ ],
+ "support": {
+ "irc": "irc://irc.freenode.org/composer",
+ "issues": "https://github.com/composer/xdebug-handler/issues",
+ "source": "https://github.com/composer/xdebug-handler/tree/3.0.3"
+ },
+ "funding": [
+ {
+ "url": "https://packagist.com",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/composer",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-02-25T21:32:43+00:00"
+ },
+ {
+ "name": "doctrine/annotations",
+ "version": "2.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/annotations.git",
+ "reference": "e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/annotations/zipball/e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f",
+ "reference": "e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/lexer": "^2 || ^3",
+ "ext-tokenizer": "*",
+ "php": "^7.2 || ^8.0",
+ "psr/cache": "^1 || ^2 || ^3"
+ },
+ "require-dev": {
+ "doctrine/cache": "^2.0",
+ "doctrine/coding-standard": "^10",
+ "phpstan/phpstan": "^1.8.0",
+ "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
+ "symfony/cache": "^5.4 || ^6",
+ "vimeo/psalm": "^4.10"
+ },
+ "suggest": {
+ "php": "PHP 8.0 or higher comes with attributes, a native replacement for annotations"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Guilherme Blanco",
+ "email": "guilhermeblanco@gmail.com"
+ },
+ {
+ "name": "Roman Borschel",
+ "email": "roman@code-factory.org"
+ },
+ {
+ "name": "Benjamin Eberlei",
+ "email": "kontakt@beberlei.de"
+ },
+ {
+ "name": "Jonathan Wage",
+ "email": "jonwage@gmail.com"
+ },
+ {
+ "name": "Johannes Schmitt",
+ "email": "schmittjoh@gmail.com"
+ }
+ ],
+ "description": "Docblock Annotations Parser",
+ "homepage": "https://www.doctrine-project.org/projects/annotations.html",
+ "keywords": [
+ "annotations",
+ "docblock",
+ "parser"
+ ],
+ "support": {
+ "issues": "https://github.com/doctrine/annotations/issues",
+ "source": "https://github.com/doctrine/annotations/tree/2.0.1"
+ },
+ "time": "2023-02-02T22:02:53+00:00"
+ },
+ {
+ "name": "doctrine/lexer",
+ "version": "3.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/lexer.git",
+ "reference": "84a527db05647743d50373e0ec53a152f2cde568"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/lexer/zipball/84a527db05647743d50373e0ec53a152f2cde568",
+ "reference": "84a527db05647743d50373e0ec53a152f2cde568",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^8.1"
+ },
+ "require-dev": {
+ "doctrine/coding-standard": "^10",
+ "phpstan/phpstan": "^1.9",
+ "phpunit/phpunit": "^9.5",
+ "psalm/plugin-phpunit": "^0.18.3",
+ "vimeo/psalm": "^5.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Common\\Lexer\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Guilherme Blanco",
+ "email": "guilhermeblanco@gmail.com"
+ },
+ {
+ "name": "Roman Borschel",
+ "email": "roman@code-factory.org"
+ },
+ {
+ "name": "Johannes Schmitt",
+ "email": "schmittjoh@gmail.com"
+ }
+ ],
+ "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.",
+ "homepage": "https://www.doctrine-project.org/projects/lexer.html",
+ "keywords": [
+ "annotations",
+ "docblock",
+ "lexer",
+ "parser",
+ "php"
+ ],
+ "support": {
+ "issues": "https://github.com/doctrine/lexer/issues",
+ "source": "https://github.com/doctrine/lexer/tree/3.0.0"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-12-15T16:57:16+00:00"
+ },
+ {
+ "name": "friendsofphp/php-cs-fixer",
+ "version": "v3.21.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
+ "reference": "229b55b3eae4729a8e2a321441ba40fcb3720b86"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/229b55b3eae4729a8e2a321441ba40fcb3720b86",
+ "reference": "229b55b3eae4729a8e2a321441ba40fcb3720b86",
+ "shasum": ""
+ },
+ "require": {
+ "composer/semver": "^3.3",
+ "composer/xdebug-handler": "^3.0.3",
+ "doctrine/annotations": "^2",
+ "doctrine/lexer": "^2 || ^3",
+ "ext-json": "*",
+ "ext-tokenizer": "*",
+ "php": "^8.0.1",
+ "sebastian/diff": "^4.0 || ^5.0",
+ "symfony/console": "^5.4 || ^6.0",
+ "symfony/event-dispatcher": "^5.4 || ^6.0",
+ "symfony/filesystem": "^5.4 || ^6.0",
+ "symfony/finder": "^5.4 || ^6.0",
+ "symfony/options-resolver": "^5.4 || ^6.0",
+ "symfony/polyfill-mbstring": "^1.27",
+ "symfony/polyfill-php80": "^1.27",
+ "symfony/polyfill-php81": "^1.27",
+ "symfony/process": "^5.4 || ^6.0",
+ "symfony/stopwatch": "^5.4 || ^6.0"
+ },
+ "require-dev": {
+ "justinrainbow/json-schema": "^5.2",
+ "keradus/cli-executor": "^2.0",
+ "mikey179/vfsstream": "^1.6.11",
+ "php-coveralls/php-coveralls": "^2.5.3",
+ "php-cs-fixer/accessible-object": "^1.1",
+ "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2",
+ "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2.1",
+ "phpspec/prophecy": "^1.16",
+ "phpspec/prophecy-phpunit": "^2.0",
+ "phpunit/phpunit": "^9.5",
+ "phpunitgoodpractices/polyfill": "^1.6",
+ "phpunitgoodpractices/traits": "^1.9.2",
+ "symfony/phpunit-bridge": "^6.2.3",
+ "symfony/yaml": "^5.4 || ^6.0"
+ },
+ "suggest": {
+ "ext-dom": "For handling output formats in XML",
+ "ext-mbstring": "For handling non-UTF8 characters."
+ },
+ "bin": [
+ "php-cs-fixer"
+ ],
+ "type": "application",
+ "autoload": {
+ "psr-4": {
+ "PhpCsFixer\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Dariusz Rumiński",
+ "email": "dariusz.ruminski@gmail.com"
+ }
+ ],
+ "description": "A tool to automatically fix PHP code style",
+ "keywords": [
+ "Static code analysis",
+ "fixer",
+ "standards",
+ "static analysis"
+ ],
+ "support": {
+ "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
+ "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.21.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/keradus",
+ "type": "github"
+ }
+ ],
+ "time": "2023-07-05T21:50:25+00:00"
+ },
+ {
+ "name": "psr/cache",
+ "version": "3.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/cache.git",
+ "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf",
+ "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.0.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Cache\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "https://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for caching libraries",
+ "keywords": [
+ "cache",
+ "psr",
+ "psr-6"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/cache/tree/3.0.0"
+ },
+ "time": "2021-02-03T23:26:27+00:00"
+ },
+ {
+ "name": "psr/container",
+ "version": "2.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/container.git",
+ "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963",
+ "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.4.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Container\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "https://www.php-fig.org/"
+ }
+ ],
+ "description": "Common Container Interface (PHP FIG PSR-11)",
+ "homepage": "https://github.com/php-fig/container",
+ "keywords": [
+ "PSR-11",
+ "container",
+ "container-interface",
+ "container-interop",
+ "psr"
+ ],
+ "support": {
+ "issues": "https://github.com/php-fig/container/issues",
+ "source": "https://github.com/php-fig/container/tree/2.0.2"
+ },
+ "time": "2021-11-05T16:47:00+00:00"
+ },
+ {
+ "name": "psr/event-dispatcher",
+ "version": "1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/event-dispatcher.git",
+ "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0",
+ "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\EventDispatcher\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Standard interfaces for event handling.",
+ "keywords": [
+ "events",
+ "psr",
+ "psr-14"
+ ],
+ "support": {
+ "issues": "https://github.com/php-fig/event-dispatcher/issues",
+ "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0"
+ },
+ "time": "2019-01-08T18:20:26+00:00"
+ },
+ {
+ "name": "psr/log",
+ "version": "3.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/log.git",
+ "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001",
+ "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.0.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Log\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "https://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for logging libraries",
+ "homepage": "https://github.com/php-fig/log",
+ "keywords": [
+ "log",
+ "psr",
+ "psr-3"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/log/tree/3.0.0"
+ },
+ "time": "2021-07-14T16:46:02+00:00"
+ },
+ {
+ "name": "sebastian/diff",
+ "version": "5.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/diff.git",
+ "reference": "912dc2fbe3e3c1e7873313cc801b100b6c68c87b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/912dc2fbe3e3c1e7873313cc801b100b6c68c87b",
+ "reference": "912dc2fbe3e3c1e7873313cc801b100b6c68c87b",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^10.0",
+ "symfony/process": "^4.2 || ^5"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "5.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Kore Nordmann",
+ "email": "mail@kore-nordmann.de"
+ }
+ ],
+ "description": "Diff implementation",
+ "homepage": "https://github.com/sebastianbergmann/diff",
+ "keywords": [
+ "diff",
+ "udiff",
+ "unidiff",
+ "unified diff"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/diff/issues",
+ "security": "https://github.com/sebastianbergmann/diff/security/policy",
+ "source": "https://github.com/sebastianbergmann/diff/tree/5.0.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-05-01T07:48:21+00:00"
+ },
+ {
+ "name": "symfony/console",
+ "version": "v6.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/console.git",
+ "reference": "8788808b07cf0bdd6e4b7fdd23d8ddb1470c83b7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/console/zipball/8788808b07cf0bdd6e4b7fdd23d8ddb1470c83b7",
+ "reference": "8788808b07cf0bdd6e4b7fdd23d8ddb1470c83b7",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/deprecation-contracts": "^2.5|^3",
+ "symfony/polyfill-mbstring": "~1.0",
+ "symfony/service-contracts": "^2.5|^3",
+ "symfony/string": "^5.4|^6.0"
+ },
+ "conflict": {
+ "symfony/dependency-injection": "<5.4",
+ "symfony/dotenv": "<5.4",
+ "symfony/event-dispatcher": "<5.4",
+ "symfony/lock": "<5.4",
+ "symfony/process": "<5.4"
+ },
+ "provide": {
+ "psr/log-implementation": "1.0|2.0|3.0"
+ },
+ "require-dev": {
+ "psr/log": "^1|^2|^3",
+ "symfony/config": "^5.4|^6.0",
+ "symfony/dependency-injection": "^5.4|^6.0",
+ "symfony/event-dispatcher": "^5.4|^6.0",
+ "symfony/lock": "^5.4|^6.0",
+ "symfony/process": "^5.4|^6.0",
+ "symfony/var-dumper": "^5.4|^6.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Console\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Eases the creation of beautiful and testable command line interfaces",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "cli",
+ "command-line",
+ "console",
+ "terminal"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/console/tree/v6.3.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-05-29T12:49:39+00:00"
+ },
+ {
+ "name": "symfony/deprecation-contracts",
+ "version": "v3.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/deprecation-contracts.git",
+ "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf",
+ "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.4-dev"
+ },
+ "thanks": {
+ "name": "symfony/contracts",
+ "url": "https://github.com/symfony/contracts"
+ }
+ },
+ "autoload": {
+ "files": [
+ "function.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "A generic function and convention to trigger deprecation notices",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/deprecation-contracts/tree/v3.3.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-05-23T14:45:45+00:00"
+ },
+ {
+ "name": "symfony/event-dispatcher",
+ "version": "v6.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/event-dispatcher.git",
+ "reference": "3af8ac1a3f98f6dbc55e10ae59c9e44bfc38dfaa"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/3af8ac1a3f98f6dbc55e10ae59c9e44bfc38dfaa",
+ "reference": "3af8ac1a3f98f6dbc55e10ae59c9e44bfc38dfaa",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/event-dispatcher-contracts": "^2.5|^3"
+ },
+ "conflict": {
+ "symfony/dependency-injection": "<5.4",
+ "symfony/service-contracts": "<2.5"
+ },
+ "provide": {
+ "psr/event-dispatcher-implementation": "1.0",
+ "symfony/event-dispatcher-implementation": "2.0|3.0"
+ },
+ "require-dev": {
+ "psr/log": "^1|^2|^3",
+ "symfony/config": "^5.4|^6.0",
+ "symfony/dependency-injection": "^5.4|^6.0",
+ "symfony/error-handler": "^5.4|^6.0",
+ "symfony/expression-language": "^5.4|^6.0",
+ "symfony/http-foundation": "^5.4|^6.0",
+ "symfony/service-contracts": "^2.5|^3",
+ "symfony/stopwatch": "^5.4|^6.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\EventDispatcher\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/event-dispatcher/tree/v6.3.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-04-21T14:41:17+00:00"
+ },
+ {
+ "name": "symfony/event-dispatcher-contracts",
+ "version": "v3.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/event-dispatcher-contracts.git",
+ "reference": "a76aed96a42d2b521153fb382d418e30d18b59df"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/a76aed96a42d2b521153fb382d418e30d18b59df",
+ "reference": "a76aed96a42d2b521153fb382d418e30d18b59df",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "psr/event-dispatcher": "^1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.4-dev"
+ },
+ "thanks": {
+ "name": "symfony/contracts",
+ "url": "https://github.com/symfony/contracts"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Contracts\\EventDispatcher\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Generic abstractions related to dispatching event",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "abstractions",
+ "contracts",
+ "decoupling",
+ "interfaces",
+ "interoperability",
+ "standards"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.3.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-05-23T14:45:45+00:00"
+ },
+ {
+ "name": "symfony/filesystem",
+ "version": "v6.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/filesystem.git",
+ "reference": "edd36776956f2a6fcf577edb5b05eb0e3bdc52ae"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/edd36776956f2a6fcf577edb5b05eb0e3bdc52ae",
+ "reference": "edd36776956f2a6fcf577edb5b05eb0e3bdc52ae",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/polyfill-ctype": "~1.8",
+ "symfony/polyfill-mbstring": "~1.8"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Filesystem\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Provides basic utilities for the filesystem",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/filesystem/tree/v6.3.1"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-06-01T08:30:39+00:00"
+ },
+ {
+ "name": "symfony/finder",
+ "version": "v6.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/finder.git",
+ "reference": "d9b01ba073c44cef617c7907ce2419f8d00d75e2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/finder/zipball/d9b01ba073c44cef617c7907ce2419f8d00d75e2",
+ "reference": "d9b01ba073c44cef617c7907ce2419f8d00d75e2",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "require-dev": {
+ "symfony/filesystem": "^6.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Finder\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Finds files and directories via an intuitive fluent interface",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/finder/tree/v6.3.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-04-02T01:25:41+00:00"
+ },
+ {
+ "name": "symfony/options-resolver",
+ "version": "v6.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/options-resolver.git",
+ "reference": "a10f19f5198d589d5c33333cffe98dc9820332dd"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/options-resolver/zipball/a10f19f5198d589d5c33333cffe98dc9820332dd",
+ "reference": "a10f19f5198d589d5c33333cffe98dc9820332dd",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/deprecation-contracts": "^2.5|^3"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\OptionsResolver\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Provides an improved replacement for the array_replace PHP function",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "config",
+ "configuration",
+ "options"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/options-resolver/tree/v6.3.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-05-12T14:21:09+00:00"
+ },
+ {
+ "name": "symfony/polyfill-ctype",
+ "version": "v1.27.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-ctype.git",
+ "reference": "5bbc823adecdae860bb64756d639ecfec17b050a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a",
+ "reference": "5bbc823adecdae860bb64756d639ecfec17b050a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "provide": {
+ "ext-ctype": "*"
+ },
+ "suggest": {
+ "ext-ctype": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.27-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Ctype\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Gert de Pagter",
+ "email": "BackEndTea@gmail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for ctype functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "ctype",
+ "polyfill",
+ "portable"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-11-03T14:55:06+00:00"
+ },
+ {
+ "name": "symfony/polyfill-intl-grapheme",
+ "version": "v1.27.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-intl-grapheme.git",
+ "reference": "511a08c03c1960e08a883f4cffcacd219b758354"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/511a08c03c1960e08a883f4cffcacd219b758354",
+ "reference": "511a08c03c1960e08a883f4cffcacd219b758354",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "suggest": {
+ "ext-intl": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.27-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Intl\\Grapheme\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for intl's grapheme_* functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "grapheme",
+ "intl",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.27.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-11-03T14:55:06+00:00"
+ },
+ {
+ "name": "symfony/polyfill-intl-normalizer",
+ "version": "v1.27.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-intl-normalizer.git",
+ "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/19bd1e4fcd5b91116f14d8533c57831ed00571b6",
+ "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "suggest": {
+ "ext-intl": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.27-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Intl\\Normalizer\\": ""
+ },
+ "classmap": [
+ "Resources/stubs"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for intl's Normalizer class and related functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "intl",
+ "normalizer",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.27.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-11-03T14:55:06+00:00"
+ },
+ {
+ "name": "symfony/polyfill-mbstring",
+ "version": "v1.27.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-mbstring.git",
+ "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534",
+ "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "provide": {
+ "ext-mbstring": "*"
+ },
+ "suggest": {
+ "ext-mbstring": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.27-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Mbstring\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for the Mbstring extension",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "mbstring",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-11-03T14:55:06+00:00"
+ },
+ {
+ "name": "symfony/polyfill-php80",
+ "version": "v1.27.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-php80.git",
+ "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936",
+ "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.27-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Php80\\": ""
+ },
+ "classmap": [
+ "Resources/stubs"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Ion Bazan",
+ "email": "ion.bazan@gmail.com"
+ },
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-11-03T14:55:06+00:00"
+ },
+ {
+ "name": "symfony/polyfill-php81",
+ "version": "v1.27.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-php81.git",
+ "reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/707403074c8ea6e2edaf8794b0157a0bfa52157a",
+ "reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.27-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Php81\\": ""
+ },
+ "classmap": [
+ "Resources/stubs"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-php81/tree/v1.27.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-11-03T14:55:06+00:00"
+ },
+ {
+ "name": "symfony/process",
+ "version": "v6.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/process.git",
+ "reference": "8741e3ed7fe2e91ec099e02446fb86667a0f1628"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/process/zipball/8741e3ed7fe2e91ec099e02446fb86667a0f1628",
+ "reference": "8741e3ed7fe2e91ec099e02446fb86667a0f1628",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Process\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Executes commands in sub-processes",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/process/tree/v6.3.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-05-19T08:06:44+00:00"
+ },
+ {
+ "name": "symfony/service-contracts",
+ "version": "v3.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/service-contracts.git",
+ "reference": "40da9cc13ec349d9e4966ce18b5fbcd724ab10a4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/service-contracts/zipball/40da9cc13ec349d9e4966ce18b5fbcd724ab10a4",
+ "reference": "40da9cc13ec349d9e4966ce18b5fbcd724ab10a4",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "psr/container": "^2.0"
+ },
+ "conflict": {
+ "ext-psr": "<1.1|>=2"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.4-dev"
+ },
+ "thanks": {
+ "name": "symfony/contracts",
+ "url": "https://github.com/symfony/contracts"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Contracts\\Service\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Test/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Generic abstractions related to writing services",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "abstractions",
+ "contracts",
+ "decoupling",
+ "interfaces",
+ "interoperability",
+ "standards"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/service-contracts/tree/v3.3.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-05-23T14:45:45+00:00"
+ },
+ {
+ "name": "symfony/stopwatch",
+ "version": "v6.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/stopwatch.git",
+ "reference": "fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/stopwatch/zipball/fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2",
+ "reference": "fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/service-contracts": "^2.5|^3"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Stopwatch\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Provides a way to profile code",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/stopwatch/tree/v6.3.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-02-16T10:14:28+00:00"
+ },
+ {
+ "name": "symfony/string",
+ "version": "v6.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/string.git",
+ "reference": "f2e190ee75ff0f5eced645ec0be5c66fac81f51f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/string/zipball/f2e190ee75ff0f5eced645ec0be5c66fac81f51f",
+ "reference": "f2e190ee75ff0f5eced645ec0be5c66fac81f51f",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/polyfill-ctype": "~1.8",
+ "symfony/polyfill-intl-grapheme": "~1.0",
+ "symfony/polyfill-intl-normalizer": "~1.0",
+ "symfony/polyfill-mbstring": "~1.0"
+ },
+ "conflict": {
+ "symfony/translation-contracts": "<2.5"
+ },
+ "require-dev": {
+ "symfony/error-handler": "^5.4|^6.0",
+ "symfony/http-client": "^5.4|^6.0",
+ "symfony/intl": "^6.2",
+ "symfony/translation-contracts": "^2.5|^3.0",
+ "symfony/var-exporter": "^5.4|^6.0"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "Resources/functions.php"
+ ],
+ "psr-4": {
+ "Symfony\\Component\\String\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "grapheme",
+ "i18n",
+ "string",
+ "unicode",
+ "utf-8",
+ "utf8"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/string/tree/v6.3.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-03-21T21:06:29+00:00"
+ }
+ ],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": [],
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": [],
+ "platform-dev": [],
+ "plugin-api-version": "2.3.0"
+}
diff --git a/index.php b/index.php
index b125c42..b7a0bfc 100644
--- a/index.php
+++ b/index.php
@@ -1,8 +1,8 @@
-
\ No newline at end of file
+
+
@@ -21,81 +21,86 @@
- 1. ',$lang['instdb'],' ';
- } else {
- echo '1. ',$lang['instdb'],' ';
- }
- if (isset($_POST['install'])) {
- echo '2. ',$lang['isntwiusrcr'],' ';
- } else {
- echo '2. ',$lang['isntwiusrcr'],' ';
- }
- if (isset($_POST['confweb'])) {
- echo '3. ',$lang['isntwicfg2'],' ';
- } else {
- echo '3. ',$lang['isntwicfg2'],' ';
- }
- ?>
+ 1. ',$lang['instdb'],' ';
+} else {
+ echo '1. ',$lang['instdb'],' ';
+}
+if (isset($_POST['install'])) {
+ echo '2. ',$lang['isntwiusrcr'],' ';
+} else {
+ echo '2. ',$lang['isntwiusrcr'],' ';
+}
+if (isset($_POST['confweb'])) {
+ echo '3. ',$lang['isntwicfg2'],' ';
+} else {
+ echo '3. ',$lang['isntwicfg2'],' ';
+}
+?>
-';
-
- if(!is_writable('./other/dbconfig.php')) {
- $err_msg = $lang['isntwicfg'];
- $err_lvl = 2;
- } else {
- $count = 1;
- $stmt = $mysqlcon->query('SHOW DATABASES');
- while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
- if ($row['Database'] == $dbname) {
- $dbExists = true;
- break;
- }
- }
- if ($dbExists) {
- if(($mysqlcon->exec("DROP DATABASE `$dbname`")) === false) { }
- }
-
- if($mysqlcon->exec("CREATE DATABASE `$dbname`") === false) {
- $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode()." ".print_r($mysqlcon->errorInfo(), true).'
'; $err_lvl = 2;
- $count++;
- }
-
- if($mysqlcon->exec("CREATE TABLE `$dbname`.`user` (
+?>';
+
+ if (! is_writable('./other/dbconfig.php')) {
+ $err_msg = $lang['isntwicfg'];
+ $err_lvl = 2;
+ } else {
+ $count = 1;
+ $stmt = $mysqlcon->query('SHOW DATABASES');
+ while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+ if ($row['Database'] == $dbname) {
+ $dbExists = true;
+ break;
+ }
+ }
+ if ($dbExists) {
+ if (($mysqlcon->exec("DROP DATABASE `$dbname`")) === false) {
+ }
+ }
+
+ if ($mysqlcon->exec("CREATE DATABASE `$dbname`") === false) {
+ $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode().' '.print_r($mysqlcon->errorInfo(), true).'
';
+ $err_lvl = 2;
+ $count++;
+ }
+
+ if ($mysqlcon->exec("CREATE TABLE `$dbname`.`user` (
`uuid` char(28) CHARACTER SET utf8 COLLATE utf8_unicode_ci PRIMARY KEY,
`cldbid` int(10) NOT NULL default '0',
`count` DECIMAL(14,3) NOT NULL default '0',
@@ -115,25 +120,29 @@ function install($type, $host, $user, $pass, $dbname, $lang, $mysqlcon, &$err_ms
`except` tinyint(1) NOT NULL default '0',
`grpsince` int(10) UNSIGNED NOT NULL default '0',
`cid` int(10) NOT NULL default '0'
- );") === false) {
- $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode()." ".print_r($mysqlcon->errorInfo(), true).'
'; $err_lvl = 2;
- $count++;
- } else {
- if($mysqlcon->exec("CREATE INDEX `user_version` ON `$dbname`.`user` (`version`)") === false) {
- $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode()." ".print_r($mysqlcon->errorInfo(), true).'
'; $err_lvl = 2;
- $count++;
- }
- if($mysqlcon->exec("CREATE INDEX `user_cldbid` ON `$dbname`.`user` (`cldbid` ASC,`uuid`,`rank`)") === false) {
- $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode()." ".print_r($mysqlcon->errorInfo(), true).'
'; $err_lvl = 2;
- $count++;
- }
- if($mysqlcon->exec("CREATE INDEX `user_online` ON `$dbname`.`user` (`online`,`lastseen`)") === false) {
- $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode()." ".print_r($mysqlcon->errorInfo(), true).'
'; $err_lvl = 2;
- $count++;
- }
- }
-
- if($mysqlcon->exec("CREATE TABLE `$dbname`.`groups` (
+ );") === false) {
+ $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode().' '.print_r($mysqlcon->errorInfo(), true).'
';
+ $err_lvl = 2;
+ $count++;
+ } else {
+ if ($mysqlcon->exec("CREATE INDEX `user_version` ON `$dbname`.`user` (`version`)") === false) {
+ $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode().' '.print_r($mysqlcon->errorInfo(), true).'
';
+ $err_lvl = 2;
+ $count++;
+ }
+ if ($mysqlcon->exec("CREATE INDEX `user_cldbid` ON `$dbname`.`user` (`cldbid` ASC,`uuid`,`rank`)") === false) {
+ $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode().' '.print_r($mysqlcon->errorInfo(), true).'
';
+ $err_lvl = 2;
+ $count++;
+ }
+ if ($mysqlcon->exec("CREATE INDEX `user_online` ON `$dbname`.`user` (`online`,`lastseen`)") === false) {
+ $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode().' '.print_r($mysqlcon->errorInfo(), true).'
';
+ $err_lvl = 2;
+ $count++;
+ }
+ }
+
+ if ($mysqlcon->exec("CREATE TABLE `$dbname`.`groups` (
`sgid` int(10) UNSIGNED NOT NULL default '0' PRIMARY KEY,
`sgidname` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
`iconid` bigint(10) NOT NULL default '0',
@@ -141,54 +150,61 @@ function install($type, $host, $user, $pass, $dbname, $lang, $mysqlcon, &$err_ms
`sortid` int(10) NOT NULL default '0',
`type` tinyint(1) NOT NULL default '0',
`ext` char(3) CHARACTER SET utf8 COLLATE utf8_unicode_ci
- );") === false) {
- $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode()." ".print_r($mysqlcon->errorInfo(), true).'
'; $err_lvl = 2;
- $count++;
- }
-
- if($mysqlcon->exec("CREATE TABLE `$dbname`.`cfg_params` (
+ );") === false) {
+ $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode().' '.print_r($mysqlcon->errorInfo(), true).'
';
+ $err_lvl = 2;
+ $count++;
+ }
+
+ if ($mysqlcon->exec("CREATE TABLE `$dbname`.`cfg_params` (
`param` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci PRIMARY KEY,
`value` varchar(21588) CHARACTER SET utf8 COLLATE utf8_unicode_ci
- );") === false) {
- $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode()." ".print_r($mysqlcon->errorInfo(), true).'
'; $err_lvl = 2;
- $count++;
- }
-
- if($mysqlcon->exec("CREATE TABLE `$dbname`.`server_usage` (
+ );") === false) {
+ $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode().' '.print_r($mysqlcon->errorInfo(), true).'
';
+ $err_lvl = 2;
+ $count++;
+ }
+
+ if ($mysqlcon->exec("CREATE TABLE `$dbname`.`server_usage` (
`timestamp` int(10) UNSIGNED NOT NULL default '0',
`clients` smallint(5) UNSIGNED NOT NULL default '0',
`channel` smallint(5) UNSIGNED NOT NULL default '0'
- );") === false) {
- $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode()." ".print_r($mysqlcon->errorInfo(), true).'
'; $err_lvl = 2;
- $count++;
- } else {
- if($mysqlcon->exec("CREATE INDEX `serverusage_timestamp` ON `$dbname`.`server_usage` (`timestamp`)") === false) {
- $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode()." ".print_r($mysqlcon->errorInfo(), true).'
'; $err_lvl = 2;
- $count++;
- }
- }
-
- if($mysqlcon->exec("CREATE TABLE `$dbname`.`user_snapshot` (
+ );") === false) {
+ $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode().' '.print_r($mysqlcon->errorInfo(), true).'
';
+ $err_lvl = 2;
+ $count++;
+ } else {
+ if ($mysqlcon->exec("CREATE INDEX `serverusage_timestamp` ON `$dbname`.`server_usage` (`timestamp`)") === false) {
+ $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode().' '.print_r($mysqlcon->errorInfo(), true).'
';
+ $err_lvl = 2;
+ $count++;
+ }
+ }
+
+ if ($mysqlcon->exec("CREATE TABLE `$dbname`.`user_snapshot` (
`id` tinyint(3) UNSIGNED NOT NULL default '0',
`cldbid` int(10) UNSIGNED NOT NULL default '0',
`count` int(10) UNSIGNED NOT NULL default '0',
`idle` int(10) UNSIGNED NOT NULL default '0',
PRIMARY KEY (`id`,`cldbid`)
- );") === false) {
- $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode()." ".print_r($mysqlcon->errorInfo(), true).'
'; $err_lvl = 2;
- $count++;
- } else {
- if($mysqlcon->exec("CREATE INDEX `snapshot_id` ON `$dbname`.`user_snapshot` (`id`)") === false) {
- $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode()." ".print_r($mysqlcon->errorInfo(), true).'
'; $err_lvl = 2;
- $count++;
- }
- if($mysqlcon->exec("CREATE INDEX `snapshot_cldbid` ON `$dbname`.`user_snapshot` (`cldbid`)") === false) {
- $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode()." ".print_r($mysqlcon->errorInfo(), true).'
'; $err_lvl = 2;
- $count++;
- }
- }
-
- if($mysqlcon->exec("CREATE TABLE `$dbname`.`stats_server` (
+ );") === false) {
+ $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode().' '.print_r($mysqlcon->errorInfo(), true).'
';
+ $err_lvl = 2;
+ $count++;
+ } else {
+ if ($mysqlcon->exec("CREATE INDEX `snapshot_id` ON `$dbname`.`user_snapshot` (`id`)") === false) {
+ $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode().' '.print_r($mysqlcon->errorInfo(), true).'
';
+ $err_lvl = 2;
+ $count++;
+ }
+ if ($mysqlcon->exec("CREATE INDEX `snapshot_cldbid` ON `$dbname`.`user_snapshot` (`cldbid`)") === false) {
+ $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode().' '.print_r($mysqlcon->errorInfo(), true).'
';
+ $err_lvl = 2;
+ $count++;
+ }
+ }
+
+ if ($mysqlcon->exec("CREATE TABLE `$dbname`.`stats_server` (
`total_user` int(10) NOT NULL default '0',
`total_online_time` bigint(13) NOT NULL default '0',
`total_online_month` bigint(11) NOT NULL default '0',
@@ -243,12 +259,13 @@ function install($type, $host, $user, $pass, $dbname, $lang, $mysqlcon, &$err_ms
`user_week` int(10) NOT NULL default '0',
`user_month` int(10) NOT NULL default '0',
`user_quarter` int(10) NOT NULL default '0'
- );") === false) {
- $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode()." ".print_r($mysqlcon->errorInfo(), true).'
'; $err_lvl = 2;
- $count++;
- }
-
- if($mysqlcon->exec("CREATE TABLE `$dbname`.`stats_user` (
+ );") === false) {
+ $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode().' '.print_r($mysqlcon->errorInfo(), true).'
';
+ $err_lvl = 2;
+ $count++;
+ }
+
+ if ($mysqlcon->exec("CREATE TABLE `$dbname`.`stats_user` (
`uuid` char(28) CHARACTER SET utf8 COLLATE utf8_unicode_ci PRIMARY KEY,
`active_day` mediumint(8) UNSIGNED NOT NULL default '0',
`active_month` mediumint(8) UNSIGNED NOT NULL default '0',
@@ -266,44 +283,49 @@ function install($type, $host, $user, $pass, $dbname, $lang, $mysqlcon, &$err_ms
`last_calculated` int(10) UNSIGNED NOT NULL default '0',
`removed` tinyint(1) NOT NULL default '0',
`total_connections` MEDIUMINT(8) UNSIGNED NOT NULL default '0'
- );") === false) {
- $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode()." ".print_r($mysqlcon->errorInfo(), true).'
'; $err_lvl = 2;
- $count++;
- }
-
- if($mysqlcon->exec("INSERT INTO `$dbname`.`stats_server` SET `total_user`='9999'") === false) {
- $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode()." ".print_r($mysqlcon->errorInfo(), true).'
'; $err_lvl = 2;
- $count++;
- }
-
- if($mysqlcon->exec("CREATE TABLE `$dbname`.`admin_addtime` (
+ );") === false) {
+ $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode().' '.print_r($mysqlcon->errorInfo(), true).'
';
+ $err_lvl = 2;
+ $count++;
+ }
+
+ if ($mysqlcon->exec("INSERT INTO `$dbname`.`stats_server` SET `total_user`='9999'") === false) {
+ $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode().' '.print_r($mysqlcon->errorInfo(), true).'
';
+ $err_lvl = 2;
+ $count++;
+ }
+
+ if ($mysqlcon->exec("CREATE TABLE `$dbname`.`admin_addtime` (
`uuid` char(28) CHARACTER SET utf8 COLLATE utf8_unicode_ci,
`timestamp` int(10) UNSIGNED NOT NULL default '0',
`timecount` int(10) NOT NULL default '0',
PRIMARY KEY (`uuid`,`timestamp`)
- );") === false) {
- $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode()." ".print_r($mysqlcon->errorInfo(), true).'
'; $err_lvl = 2;
- $count++;
- }
-
- if($mysqlcon->exec("CREATE TABLE `$dbname`.`user_iphash` (
+ );") === false) {
+ $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode().' '.print_r($mysqlcon->errorInfo(), true).'
';
+ $err_lvl = 2;
+ $count++;
+ }
+
+ if ($mysqlcon->exec("CREATE TABLE `$dbname`.`user_iphash` (
`uuid` char(28) CHARACTER SET utf8 COLLATE utf8_unicode_ci PRIMARY KEY,
`iphash` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci,
`ip` varchar(39) CHARACTER SET utf8 COLLATE utf8_unicode_ci
- );") === false) {
- $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode()." ".print_r($mysqlcon->errorInfo(), true).'
'; $err_lvl = 2;
- $count++;
- }
-
- if($mysqlcon->exec("CREATE TABLE `$dbname`.`job_check` (
+ );") === false) {
+ $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode().' '.print_r($mysqlcon->errorInfo(), true).'
';
+ $err_lvl = 2;
+ $count++;
+ }
+
+ if ($mysqlcon->exec("CREATE TABLE `$dbname`.`job_check` (
`job_name` varchar(20) CHARACTER SET utf8 COLLATE utf8_unicode_ci PRIMARY KEY,
`timestamp` int(10) UNSIGNED NOT NULL default '0'
- );") === false) {
- $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode()." ".print_r($mysqlcon->errorInfo(), true).'
'; $err_lvl = 2;
- $count++;
- }
-
- if($mysqlcon->exec("INSERT INTO `$dbname`.`job_check` (`job_name`) VALUES
+ );") === false) {
+ $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode().' '.print_r($mysqlcon->errorInfo(), true).'
';
+ $err_lvl = 2;
+ $count++;
+ }
+
+ if ($mysqlcon->exec("INSERT INTO `$dbname`.`job_check` (`job_name`) VALUES
('calc_donut_chars'),
('calc_server_stats'),
('calc_user_lastscan'),
@@ -331,55 +353,61 @@ function install($type, $host, $user, $pass, $dbname, $lang, $mysqlcon, &$err_ms
('runtime_check'),
('update_channel'),
('update_groups')
- ;") === false) {
- $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode()." ".print_r($mysqlcon->errorInfo(), true).'
'; $err_lvl = 2;
- $count++;
- }
-
- if($mysqlcon->exec("CREATE TABLE `$dbname`.`stats_nations` (
+ ;") === false) {
+ $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode().' '.print_r($mysqlcon->errorInfo(), true).'
';
+ $err_lvl = 2;
+ $count++;
+ }
+
+ if ($mysqlcon->exec("CREATE TABLE `$dbname`.`stats_nations` (
`nation` char(2) CHARACTER SET utf8 COLLATE utf8_unicode_ci PRIMARY KEY,
`count` smallint(5) UNSIGNED NOT NULL default '0'
- );") === false) {
- $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode()." ".print_r($mysqlcon->errorInfo(), true).'
'; $err_lvl = 2;
- $count++;
- }
-
- if($mysqlcon->exec("CREATE TABLE `$dbname`.`stats_versions` (
+ );") === false) {
+ $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode().' '.print_r($mysqlcon->errorInfo(), true).'
';
+ $err_lvl = 2;
+ $count++;
+ }
+
+ if ($mysqlcon->exec("CREATE TABLE `$dbname`.`stats_versions` (
`version` varchar(64) CHARACTER SET utf8 COLLATE utf8_unicode_ci PRIMARY KEY,
`count` smallint(5) UNSIGNED NOT NULL default '0'
- );") === false) {
- $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode()." ".print_r($mysqlcon->errorInfo(), true).'
'; $err_lvl = 2;
- $count++;
- }
-
- if($mysqlcon->exec("CREATE TABLE `$dbname`.`stats_platforms` (
+ );") === false) {
+ $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode().' '.print_r($mysqlcon->errorInfo(), true).'
';
+ $err_lvl = 2;
+ $count++;
+ }
+
+ if ($mysqlcon->exec("CREATE TABLE `$dbname`.`stats_platforms` (
`platform` varchar(32) CHARACTER SET utf8 COLLATE utf8_unicode_ci PRIMARY KEY,
`count` smallint(5) UNSIGNED NOT NULL default '0'
- );") === false) {
- $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode()." ".print_r($mysqlcon->errorInfo(), true).'
'; $err_lvl = 2;
- $count++;
- } else {
- if($mysqlcon->exec("INSERT INTO `$dbname`.`stats_platforms` (`platform`,`count`) VALUES
+ );") === false) {
+ $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode().' '.print_r($mysqlcon->errorInfo(), true).'
';
+ $err_lvl = 2;
+ $count++;
+ } else {
+ if ($mysqlcon->exec("INSERT INTO `$dbname`.`stats_platforms` (`platform`,`count`) VALUES
('Windows',0),
('Android',0),
('OSX',0),
('iOS',0),
('Linux',0)
- ;") === false) {
- $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode()." ".print_r($mysqlcon->errorInfo(), true).'
'; $err_lvl = 2;
- $count++;
- }
- }
-
- if($mysqlcon->exec("CREATE TABLE `$dbname`.`addons_config` (
+ ;") === false) {
+ $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode().' '.print_r($mysqlcon->errorInfo(), true).'
';
+ $err_lvl = 2;
+ $count++;
+ }
+ }
+
+ if ($mysqlcon->exec("CREATE TABLE `$dbname`.`addons_config` (
`param` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci UNIQUE,
`value` varchar(16000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
- );") === false) {
- $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode()." ".print_r($mysqlcon->errorInfo(), true).'
'; $err_lvl = 2;
- $count++;
- }
-
- $channelinfo_desc = $mysqlcon->quote('[CENTER][B][SIZE=15]User Toplist (last week)[/SIZE][/B][/CENTER]
+ );") === false) {
+ $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode().' '.print_r($mysqlcon->errorInfo(), true).'
';
+ $err_lvl = 2;
+ $count++;
+ }
+
+ $channelinfo_desc = $mysqlcon->quote('[CENTER][B][SIZE=15]User Toplist (last week)[/SIZE][/B][/CENTER]
[SIZE=11][B]1st[/B] [URL=client://0/{$CLIENT_UNIQUE_IDENTIFIER_1}]{$CLIENT_NICKNAME_1}[/URL][/SIZE][SIZE=7] {if {$CLIENT_ONLINE_STATUS_1} === \'Online\'}[COLOR=GREEN](Online)[/COLOR]
currently in channel [URL=channelid://{$CLIENT_CURRENT_CHANNEL_ID_1}]{$CLIENT_CURRENT_CHANNEL_NAME_1}[/URL]{else}[COLOR=RED](Offline)[/COLOR]
@@ -432,9 +460,9 @@ function install($type, $host, $user, $pass, $dbname, $lang, $mysqlcon, &$err_ms
[SIZE=8]Last week active: {$CLIENT_ACTIVE_TIME_LAST_WEEK_10}; reached Servergroup: [IMG]https://domain.com/ranksystem/{$CLIENT_CURRENT_RANK_GROUP_ICON_URL_10}[/IMG] {$CLIENT_CURRENT_RANK_GROUP_NAME_10}[/SIZE]
-[SIZE=6]Updated: {$LAST_UPDATE_TIME}[/SIZE]', ENT_QUOTES);
-
- if($mysqlcon->exec("INSERT INTO `$dbname`.`addons_config` (`param`,`value`) VALUES
+[SIZE=6]Updated: {$LAST_UPDATE_TIME}[/SIZE]', ENT_QUOTES);
+
+ if ($mysqlcon->exec("INSERT INTO `$dbname`.`addons_config` (`param`,`value`) VALUES
('assign_groups_active','0'),
('assign_groups_name',''),
('assign_groups_excepted_groupids',''),
@@ -447,123 +475,132 @@ function install($type, $host, $user, $pass, $dbname, $lang, $mysqlcon, &$err_ms
('channelinfo_toplist_channelid','0'),
('channelinfo_toplist_modus','1'),
('channelinfo_toplist_lastupdate','0')
- ;") === false) {
- $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode()." ".print_r($mysqlcon->errorInfo(), true).'
'; $err_lvl = 2;
- $count++;
- }
-
- if($mysqlcon->exec("CREATE TABLE `$dbname`.`addon_assign_groups` (
+ ;") === false) {
+ $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode().' '.print_r($mysqlcon->errorInfo(), true).'
';
+ $err_lvl = 2;
+ $count++;
+ }
+
+ if ($mysqlcon->exec("CREATE TABLE `$dbname`.`addon_assign_groups` (
`uuid` char(28) CHARACTER SET utf8 COLLATE utf8_unicode_ci PRIMARY KEY,
`grpids` varchar(1000) CHARACTER SET utf8 COLLATE utf8_unicode_ci
- );") === false) {
- $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode()." ".print_r($mysqlcon->errorInfo(), true).'
'; $err_lvl = 2;
- $count++;
- }
-
- if($mysqlcon->exec("CREATE TABLE `$dbname`.`csrf_token` (
+ );") === false) {
+ $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode().' '.print_r($mysqlcon->errorInfo(), true).'
';
+ $err_lvl = 2;
+ $count++;
+ }
+
+ if ($mysqlcon->exec("CREATE TABLE `$dbname`.`csrf_token` (
`token` varchar(64) CHARACTER SET utf8 COLLATE utf8_unicode_ci PRIMARY KEY,
`timestamp` int(10) UNSIGNED NOT NULL default '0',
`sessionid` varchar(128) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL
- );") === false) {
- $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode()." ".print_r($mysqlcon->errorInfo(), true).'
'; $err_lvl = 2;
- $count++;
- }
-
- if($mysqlcon->exec("CREATE TABLE `$dbname`.`channel` (
+ );") === false) {
+ $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode().' '.print_r($mysqlcon->errorInfo(), true).'
';
+ $err_lvl = 2;
+ $count++;
+ }
+
+ if ($mysqlcon->exec("CREATE TABLE `$dbname`.`channel` (
`cid` int(10) UNSIGNED NOT NULL default '0' PRIMARY KEY,
`pid` int(10) UNSIGNED NOT NULL default '0',
`channel_order` int(10) UNSIGNED NOT NULL default '0',
`channel_name` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL
- );") === false) {
- $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode()." ".print_r($mysqlcon->errorInfo(), true).'
'; $err_lvl = 2;
- $count++;
- }
-
- if($count == 1) {
- $err_msg = sprintf($lang['instdbsuc'], $dbname); $err_lvl = NULL;
- $install_webuser = 1;
-
- $dbconfig = fopen('./other/dbconfig.php','w');
- if(!fwrite($dbconfig, $newconfig)) {
- $err_msg = $lang['isntwicfg'];
- $err_lvl = 2;
- }
- fclose($dbconfig);
- }
- }
-}
-
-if (isset($_POST['install'])) {
- unset($err_msg);
- if ($_POST['dbtype'] == 'mysql') {
- if(!in_array('pdo_mysql', get_loaded_extensions())) {
- unset($err_msg); $err_msg = sprintf($lang['insterr2'],'PHP MySQL','//php.net/manual/en/ref.pdo-mysql.php',get_cfg_var('cfg_file_path')); $err_lvl = 3;
- } else {
- $dboptions = array();
- }
- } else {
- $dboptions = array();
- }
-
- if(!isset($err_msg)) {
- $dbserver = $_POST['dbtype'].':host='.$_POST['dbhost'].'; dbname='.$_POST['dbname'].';charset=utf8mb4';
- $dbserver2 = $_POST['dbtype'].':host='.$_POST['dbhost'].';charset=utf8mb4';
- $dbexists = 0;
- try {
- $mysqlcon = new PDO($dbserver, $_POST['dbuser'], $_POST['dbpass'], $dboptions);
- $dbexists = 1;
- } catch (PDOException $e) {
- try {
- $mysqlcon = new PDO($dbserver2, $_POST['dbuser'], $_POST['dbpass'], $dboptions);
- } catch (PDOException $e) {
- $err_msg = htmlspecialchars($lang['dbconerr'].$e->getMessage()); $err_lvl = 1;
- }
- }
-
- if(!is_writable('./other/dbconfig.php')) {
- $err_msg = $lang['isntwicfg'];
- $err_lvl = 2;
- }
- }
-
- if(!isset($err_msg)) {
- if(isset($_POST['installchecked'])) {
- install($_POST['dbtype'], $_POST['dbhost'], $_POST['dbuser'], $_POST['dbpass'], $_POST['dbname'], $lang, $mysqlcon, $err_msg, $err_lvl, $install_webuser);
- } elseif($dbexists == 1) {
- $err_msg = sprintf($lang['insterr1'],$_POST['dbname']);
- $err_lvl = 2;
- $show_warning = 1;
- } else {
- install($_POST['dbtype'], $_POST['dbhost'], $_POST['dbuser'], $_POST['dbpass'], $_POST['dbname'], $lang, $mysqlcon, $err_msg, $err_lvl, $install_webuser);
- }
- }
-}
-
-if(isset($_POST['confweb'])) {
- require_once('other/dbconfig.php');
- $user=$_POST['user'];
- $pass=password_hash($_POST['pass'], PASSWORD_DEFAULT);
- $logpath = addslashes(__DIR__.DIRECTORY_SEPARATOR."logs".DIRECTORY_SEPARATOR);
- $dbname = $db['dbname'];
- $dbserver = $db['type'].':host='.$db['host'].'; dbname=`'.$db['dbname'].'`;charset=utf8mb4';
- $dbserver2 = $db['type'].':host='.$db['host'];
- try {
- $mysqlcon = new PDO($dbserver, $db['user'], $db['pass']);
- } catch (PDOException $e) {
- try {
- $mysqlcon = new PDO($dbserver2, $db['user'], $db['pass']);
- } catch (PDOException $e) {
- $err_msg = htmlspecialchars($lang['dbconerr'].$e->getMessage()); $err_lvl = 1;
- }
- }
- if(!isset($err_lvl) || $err_lvl != 1) {
- $dateformat = $mysqlcon->quote("%a days, %h hours, %i mins, %s secs");
- $nextupinfomsg1 = $mysqlcon->quote("Your next rank up will be in %1\$s days, %2\$s hours, %3\$s minutes and %4\$s seconds. The next servergroup you will reach is [B]%5\$s[/B].");
- $nextupinfomsg2 = $mysqlcon->quote("You have already reached the highest rank.");
- $nextupinfomsg3 = $mysqlcon->quote("You are excepted from the Ranksystem. If you wish to rank contact an admin on the TS3 server.");
- $servernews = $mysqlcon->quote("
Message This is an example Message.
Change this Message inside the webinterface.");
- $rankupmsg = $mysqlcon->quote('Hey, you reached a higher rank, since you already connected for %1$s days, %2$s hours and %3$s minutes to our TS3 server.[B]Keep it up![/B] ;-) ');
- if($mysqlcon->exec("INSERT INTO `$dbname`.`cfg_params` (`param`,`value`) VALUES
+ );") === false) {
+ $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode().' '.print_r($mysqlcon->errorInfo(), true).'
';
+ $err_lvl = 2;
+ $count++;
+ }
+
+ if ($count == 1) {
+ $err_msg = sprintf($lang['instdbsuc'], $dbname);
+ $err_lvl = null;
+ $install_webuser = 1;
+
+ $dbconfig = fopen('./other/dbconfig.php', 'w');
+ if (! fwrite($dbconfig, $newconfig)) {
+ $err_msg = $lang['isntwicfg'];
+ $err_lvl = 2;
+ }
+ fclose($dbconfig);
+ }
+ }
+}
+
+if (isset($_POST['install'])) {
+ unset($err_msg);
+ if ($_POST['dbtype'] == 'mysql') {
+ if (! in_array('pdo_mysql', get_loaded_extensions())) {
+ unset($err_msg);
+ $err_msg = sprintf($lang['insterr2'], 'PHP MySQL', '//php.net/manual/en/ref.pdo-mysql.php', get_cfg_var('cfg_file_path'));
+ $err_lvl = 3;
+ } else {
+ $dboptions = [];
+ }
+ } else {
+ $dboptions = [];
+ }
+
+ if (! isset($err_msg)) {
+ $dbserver = $_POST['dbtype'].':host='.$_POST['dbhost'].'; dbname='.$_POST['dbname'].';charset=utf8mb4';
+ $dbserver2 = $_POST['dbtype'].':host='.$_POST['dbhost'].';charset=utf8mb4';
+ $dbexists = 0;
+ try {
+ $mysqlcon = new PDO($dbserver, $_POST['dbuser'], $_POST['dbpass'], $dboptions);
+ $dbexists = 1;
+ } catch (PDOException $e) {
+ try {
+ $mysqlcon = new PDO($dbserver2, $_POST['dbuser'], $_POST['dbpass'], $dboptions);
+ } catch (PDOException $e) {
+ $err_msg = htmlspecialchars($lang['dbconerr'].$e->getMessage());
+ $err_lvl = 1;
+ }
+ }
+
+ if (! is_writable('./other/dbconfig.php')) {
+ $err_msg = $lang['isntwicfg'];
+ $err_lvl = 2;
+ }
+ }
+
+ if (! isset($err_msg)) {
+ if (isset($_POST['installchecked'])) {
+ install($_POST['dbtype'], $_POST['dbhost'], $_POST['dbuser'], $_POST['dbpass'], $_POST['dbname'], $lang, $mysqlcon, $err_msg, $err_lvl, $install_webuser);
+ } elseif ($dbexists == 1) {
+ $err_msg = sprintf($lang['insterr1'], $_POST['dbname']);
+ $err_lvl = 2;
+ $show_warning = 1;
+ } else {
+ install($_POST['dbtype'], $_POST['dbhost'], $_POST['dbuser'], $_POST['dbpass'], $_POST['dbname'], $lang, $mysqlcon, $err_msg, $err_lvl, $install_webuser);
+ }
+ }
+}
+
+if (isset($_POST['confweb'])) {
+ require_once 'other/dbconfig.php';
+ $user = $_POST['user'];
+ $pass = password_hash($_POST['pass'], PASSWORD_DEFAULT);
+ $logpath = addslashes(__DIR__.DIRECTORY_SEPARATOR.'logs'.DIRECTORY_SEPARATOR);
+ $dbname = $db['dbname'];
+ $dbserver = $db['type'].':host='.$db['host'].'; dbname=`'.$db['dbname'].'`;charset=utf8mb4';
+ $dbserver2 = $db['type'].':host='.$db['host'];
+ try {
+ $mysqlcon = new PDO($dbserver, $db['user'], $db['pass']);
+ } catch (PDOException $e) {
+ try {
+ $mysqlcon = new PDO($dbserver2, $db['user'], $db['pass']);
+ } catch (PDOException $e) {
+ $err_msg = htmlspecialchars($lang['dbconerr'].$e->getMessage());
+ $err_lvl = 1;
+ }
+ }
+ if (! isset($err_lvl) || $err_lvl != 1) {
+ $dateformat = $mysqlcon->quote('%a days, %h hours, %i mins, %s secs');
+ $nextupinfomsg1 = $mysqlcon->quote('Your next rank up will be in %1$s days, %2$s hours, %3$s minutes and %4$s seconds. The next servergroup you will reach is [B]%5$s[/B].');
+ $nextupinfomsg2 = $mysqlcon->quote('You have already reached the highest rank.');
+ $nextupinfomsg3 = $mysqlcon->quote('You are excepted from the Ranksystem. If you wish to rank contact an admin on the TS3 server.');
+ $servernews = $mysqlcon->quote('
Message This is an example Message.
Change this Message inside the webinterface.');
+ $rankupmsg = $mysqlcon->quote('Hey, you reached a higher rank, since you already connected for %1$s days, %2$s hours and %3$s minutes to our TS3 server.[B]Keep it up![/B] ;-) ');
+ if ($mysqlcon->exec("INSERT INTO `$dbname`.`cfg_params` (`param`,`value`) VALUES
('default_cmdline_sec_switch', '1'),
('default_date_format', {$dateformat}),
('default_header_contenttyp', '1'),
@@ -670,142 +707,164 @@ function install($type, $host, $user, $pass, $dbname, $lang, $mysqlcon, &$err_ms
('webinterface_fresh_installation', '1'),
('webinterface_pass', '{$pass}'),
('webinterface_user', '{$user}')
- ;") === false) {
- $err_msg = $lang['isntwidbmsg'].$mysqlcon->errorCode()." ".print_r($mysqlcon->errorInfo(), true); $err_lvl = 2;
- } else {
- $err_msg = $lang['isntwiusr'].'
';
- $err_msg = $lang['isntwiusr2'].'
';
- $err_msg .= sprintf($lang['isntwiconf'],"
/webinterface/ ").'
';
- if(!unlink('./install.php')) {
- $err_msg .= $lang['isntwidel'];
- }
- $install_finished = 1; $err_lvl = NULL;
- }
- }
-}
-
-if (!isset($_POST['install']) && !isset($_POST['confweb'])) {
- unset($err_msg);
- unset($err_lvl);
- $err_msg = '';
- if(!is_writable('./other/dbconfig.php')) {
- $err_msg = $lang['isntwicfg']; $err_lvl = 3;
- }
-
- $file_err_count=0;
- $file_err_msg = '';
- try {
- $scandir = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(__DIR__));
- $files = array();
- foreach ($scandir as $object) {
- if(!strstr($object, '/.') && !strstr($object, '\.')) {
- if (!$object->isDir()) {
- if(!is_writable($object->getPathname())) {
- $file_err_msg .= "File is not writeable ".$object."
";
- $file_err_count++;
- }
- } else {
- if(!is_writable($object->getPathname())) {
- $file_err_msg .= "Folder is not writeable ".$object."
";
- $file_err_count++;
- }
- }
- }
- }
- } catch (Exception $e) {
- $err_msg .= "File Permissions Error: ".$e->getCode()." ".$e->getMessage();
- $err_lvl = 3;
- }
-
- if($file_err_count!=0) {
- $err_msg = "
Wrong file/folder permissions! You need to correct the owner and access permissions of the named files/folders!
The
owner of all files and folders of the Ranksystem installation folder must be the user of your webserver (e.g.: www-data).
On Linux systems you may do something like this (linux shell command):
chown -R www-data:www-data ".__DIR__."
Also the
access permission must be set, that the user of your webserver is able to read, write and execute files.
On Linux systems you may do something like this (linux shell command):
chmod -R 640 ".__DIR__."
List of concerned files/folders:
";
- $err_lvl = 3;
- $err_msg .= $file_err_msg;
- }
-
- if(!class_exists('PDO')) {
- $err_msg = sprintf($lang['insterr2'],'PHP PDO','//php.net/manual/en/book.pdo.php',get_cfg_var('cfg_file_path')); $err_lvl = 3;
- }
- if(version_compare(phpversion(), '5.5.0', '<')) {
- $err_msg = sprintf($lang['insterr4'],phpversion()); $err_lvl = 3;
- }
- if(!function_exists('simplexml_load_file')) {
- $err_msg = sprintf($lang['insterr2'],'PHP SimpleXML','//php.net/manual/en/book.simplexml.php',get_cfg_var('cfg_file_path')); $err_lvl = 3;
- }
- if(!in_array('curl', get_loaded_extensions())) {
- $err_msg = sprintf($lang['insterr2'],'PHP cURL','//php.net/manual/en/book.curl.php',get_cfg_var('cfg_file_path')); $err_lvl = 3;
- }
- if(!in_array('zip', get_loaded_extensions())) {
- $err_msg = sprintf($lang['insterr2'],'PHP Zip','//php.net/manual/en/book.zip.php',get_cfg_var('cfg_file_path')); $err_lvl = 3;
- }
- if(!in_array('mbstring', get_loaded_extensions())) {
- $err_msg = sprintf($lang['insterr2'],'PHP mbstring','//php.net/manual/en/book.mbstring.php',get_cfg_var('cfg_file_path')); $err_lvl = 3;
- }
- if(!in_array('openssl', get_loaded_extensions())) {
- unset($err_msg); $err_msg = sprintf($lang['insterr2'],'PHP OpenSSL','//php.net/manual/en/book.openssl.php',get_cfg_var('cfg_file_path')); $err_lvl = 3; $dis_login = 1;
- }
- if(strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
- if(!in_array('com_dotnet', get_loaded_extensions())) {
- $err_msg = sprintf($lang['insterr2'],'PHP COM and .NET (Windows only)','//php.net/manual/en/book.com.php',get_cfg_var('cfg_file_path')); $err_lvl = 3;
- }
- }
- if(!function_exists('exec')) {
- unset($err_msg); $err_msg = sprintf($lang['insterr3'],'exec','//php.net/manual/en/book.exec.php',get_cfg_var('cfg_file_path')); $err_lvl = 3;
- } else {
- if ($err_msg == NULL) {
- require_once('other/phpcommand.php');
- exec("$phpcommand -v", $phpversioncheck);
- $output = '';
- foreach($phpversioncheck as $line) $output .= print_r($line, true).'
';
- if(empty($phpversioncheck) || strtoupper(substr($phpversioncheck[0], 0, 3)) != "PHP") {
- $err_msg .= sprintf($lang['chkphpcmd'], "\"other/phpcommand.php\"", "
\"other/phpcommand.php\" ", '
'.$phpcommand.' ', '
'.$output.' ', '
php -v '); $err_lvl = 3;
- } else {
- $exploded = explode(' ',$phpversioncheck[0]);
- if($exploded[1] != phpversion()) {
- $err_msg .= sprintf($lang['chkphpmulti'], phpversion(), "
\"other/phpcommand.php\" ", $exploded[1], "\"other/phpcommand.php\"", "\"other/phpcommand.php\"", '
'.$phpcommand.' ');
- if(getenv('PATH')!='') {
- $err_msg .= "
".sprintf($lang['chkphpmulti2'], '
'.getenv('PATH')); $err_lvl = 2;
- }
- }
- }
- }
- }
-
- if($err_msg == '' && (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != "on")) {
- $host = "
";
- $err_msg = sprintf($lang['winav10'], $host,' !
', '
'); $err_lvl = 2;
- }
-
- if(!isset($err_lvl)) {
- unset($err_msg);
- }
-}
-
-if ((!isset($_POST['install']) && !isset($_POST['confweb'])) || $err_lvl == 1 || $err_lvl == 2 || $err_lvl == 3) {
- if(isset($show_warning)) {
- $dbhost = $_POST['dbhost'];
- $dbname = $_POST['dbname'];
- $dbuser = $_POST['dbuser'];
- $dbpass = $_POST['dbpass'];
- } elseif(isset($_GET["dbhost"]) && isset($_GET["dbname"]) && isset($_GET["dbuser"]) && isset($_GET["dbpass"])) {
- $dbhost = $_GET["dbhost"];
- $dbname = $_GET['dbname'];
- $dbuser = $_GET['dbuser'];
- $dbpass = $_GET['dbpass'];
- } else {
- $dbhost = "";
- $dbname = "";
- $dbuser = "";
- $dbpass = "";
- }
- ?>
+ ;") === false) {
+ $err_msg = $lang['isntwidbmsg'].$mysqlcon->errorCode().' '.print_r($mysqlcon->errorInfo(), true);
+ $err_lvl = 2;
+ } else {
+ $err_msg = $lang['isntwiusr'].'
';
+ $err_msg = $lang['isntwiusr2'].'
';
+ $err_msg .= sprintf($lang['isntwiconf'], '
/webinterface/ ').'
';
+ if (! unlink('./install.php')) {
+ $err_msg .= $lang['isntwidel'];
+ }
+ $install_finished = 1;
+ $err_lvl = null;
+ }
+ }
+}
+
+if (! isset($_POST['install']) && ! isset($_POST['confweb'])) {
+ unset($err_msg);
+ unset($err_lvl);
+ $err_msg = '';
+ if (! is_writable('./other/dbconfig.php')) {
+ $err_msg = $lang['isntwicfg'];
+ $err_lvl = 3;
+ }
+
+ $file_err_count = 0;
+ $file_err_msg = '';
+ try {
+ $scandir = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(__DIR__));
+ $files = [];
+ foreach ($scandir as $object) {
+ if (! strstr($object, '/.') && ! strstr($object, '\.')) {
+ if (! $object->isDir()) {
+ if (! is_writable($object->getPathname())) {
+ $file_err_msg .= 'File is not writeable '.$object.'
';
+ $file_err_count++;
+ }
+ } else {
+ if (! is_writable($object->getPathname())) {
+ $file_err_msg .= 'Folder is not writeable '.$object.'
';
+ $file_err_count++;
+ }
+ }
+ }
+ }
+ } catch (Exception $e) {
+ $err_msg .= 'File Permissions Error: '.$e->getCode().' '.$e->getMessage();
+ $err_lvl = 3;
+ }
+
+ if ($file_err_count != 0) {
+ $err_msg = '
Wrong file/folder permissions! You need to correct the owner and access permissions of the named files/folders!
The
owner of all files and folders of the Ranksystem installation folder must be the user of your webserver (e.g.: www-data).
On Linux systems you may do something like this (linux shell command):
chown -R www-data:www-data '.__DIR__.'
Also the
access permission must be set, that the user of your webserver is able to read, write and execute files.
On Linux systems you may do something like this (linux shell command):
chmod -R 640 '.__DIR__.'
List of concerned files/folders:
';
+ $err_lvl = 3;
+ $err_msg .= $file_err_msg;
+ }
+
+ if (! class_exists('PDO')) {
+ $err_msg = sprintf($lang['insterr2'], 'PHP PDO', '//php.net/manual/en/book.pdo.php', get_cfg_var('cfg_file_path'));
+ $err_lvl = 3;
+ }
+ if (version_compare(phpversion(), '5.5.0', '<')) {
+ $err_msg = sprintf($lang['insterr4'], phpversion());
+ $err_lvl = 3;
+ }
+ if (! function_exists('simplexml_load_file')) {
+ $err_msg = sprintf($lang['insterr2'], 'PHP SimpleXML', '//php.net/manual/en/book.simplexml.php', get_cfg_var('cfg_file_path'));
+ $err_lvl = 3;
+ }
+ if (! in_array('curl', get_loaded_extensions())) {
+ $err_msg = sprintf($lang['insterr2'], 'PHP cURL', '//php.net/manual/en/book.curl.php', get_cfg_var('cfg_file_path'));
+ $err_lvl = 3;
+ }
+ if (! in_array('zip', get_loaded_extensions())) {
+ $err_msg = sprintf($lang['insterr2'], 'PHP Zip', '//php.net/manual/en/book.zip.php', get_cfg_var('cfg_file_path'));
+ $err_lvl = 3;
+ }
+ if (! in_array('mbstring', get_loaded_extensions())) {
+ $err_msg = sprintf($lang['insterr2'], 'PHP mbstring', '//php.net/manual/en/book.mbstring.php', get_cfg_var('cfg_file_path'));
+ $err_lvl = 3;
+ }
+ if (! in_array('openssl', get_loaded_extensions())) {
+ unset($err_msg);
+ $err_msg = sprintf($lang['insterr2'], 'PHP OpenSSL', '//php.net/manual/en/book.openssl.php', get_cfg_var('cfg_file_path'));
+ $err_lvl = 3;
+ $dis_login = 1;
+ }
+ if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
+ if (! in_array('com_dotnet', get_loaded_extensions())) {
+ $err_msg = sprintf($lang['insterr2'], 'PHP COM and .NET (Windows only)', '//php.net/manual/en/book.com.php', get_cfg_var('cfg_file_path'));
+ $err_lvl = 3;
+ }
+ }
+ if (! function_exists('exec')) {
+ unset($err_msg);
+ $err_msg = sprintf($lang['insterr3'], 'exec', '//php.net/manual/en/book.exec.php', get_cfg_var('cfg_file_path'));
+ $err_lvl = 3;
+ } else {
+ if ($err_msg == null) {
+ require_once 'other/phpcommand.php';
+ exec("$phpcommand -v", $phpversioncheck);
+ $output = '';
+ foreach ($phpversioncheck as $line) {
+ $output .= print_r($line, true).'
';
+ }
+ if (empty($phpversioncheck) || strtoupper(substr($phpversioncheck[0], 0, 3)) != 'PHP') {
+ $err_msg .= sprintf($lang['chkphpcmd'], '"other/phpcommand.php"', '
"other/phpcommand.php" ', '
'.$phpcommand.' ', '
'.$output.' ', '
php -v ');
+ $err_lvl = 3;
+ } else {
+ $exploded = explode(' ', $phpversioncheck[0]);
+ if ($exploded[1] != phpversion()) {
+ $err_msg .= sprintf($lang['chkphpmulti'], phpversion(), '
"other/phpcommand.php" ', $exploded[1], '"other/phpcommand.php"', '"other/phpcommand.php"', '
'.$phpcommand.' ');
+ if (getenv('PATH') != '') {
+ $err_msg .= '
'.sprintf($lang['chkphpmulti2'], '
'.getenv('PATH'));
+ $err_lvl = 2;
+ }
+ }
+ }
+ }
+ }
+
+ if ($err_msg == '' && (! isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != 'on')) {
+ $host = '
';
+ $err_msg = sprintf($lang['winav10'], $host, ' !
', '
');
+ $err_lvl = 2;
+ }
+
+ if (! isset($err_lvl)) {
+ unset($err_msg);
+ }
+}
+
+if ((! isset($_POST['install']) && ! isset($_POST['confweb'])) || $err_lvl == 1 || $err_lvl == 2 || $err_lvl == 3) {
+ if (isset($show_warning)) {
+ $dbhost = $_POST['dbhost'];
+ $dbname = $_POST['dbname'];
+ $dbuser = $_POST['dbuser'];
+ $dbpass = $_POST['dbpass'];
+ } elseif (isset($_GET['dbhost']) && isset($_GET['dbname']) && isset($_GET['dbuser']) && isset($_GET['dbpass'])) {
+ $dbhost = $_GET['dbhost'];
+ $dbname = $_GET['dbname'];
+ $dbuser = $_GET['dbuser'];
+ $dbpass = $_GET['dbpass'];
+ } else {
+ $dbhost = '';
+ $dbname = '';
+ $dbuser = '';
+ $dbpass = '';
+ }
+ ?>
-
+
@@ -869,16 +928,16 @@ function install($type, $host, $user, $pass, $dbname, $lang, $mysqlcon, &$err_ms
- ",$lang['instdb'],"";
- } else {
- echo "",$lang['instdb']," ";
- }
- if(isset($show_warning)) {
- echo ' ';
- }
- ?>
+ ',$lang['instdb'],'';
+ } else {
+ echo '',$lang['instdb'],' ';
+ }
+ if (isset($show_warning)) {
+ echo ' ';
+ }
+ ?>
@@ -894,10 +953,10 @@ function install($type, $host, $user, $pass, $dbname, $lang, $mysqlcon, &$err_ms
- https://ts-ranksystem.com/#linux'); ?>
+ https://ts-ranksystem.com/#linux'); ?>
@@ -910,10 +969,10 @@ function install($type, $host, $user, $pass, $dbname, $lang, $mysqlcon, &$err_ms
-
+
@@ -926,10 +985,10 @@ function install($type, $host, $user, $pass, $dbname, $lang, $mysqlcon, &$err_ms
-
+
@@ -942,10 +1001,10 @@ function install($type, $host, $user, $pass, $dbname, $lang, $mysqlcon, &$err_ms
-
+
@@ -958,10 +1017,10 @@ function install($type, $host, $user, $pass, $dbname, $lang, $mysqlcon, &$err_ms
-
+
@@ -974,27 +1033,29 @@ function install($type, $host, $user, $pass, $dbname, $lang, $mysqlcon, &$err_ms
-
+
-
+
-
+
-
+
@@ -1031,32 +1092,34 @@ function install($type, $host, $user, $pass, $dbname, $lang, $mysqlcon, &$err_ms
- ",$lang['isntwiusrcr'],"";
- } else {
- echo "",$lang['isntwiusrcr']," ";
- }
- ?>
+ ',$lang['isntwiusrcr'],'';
+ } else {
+ echo '',$lang['isntwiusrcr'],' ';
+ }
+ ?>
-
+
-
+
';
- }
- return $selectbox;
-}
-
-function set_language($language) {
- if(is_dir($GLOBALS['langpath'])) {
- foreach(scandir($GLOBALS['langpath']) as $file) {
- if ('.' === $file || '..' === $file || is_dir($file)) continue;
- $sep_lang = preg_split("/[._]/", $file);
- if(isset($sep_lang[0]) && $sep_lang[0] == 'core' && isset($sep_lang[1]) && strlen($sep_lang[1]) == 2 && isset($sep_lang[4]) && strtolower($sep_lang[4]) == 'php') {
- if(strtolower($language) == strtolower($sep_lang[1])) {
- include($GLOBALS['langpath'].DIRECTORY_SEPARATOR.'/core_'.$sep_lang[1].'_'.$sep_lang[2].'_'.$sep_lang[3].'.'.$sep_lang[4]);
- $_SESSION[get_rspath().'language'] = $sep_lang[1];
- $required_lang = 1;
- break;
- }
- }
- }
- }
- if(!isset($required_lang)) {
- include($GLOBALS['langpath'].DIRECTORY_SEPARATOR.'core_en_english_gb.php');
- }
- return $lang;
-}
-
-function set_session_ts3($mysqlcon,$cfg,$lang,$dbname) {
- $hpclientip = getclientip();
- $rspathhex = get_rspath();
-
- $allclients = $mysqlcon->query("SELECT `u`.`uuid`,`u`.`cldbid`,`u`.`name`,`u`.`firstcon`,`s`.`total_connections` FROM `$dbname`.`user` AS `u` LEFT JOIN `$dbname`.`stats_user` AS `s` ON `u`.`uuid`=`s`.`uuid` WHERE `online`='1'")->fetchAll();
- $iptable = $mysqlcon->query("SELECT `uuid`,`iphash`,`ip` FROM `$dbname`.`user_iphash`")->fetchAll(PDO::FETCH_ASSOC|PDO::FETCH_UNIQUE);
- if(!isset($_SESSION[$rspathhex.'connected']) && isset($cfg['stats_news_html'])) $_SESSION[$rspathhex.'stats_news_html'] = $cfg['stats_news_html'];
- $_SESSION[$rspathhex.'connected'] = 0;
- $_SESSION[$rspathhex.'tsname'] = $lang['stag0016'];
- $_SESSION[$rspathhex.'serverport'] = $cfg['teamspeak_voice_port'];
- $_SESSION[$rspathhex.'multiple'] = array();
-
-
- if($cfg['rankup_hash_ip_addresses_mode'] == 2) {
- $salt = md5(dechex(crc32(dirname(__DIR__))));
- $hashedip = crypt($hpclientip, '$2y$10$'.$salt.'$');
- }
-
- foreach ($allclients as $client) {
- if(isset($_SESSION[$rspathhex.'uuid_verified']) && $_SESSION[$rspathhex.'uuid_verified'] != $client['uuid']) {
- continue;
- }
- $verify = FALSE;
- if($cfg['rankup_hash_ip_addresses_mode'] == 1) {
- if (isset($iptable[$client['uuid']]['iphash']) && $iptable[$client['uuid']]['iphash'] != NULL && password_verify($hpclientip, $iptable[$client['uuid']]['iphash'])) {
- $verify = TRUE;
- }
- } elseif($cfg['rankup_hash_ip_addresses_mode'] == 2) {
- if (isset($iptable[$client['uuid']]['iphash']) && $hashedip == $iptable[$client['uuid']]['iphash'] && $iptable[$client['uuid']]['iphash'] != NULL) {
- $verify = TRUE;
- }
- } else {
- if (isset($iptable[$client['uuid']]['ip']) && $hpclientip == $iptable[$client['uuid']]['ip'] && $iptable[$client['uuid']]['ip'] != NULL) {
- $verify = TRUE;
- }
- }
- if ($verify == TRUE) {
- $_SESSION[$rspathhex.'tsname'] = htmlspecialchars($client['name']);
- if(isset($_SESSION[$rspathhex.'tsuid']) && $_SESSION[$rspathhex.'tsuid'] != $client['uuid']) {
- $_SESSION[$rspathhex.'multiple'][$client['uuid']] = htmlspecialchars($client['name']);
- $_SESSION[$rspathhex.'tsname'] = "verification needed (multiple)!";
- unset($_SESSION[$rspathhex.'admin']);
- } elseif (!isset($_SESSION[$rspathhex.'tsuid'])) {
- $_SESSION[$rspathhex.'multiple'][$client['uuid']] = htmlspecialchars($client['name']);
- }
- $_SESSION[$rspathhex.'tsuid'] = $client['uuid'];
- if(isset($cfg['webinterface_admin_client_unique_id_list']) && $cfg['webinterface_admin_client_unique_id_list'] != NULL) {
- foreach(array_flip($cfg['webinterface_admin_client_unique_id_list']) as $auuid) {
- if ($_SESSION[$rspathhex.'tsuid'] == $auuid) {
- $_SESSION[$rspathhex.'admin'] = TRUE;
- }
- }
- }
- $_SESSION[$rspathhex.'tscldbid'] = $client['cldbid'];
- if ($client['firstcon'] == 0) {
- $_SESSION[$rspathhex.'tscreated'] = $lang['unknown'];
- } else {
- $_SESSION[$rspathhex.'tscreated'] = date('d-m-Y', $client['firstcon']);
- }
- if ($client['total_connections'] != NULL) {
- $_SESSION[$rspathhex.'tsconnections'] = $client['total_connections'];
- } else {
- $_SESSION[$rspathhex.'tsconnections'] = 0;
- }
- $convert = array('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p');
- $uuidasbase16 = '';
- for ($i = 0; $i < 20; $i++) {
- $char = ord(substr(base64_decode($_SESSION[$rspathhex.'tsuid']), $i, 1));
- $uuidasbase16 .= $convert[($char & 0xF0) >> 4];
- $uuidasbase16 .= $convert[$char & 0x0F];
- }
- if (is_file('../avatars/' . $uuidasbase16 . '.png')) {
- $_SESSION[$rspathhex.'tsavatar'] = $uuidasbase16 . '.png';
- } else {
- $_SESSION[$rspathhex.'tsavatar'] = "none";
- }
- $_SESSION[$rspathhex.'connected'] = 1;
- $_SESSION[$rspathhex.'language'] = $cfg['default_language'];
- $_SESSION[$rspathhex.'style'] = $cfg['default_style'];
- }
- }
-}
-
-function sendmessage($ts3, $cfg, $uuid, $msg, $targetmode, $targetid=NULL, $erromsg=NULL, $loglevel=NULL, $successmsg=NULL, $nolog=NULL) {
- try {
- if(strlen($msg) > 1024) {
- $fragarr = explode("##*##", wordwrap($msg, 1022, "##*##", TRUE), 1022);
- foreach($fragarr as $frag) {
- usleep($cfg['teamspeak_query_command_delay']);
- if ($targetmode==2 && $targetid!=NULL) {
- $ts3->serverGetSelected()->channelGetById($targetid)->message("\n".$frag);
- if($nolog==NULL) enter_logfile(6,"sendmessage fragment to channel (ID: $targetid): ".$frag);
- } elseif ($targetmode==3) {
- $ts3->serverGetSelected()->message("\n".$frag);
- if($nolog==NULL) enter_logfile(6,"sendmessage fragment to server: ".$frag);
- } elseif ($targetmode==1 && $targetid!=NULL) {
- $ts3->serverGetSelected()->clientGetById($targetid)->message("\n".$frag);
- if($nolog==NULL) enter_logfile(6,"sendmessage fragment to connectionID $targetid (uuid $uuid): ".$frag);
- } else {
- $ts3->serverGetSelected()->clientGetByUid($uuid)->message("\n".$frag);
- if($nolog==NULL) enter_logfile(6,"sendmessage fragment to uuid $uuid (connectionID $targetid): ".$frag);
- }
- }
- } else {
- usleep($cfg['teamspeak_query_command_delay']);
- if ($targetmode==2 && $targetid!=NULL) {
- $ts3->serverGetSelected()->channelGetById($targetid)->message($msg);
- if($nolog==NULL) enter_logfile(6,"sendmessage to channel (ID: $targetid): ".$msg);
- } elseif ($targetmode==3) {
- $ts3->serverGetSelected()->message($msg);
- if($nolog==NULL) enter_logfile(6,"sendmessage to server: ".$msg);
- } elseif ($targetmode==1 && $targetid!=NULL) {
- $ts3->serverGetSelected()->clientGetById($targetid)->message($msg);
- if($nolog==NULL) enter_logfile(6,"sendmessage to connectionID $targetid (uuid $uuid): ".$msg);
- } else {
- $ts3->serverGetSelected()->clientGetByUid($uuid)->message($msg);
- if($nolog==NULL) enter_logfile(6,"sendmessage to uuid $uuid (connectionID $targetid): ".$msg);
- }
-
- }
- if($successmsg!=NULL) {
- enter_logfile(5,$successmsg);
- }
- } catch (Exception $e) {
- if($loglevel!=NULL) {
- enter_logfile($loglevel,$erromsg." TS3: ".$e->getCode().': '.$e->getMessage());
- } else {
- enter_logfile(3,"sendmessage: ".$e->getCode().': '.$e->getMessage().", targetmode: $targetmode, targetid: $targetid");
- }
- }
-}
-
-function shutdown($mysqlcon,$loglevel,$reason,$nodestroypid = TRUE) {
- if($nodestroypid === TRUE) {
- if (file_exists($GLOBALS['pidfile'])) {
- unlink($GLOBALS['pidfile']);
- }
- }
- if($nodestroypid === TRUE) {
- enter_logfile($loglevel,$reason." Shutting down!");
- enter_logfile(9,"###################################################################");
- } else {
- enter_logfile($loglevel,$reason." Ignore request!");
- }
- if(isset($mysqlcon)) {
- $mysqlcon = null;
- }
- exit;
-}
-
-function sort_channel_tree($channellist) {
- foreach($channellist as $cid => $results) {
- $channel['channel_order'][$results['pid']][$results['channel_order']] = $cid;
- $channel['pid'][$results['pid']][] = $cid;
- }
-
- foreach($channel['pid'] as $pid => $pid_value) {
- $channel_order = 0;
- $count_pid = count($pid_value);
- for($y=0; $y<$count_pid; $y++) {
- foreach($channellist as $cid => $value) {
- if(isset($channel['channel_order'][$pid][$channel_order]) && $channel['channel_order'][$pid][$channel_order] == $cid) {
- $channel['sorted'][$pid][$cid] = $channellist[$cid];
- $channel_order = $cid;
- }
- }
- }
- }
-
- function channel_list($channel, $channel_list, $pid, $sub) {
- if($channel['sorted'][$pid]) {
- foreach($channel['sorted'][$pid] as $cid => $value) {
- $channel_list[$cid] = $value;
- $channel_list[$cid]['sub_level'] = $sub;
- if(isset($channel['pid'][$cid])) {
- $sub++;
- $channel_list[$cid]['has_childs'] = 1;
- $channel_list = channel_list($channel, $channel_list, $cid, $sub);
- $sub--;
- }
- }
- }
- return $channel_list;
- }
-
- $sorted_channel = channel_list($channel, array(), 0, 1);
- return $sorted_channel;
-}
-
-function sort_options($lang) {
- $arr_sort_options = array(
- array('option' => 'rank', 'title' => $lang['listrank'], 'icon' => 'fas fa-hashtag', 'config' => 'stats_column_rank_switch'),
- array('option' => 'name', 'title' => $lang['listnick'], 'icon' => 'fas fa-user', 'config' => 'stats_column_client_name_switch'),
- array('option' => 'uuid', 'title' => $lang['listuid'], 'icon' => 'fas fa-id-card', 'config' => 'stats_column_unique_id_switch'),
- array('option' => 'cldbid', 'title' => $lang['listcldbid'], 'icon' => 'fas fa-database', 'config' => 'stats_column_client_db_id_switch'),
- array('option' => 'lastseen', 'title' => $lang['listseen'], 'icon' => 'fas fa-user-clock', 'config' => 'stats_column_last_seen_switch'),
- array('option' => 'nation', 'title' => $lang['listnat'], 'icon' => 'fas fa-globe-europe', 'config' => 'stats_column_nation_switch'),
- array('option' => 'version', 'title' => $lang['listver'], 'icon' => 'fas fa-tag', 'config' => 'stats_column_version_switch'),
- array('option' => 'platform', 'title' => $lang['listpla'], 'icon' => 'fas fa-server', 'config' => 'stats_column_platform_switch'),
- array('option' => 'count', 'title' => $lang['listsumo'], 'icon' => 'fas fa-hourglass-start', 'config' => 'stats_column_online_time_switch'),
- array('option' => 'idle', 'title' => $lang['listsumi'], 'icon' => 'fas fa-hourglass-end', 'config' => 'stats_column_idle_time_switch'),
- array('option' => 'active', 'title' => $lang['listsuma'], 'icon' => 'fas fa-hourglass-half', 'config' => 'stats_column_active_time_switch'),
- array('option' => 'count_day', 'title' => $lang['listsumo'].' '.$lang['stix0013'], 'icon' => 'fas fa-hourglass-start', 'config' => 'stats_column_online_day_switch'),
- array('option' => 'idle_day', 'title' => $lang['listsumi'].' '.$lang['stix0013'], 'icon' => 'fas fa-hourglass-half', 'config' => 'stats_column_idle_day_switch'),
- array('option' => 'active_day', 'title' => $lang['listsuma'].' '.$lang['stix0013'], 'icon' => 'fas fa-hourglass-end', 'config' => 'stats_column_active_day_switch'),
- array('option' => 'count_week', 'title' => $lang['listsumo'].' '.$lang['stix0014'], 'icon' => 'fas fa-hourglass-start', 'config' => 'stats_column_online_week_switch'),
- array('option' => 'idle_week', 'title' => $lang['listsumi'].' '.$lang['stix0014'], 'icon' => 'fas fa-hourglass-half', 'config' => 'stats_column_idle_week_switch'),
- array('option' => 'active_week', 'title' => $lang['listsuma'].' '.$lang['stix0014'], 'icon' => 'fas fa-hourglass-end', 'config' => 'stats_column_active_week_switch'),
- array('option' => 'count_month', 'title' => $lang['listsumo'].' '.$lang['stix0015'], 'icon' => 'fas fa-hourglass-start', 'config' => 'stats_column_online_month_switch'),
- array('option' => 'idle_month', 'title' => $lang['listsumi'].' '.$lang['stix0015'], 'icon' => 'fas fa-hourglass-half', 'config' => 'stats_column_idle_month_switch'),
- array('option' => 'active_month', 'title' => $lang['listsuma'].' '.$lang['stix0015'], 'icon' => 'fas fa-hourglass-end', 'config' => 'stats_column_active_month_switch'),
- array('option' => 'grpid', 'title' => $lang['listacsg'], 'icon' => 'fas fa-clipboard-check', 'config' => 'stats_column_current_server_group_switch'),
- array('option' => 'grpidsince', 'title' => $lang['listgrps'], 'icon' => 'fas fa-history', 'config' => 'stats_column_current_group_since_switch'),
- array('option' => 'nextup', 'title' => $lang['listnxup'], 'icon' => 'fas fa-clock', 'config' => 'stats_column_next_rankup_switch'),
- array('option' => 'active', 'title' => $lang['listnxsg'], 'icon' => 'fas fa-clipboard-list', 'config' => 'stats_column_next_server_group_switch')
- );
- return $arr_sort_options;
-}
-
-function start_session($cfg) {
- ini_set('session.cookie_httponly', 1);
- ini_set('session.use_strict_mode', 1);
- ini_set('session.sid_length', 128);
- if(isset($cfg['default_header_xss'])) {
- header("X-XSS-Protection: ".$cfg['default_header_xss']);
- } else {
- header("X-XSS-Protection: 1; mode=block");
- }
- if(!isset($cfg['default_header_contenttyp']) || $cfg['default_header_contenttyp'] == 1) {
- header("X-Content-Type-Options: nosniff");
- }
- if(isset($cfg['default_header_frame']) && $cfg['default_header_frame'] != NULL) {
- header("X-Frame-Options: ".$cfg['default_header_frame']);
- }
-
- if(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == "on") {
- $prot = 'https';
- ini_set('session.cookie_secure', 1);
- if(!headers_sent()) {
- header("Strict-Transport-Security: max-age=31536000; includeSubDomains; preload;");
- }
- } else {
- $prot = 'http';
- }
-
- if(isset($cfg['default_header_origin']) && $cfg['default_header_origin'] != NULL && $cfg['default_header_origin'] != 'null') {
- if(strstr($cfg['default_header_origin'], ',')) {
- $origin_arr = explode(',', $cfg['default_header_origin']);
- if(isset($_SERVER['HTTP_ORIGIN']) && in_array($_SERVER['HTTP_ORIGIN'], $origin_arr)) {
- header("Access-Control-Allow-Origin: ".$_SERVER['HTTP_ORIGIN']);
- }
- } else {
- header("Access-Control-Allow-Origin: ".$cfg['default_header_origin']);
- }
- }
-
- if(version_compare(PHP_VERSION, '7.3.0', '>=')) {
- if(isset($cfg['default_session_sametime'])) {
- ini_set('session.cookie_samesite', $cfg['default_session_sametime']);
- } else {
- ini_set('session.cookie_samesite', "Strict");
- }
- }
-
- session_start();
- return $prot;
-}
-?>
\ No newline at end of file
+ });';
+ }
+
+ return $selectbox;
+}
+
+function set_language($language)
+{
+ if (is_dir($GLOBALS['langpath'])) {
+ foreach (scandir($GLOBALS['langpath']) as $file) {
+ if ('.' === $file || '..' === $file || is_dir($file)) {
+ continue;
+ }
+ $sep_lang = preg_split('/[._]/', $file);
+ if (isset($sep_lang[0]) && $sep_lang[0] == 'core' && isset($sep_lang[1]) && strlen($sep_lang[1]) == 2 && isset($sep_lang[4]) && strtolower($sep_lang[4]) == 'php') {
+ if (strtolower($language) == strtolower($sep_lang[1])) {
+ include $GLOBALS['langpath'].DIRECTORY_SEPARATOR.'/core_'.$sep_lang[1].'_'.$sep_lang[2].'_'.$sep_lang[3].'.'.$sep_lang[4];
+ $_SESSION[get_rspath().'language'] = $sep_lang[1];
+ $required_lang = 1;
+ break;
+ }
+ }
+ }
+ }
+ if (! isset($required_lang)) {
+ include $GLOBALS['langpath'].DIRECTORY_SEPARATOR.'core_en_english_gb.php';
+ }
+
+ return $lang;
+}
+
+function set_session_ts3($mysqlcon, $cfg, $lang, $dbname)
+{
+ $hpclientip = getclientip();
+ $rspathhex = get_rspath();
+
+ $allclients = $mysqlcon->query("SELECT `u`.`uuid`,`u`.`cldbid`,`u`.`name`,`u`.`firstcon`,`s`.`total_connections` FROM `$dbname`.`user` AS `u` LEFT JOIN `$dbname`.`stats_user` AS `s` ON `u`.`uuid`=`s`.`uuid` WHERE `online`='1'")->fetchAll();
+ $iptable = $mysqlcon->query("SELECT `uuid`,`iphash`,`ip` FROM `$dbname`.`user_iphash`")->fetchAll(PDO::FETCH_ASSOC | PDO::FETCH_UNIQUE);
+ if (! isset($_SESSION[$rspathhex.'connected']) && isset($cfg['stats_news_html'])) {
+ $_SESSION[$rspathhex.'stats_news_html'] = $cfg['stats_news_html'];
+ }
+ $_SESSION[$rspathhex.'connected'] = 0;
+ $_SESSION[$rspathhex.'tsname'] = $lang['stag0016'];
+ $_SESSION[$rspathhex.'serverport'] = $cfg['teamspeak_voice_port'];
+ $_SESSION[$rspathhex.'multiple'] = [];
+
+ if ($cfg['rankup_hash_ip_addresses_mode'] == 2) {
+ $salt = md5(dechex(crc32(dirname(__DIR__))));
+ $hashedip = crypt($hpclientip, '$2y$10$'.$salt.'$');
+ }
+
+ foreach ($allclients as $client) {
+ if (isset($_SESSION[$rspathhex.'uuid_verified']) && $_SESSION[$rspathhex.'uuid_verified'] != $client['uuid']) {
+ continue;
+ }
+ $verify = false;
+ if ($cfg['rankup_hash_ip_addresses_mode'] == 1) {
+ if (isset($iptable[$client['uuid']]['iphash']) && $iptable[$client['uuid']]['iphash'] != null && password_verify($hpclientip, $iptable[$client['uuid']]['iphash'])) {
+ $verify = true;
+ }
+ } elseif ($cfg['rankup_hash_ip_addresses_mode'] == 2) {
+ if (isset($iptable[$client['uuid']]['iphash']) && $hashedip == $iptable[$client['uuid']]['iphash'] && $iptable[$client['uuid']]['iphash'] != null) {
+ $verify = true;
+ }
+ } else {
+ if (isset($iptable[$client['uuid']]['ip']) && $hpclientip == $iptable[$client['uuid']]['ip'] && $iptable[$client['uuid']]['ip'] != null) {
+ $verify = true;
+ }
+ }
+ if ($verify == true) {
+ $_SESSION[$rspathhex.'tsname'] = htmlspecialchars($client['name']);
+ if (isset($_SESSION[$rspathhex.'tsuid']) && $_SESSION[$rspathhex.'tsuid'] != $client['uuid']) {
+ $_SESSION[$rspathhex.'multiple'][$client['uuid']] = htmlspecialchars($client['name']);
+ $_SESSION[$rspathhex.'tsname'] = 'verification needed (multiple)!';
+ unset($_SESSION[$rspathhex.'admin']);
+ } elseif (! isset($_SESSION[$rspathhex.'tsuid'])) {
+ $_SESSION[$rspathhex.'multiple'][$client['uuid']] = htmlspecialchars($client['name']);
+ }
+ $_SESSION[$rspathhex.'tsuid'] = $client['uuid'];
+ if (isset($cfg['webinterface_admin_client_unique_id_list']) && $cfg['webinterface_admin_client_unique_id_list'] != null) {
+ foreach (array_flip($cfg['webinterface_admin_client_unique_id_list']) as $auuid) {
+ if ($_SESSION[$rspathhex.'tsuid'] == $auuid) {
+ $_SESSION[$rspathhex.'admin'] = true;
+ }
+ }
+ }
+ $_SESSION[$rspathhex.'tscldbid'] = $client['cldbid'];
+ if ($client['firstcon'] == 0) {
+ $_SESSION[$rspathhex.'tscreated'] = $lang['unknown'];
+ } else {
+ $_SESSION[$rspathhex.'tscreated'] = date('d-m-Y', $client['firstcon']);
+ }
+ if ($client['total_connections'] != null) {
+ $_SESSION[$rspathhex.'tsconnections'] = $client['total_connections'];
+ } else {
+ $_SESSION[$rspathhex.'tsconnections'] = 0;
+ }
+ $convert = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p'];
+ $uuidasbase16 = '';
+ for ($i = 0; $i < 20; $i++) {
+ $char = ord(substr(base64_decode($_SESSION[$rspathhex.'tsuid']), $i, 1));
+ $uuidasbase16 .= $convert[($char & 0xF0) >> 4];
+ $uuidasbase16 .= $convert[$char & 0x0F];
+ }
+ if (is_file('../avatars/'.$uuidasbase16.'.png')) {
+ $_SESSION[$rspathhex.'tsavatar'] = $uuidasbase16.'.png';
+ } else {
+ $_SESSION[$rspathhex.'tsavatar'] = 'none';
+ }
+ $_SESSION[$rspathhex.'connected'] = 1;
+ $_SESSION[$rspathhex.'language'] = $cfg['default_language'];
+ $_SESSION[$rspathhex.'style'] = $cfg['default_style'];
+ }
+ }
+}
+
+function sendmessage($ts3, $cfg, $uuid, $msg, $targetmode, $targetid = null, $erromsg = null, $loglevel = null, $successmsg = null, $nolog = null)
+{
+ try {
+ if (strlen($msg) > 1024) {
+ $fragarr = explode('##*##', wordwrap($msg, 1022, '##*##', true), 1022);
+ foreach ($fragarr as $frag) {
+ usleep($cfg['teamspeak_query_command_delay']);
+ if ($targetmode == 2 && $targetid != null) {
+ $ts3->serverGetSelected()->channelGetById($targetid)->message("\n".$frag);
+ if ($nolog == null) {
+ enter_logfile(6, "sendmessage fragment to channel (ID: $targetid): ".$frag);
+ }
+ } elseif ($targetmode == 3) {
+ $ts3->serverGetSelected()->message("\n".$frag);
+ if ($nolog == null) {
+ enter_logfile(6, 'sendmessage fragment to server: '.$frag);
+ }
+ } elseif ($targetmode == 1 && $targetid != null) {
+ $ts3->serverGetSelected()->clientGetById($targetid)->message("\n".$frag);
+ if ($nolog == null) {
+ enter_logfile(6, "sendmessage fragment to connectionID $targetid (uuid $uuid): ".$frag);
+ }
+ } else {
+ $ts3->serverGetSelected()->clientGetByUid($uuid)->message("\n".$frag);
+ if ($nolog == null) {
+ enter_logfile(6, "sendmessage fragment to uuid $uuid (connectionID $targetid): ".$frag);
+ }
+ }
+ }
+ } else {
+ usleep($cfg['teamspeak_query_command_delay']);
+ if ($targetmode == 2 && $targetid != null) {
+ $ts3->serverGetSelected()->channelGetById($targetid)->message($msg);
+ if ($nolog == null) {
+ enter_logfile(6, "sendmessage to channel (ID: $targetid): ".$msg);
+ }
+ } elseif ($targetmode == 3) {
+ $ts3->serverGetSelected()->message($msg);
+ if ($nolog == null) {
+ enter_logfile(6, 'sendmessage to server: '.$msg);
+ }
+ } elseif ($targetmode == 1 && $targetid != null) {
+ $ts3->serverGetSelected()->clientGetById($targetid)->message($msg);
+ if ($nolog == null) {
+ enter_logfile(6, "sendmessage to connectionID $targetid (uuid $uuid): ".$msg);
+ }
+ } else {
+ $ts3->serverGetSelected()->clientGetByUid($uuid)->message($msg);
+ if ($nolog == null) {
+ enter_logfile(6, "sendmessage to uuid $uuid (connectionID $targetid): ".$msg);
+ }
+ }
+ }
+ if ($successmsg != null) {
+ enter_logfile(5, $successmsg);
+ }
+ } catch (Exception $e) {
+ if ($loglevel != null) {
+ enter_logfile($loglevel, $erromsg.' TS3: '.$e->getCode().': '.$e->getMessage());
+ } else {
+ enter_logfile(3, 'sendmessage: '.$e->getCode().': '.$e->getMessage().", targetmode: $targetmode, targetid: $targetid");
+ }
+ }
+}
+
+function shutdown($mysqlcon, $loglevel, $reason, $nodestroypid = true)
+{
+ if ($nodestroypid === true) {
+ if (file_exists($GLOBALS['pidfile'])) {
+ unlink($GLOBALS['pidfile']);
+ }
+ }
+ if ($nodestroypid === true) {
+ enter_logfile($loglevel, $reason.' Shutting down!');
+ enter_logfile(9, '###################################################################');
+ } else {
+ enter_logfile($loglevel, $reason.' Ignore request!');
+ }
+ if (isset($mysqlcon)) {
+ $mysqlcon = null;
+ }
+ exit;
+}
+
+function sort_channel_tree($channellist)
+{
+ foreach ($channellist as $cid => $results) {
+ $channel['channel_order'][$results['pid']][$results['channel_order']] = $cid;
+ $channel['pid'][$results['pid']][] = $cid;
+ }
+
+ foreach ($channel['pid'] as $pid => $pid_value) {
+ $channel_order = 0;
+ $count_pid = count($pid_value);
+ for ($y = 0; $y < $count_pid; $y++) {
+ foreach ($channellist as $cid => $value) {
+ if (isset($channel['channel_order'][$pid][$channel_order]) && $channel['channel_order'][$pid][$channel_order] == $cid) {
+ $channel['sorted'][$pid][$cid] = $channellist[$cid];
+ $channel_order = $cid;
+ }
+ }
+ }
+ }
+
+ function channel_list($channel, $channel_list, $pid, $sub)
+ {
+ if ($channel['sorted'][$pid]) {
+ foreach ($channel['sorted'][$pid] as $cid => $value) {
+ $channel_list[$cid] = $value;
+ $channel_list[$cid]['sub_level'] = $sub;
+ if (isset($channel['pid'][$cid])) {
+ $sub++;
+ $channel_list[$cid]['has_childs'] = 1;
+ $channel_list = channel_list($channel, $channel_list, $cid, $sub);
+ $sub--;
+ }
+ }
+ }
+
+ return $channel_list;
+ }
+
+ $sorted_channel = channel_list($channel, [], 0, 1);
+
+ return $sorted_channel;
+}
+
+function sort_options($lang)
+{
+ $arr_sort_options = [
+ ['option' => 'rank', 'title' => $lang['listrank'], 'icon' => 'fas fa-hashtag', 'config' => 'stats_column_rank_switch'],
+ ['option' => 'name', 'title' => $lang['listnick'], 'icon' => 'fas fa-user', 'config' => 'stats_column_client_name_switch'],
+ ['option' => 'uuid', 'title' => $lang['listuid'], 'icon' => 'fas fa-id-card', 'config' => 'stats_column_unique_id_switch'],
+ ['option' => 'cldbid', 'title' => $lang['listcldbid'], 'icon' => 'fas fa-database', 'config' => 'stats_column_client_db_id_switch'],
+ ['option' => 'lastseen', 'title' => $lang['listseen'], 'icon' => 'fas fa-user-clock', 'config' => 'stats_column_last_seen_switch'],
+ ['option' => 'nation', 'title' => $lang['listnat'], 'icon' => 'fas fa-globe-europe', 'config' => 'stats_column_nation_switch'],
+ ['option' => 'version', 'title' => $lang['listver'], 'icon' => 'fas fa-tag', 'config' => 'stats_column_version_switch'],
+ ['option' => 'platform', 'title' => $lang['listpla'], 'icon' => 'fas fa-server', 'config' => 'stats_column_platform_switch'],
+ ['option' => 'count', 'title' => $lang['listsumo'], 'icon' => 'fas fa-hourglass-start', 'config' => 'stats_column_online_time_switch'],
+ ['option' => 'idle', 'title' => $lang['listsumi'], 'icon' => 'fas fa-hourglass-end', 'config' => 'stats_column_idle_time_switch'],
+ ['option' => 'active', 'title' => $lang['listsuma'], 'icon' => 'fas fa-hourglass-half', 'config' => 'stats_column_active_time_switch'],
+ ['option' => 'count_day', 'title' => $lang['listsumo'].' '.$lang['stix0013'], 'icon' => 'fas fa-hourglass-start', 'config' => 'stats_column_online_day_switch'],
+ ['option' => 'idle_day', 'title' => $lang['listsumi'].' '.$lang['stix0013'], 'icon' => 'fas fa-hourglass-half', 'config' => 'stats_column_idle_day_switch'],
+ ['option' => 'active_day', 'title' => $lang['listsuma'].' '.$lang['stix0013'], 'icon' => 'fas fa-hourglass-end', 'config' => 'stats_column_active_day_switch'],
+ ['option' => 'count_week', 'title' => $lang['listsumo'].' '.$lang['stix0014'], 'icon' => 'fas fa-hourglass-start', 'config' => 'stats_column_online_week_switch'],
+ ['option' => 'idle_week', 'title' => $lang['listsumi'].' '.$lang['stix0014'], 'icon' => 'fas fa-hourglass-half', 'config' => 'stats_column_idle_week_switch'],
+ ['option' => 'active_week', 'title' => $lang['listsuma'].' '.$lang['stix0014'], 'icon' => 'fas fa-hourglass-end', 'config' => 'stats_column_active_week_switch'],
+ ['option' => 'count_month', 'title' => $lang['listsumo'].' '.$lang['stix0015'], 'icon' => 'fas fa-hourglass-start', 'config' => 'stats_column_online_month_switch'],
+ ['option' => 'idle_month', 'title' => $lang['listsumi'].' '.$lang['stix0015'], 'icon' => 'fas fa-hourglass-half', 'config' => 'stats_column_idle_month_switch'],
+ ['option' => 'active_month', 'title' => $lang['listsuma'].' '.$lang['stix0015'], 'icon' => 'fas fa-hourglass-end', 'config' => 'stats_column_active_month_switch'],
+ ['option' => 'grpid', 'title' => $lang['listacsg'], 'icon' => 'fas fa-clipboard-check', 'config' => 'stats_column_current_server_group_switch'],
+ ['option' => 'grpidsince', 'title' => $lang['listgrps'], 'icon' => 'fas fa-history', 'config' => 'stats_column_current_group_since_switch'],
+ ['option' => 'nextup', 'title' => $lang['listnxup'], 'icon' => 'fas fa-clock', 'config' => 'stats_column_next_rankup_switch'],
+ ['option' => 'active', 'title' => $lang['listnxsg'], 'icon' => 'fas fa-clipboard-list', 'config' => 'stats_column_next_server_group_switch'],
+ ];
+
+ return $arr_sort_options;
+}
+
+function start_session($cfg)
+{
+ ini_set('session.cookie_httponly', 1);
+ ini_set('session.use_strict_mode', 1);
+ ini_set('session.sid_length', 128);
+ if (isset($cfg['default_header_xss'])) {
+ header('X-XSS-Protection: '.$cfg['default_header_xss']);
+ } else {
+ header('X-XSS-Protection: 1; mode=block');
+ }
+ if (! isset($cfg['default_header_contenttyp']) || $cfg['default_header_contenttyp'] == 1) {
+ header('X-Content-Type-Options: nosniff');
+ }
+ if (isset($cfg['default_header_frame']) && $cfg['default_header_frame'] != null) {
+ header('X-Frame-Options: '.$cfg['default_header_frame']);
+ }
+
+ if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') {
+ $prot = 'https';
+ ini_set('session.cookie_secure', 1);
+ if (! headers_sent()) {
+ header('Strict-Transport-Security: max-age=31536000; includeSubDomains; preload;');
+ }
+ } else {
+ $prot = 'http';
+ }
+
+ if (isset($cfg['default_header_origin']) && $cfg['default_header_origin'] != null && $cfg['default_header_origin'] != 'null') {
+ if (strstr($cfg['default_header_origin'], ',')) {
+ $origin_arr = explode(',', $cfg['default_header_origin']);
+ if (isset($_SERVER['HTTP_ORIGIN']) && in_array($_SERVER['HTTP_ORIGIN'], $origin_arr)) {
+ header('Access-Control-Allow-Origin: '.$_SERVER['HTTP_ORIGIN']);
+ }
+ } else {
+ header('Access-Control-Allow-Origin: '.$cfg['default_header_origin']);
+ }
+ }
+
+ if (version_compare(PHP_VERSION, '7.3.0', '>=')) {
+ if (isset($cfg['default_session_sametime'])) {
+ ini_set('session.cookie_samesite', $cfg['default_session_sametime']);
+ } else {
+ ini_set('session.cookie_samesite', 'Strict');
+ }
+ }
+
+ session_start();
+
+ return $prot;
+}
diff --git a/other/config.php b/other/config.php
index 06ad353..d8e54a9 100644
--- a/other/config.php
+++ b/other/config.php
@@ -1,110 +1,118 @@
-query("SELECT * FROM `$dbname`.`cfg_params`"))) {
- if(isset($newcfg) && $newcfg != NULL) {
- $cfg = $newcfg->fetchAll(PDO::FETCH_KEY_PAIR);
- if(empty($cfg['webinterface_admin_client_unique_id_list'])) {
- $cfg['webinterface_admin_client_unique_id_list'] = NULL;
- } else {
- $cfg['webinterface_admin_client_unique_id_list'] = array_flip(explode(',', $cfg['webinterface_admin_client_unique_id_list']));
- }
- if(empty($cfg['rankup_excepted_unique_client_id_list'])) {
- $cfg['rankup_excepted_unique_client_id_list'] = NULL;
- } else {
- $cfg['rankup_excepted_unique_client_id_list'] = array_flip(explode(',', $cfg['rankup_excepted_unique_client_id_list']));
- }
- if(empty($cfg['rankup_excepted_group_id_list'])) {
- $cfg['rankup_excepted_group_id_list'] = NULL;
- } else {
- $cfg['rankup_excepted_group_id_list'] = array_flip(explode(',', $cfg['rankup_excepted_group_id_list']));
- }
- if(empty($cfg['rankup_excepted_channel_id_list'])) {
- $cfg['rankup_excepted_channel_id_list'] = NULL;
- } else {
- $cfg['rankup_excepted_channel_id_list'] = array_flip(explode(',', $cfg['rankup_excepted_channel_id_list']));
- }
- if(empty($cfg['rankup_definition'])) {
- $cfg['rankup_definition'] = NULL;
- } else {
- foreach (explode(',', $cfg['rankup_definition']) as $entry) {
- if(substr_count($entry, '=>') > 1) {
- list($time, $group, $keepflag) = explode('=>', $entry);
- } else {
- list($time, $group) = explode('=>', $entry);
- $keepflag = 0;
- }
- $addnewvalue1[$time] = array("time"=>$time,"group"=>$group,"keep"=>$keepflag);
- $cfg['rankup_definition'] = $addnewvalue1;
- }
- }
- if(empty($cfg['rankup_boost_definition'])) {
- $cfg['rankup_boost_definition'] = NULL;
- } else {
- foreach (explode(',', $cfg['rankup_boost_definition']) as $entry) {
- list($key, $value1, $value2) = explode('=>', $entry);
- $addnewvalue2[$key] = array("group"=>$key,"factor"=>$value1,"time"=>$value2);
- $cfg['rankup_boost_definition'] = $addnewvalue2;
- }
- }
- if(empty($cfg['stats_api_keys'])) {
- $cfg['stats_api_keys'] = NULL;
- } else {
- foreach (explode(',', $cfg['stats_api_keys']) as $entry) {
- list($key, $desc, $perm_bot) = array_pad(explode('=>', $entry), 3, null);
- if(!$perm_bot) $perm_bot = 0;
- $addnewvalue3[$key] = array("key"=>$key,"desc"=>$desc,"perm_bot"=>$perm_bot);
- $cfg['stats_api_keys'] = $addnewvalue3;
- }
- }
- unset($addnewvalue1, $addnewvalue2, $addnewvalue3, $newcfg);
- }
-}
-
-if(empty($cfg['logs_debug_level'])) {
- $GLOBALS['logs_debug_level'] = $cfg['logs_debug_level'] = "5";
-} else {
- $GLOBALS['logs_debug_level'] = $cfg['logs_debug_level'];
-}
-if(empty($cfg['logs_rotation_size'])) {
- $GLOBALS['logs_rotation_size'] = $cfg['logs_rotation_size'] = "5";
-} else {
- $GLOBALS['logs_rotation_size'] = $cfg['logs_rotation_size'];
-}
-
-if(!isset($cfg['logs_path']) || $cfg['logs_path'] == NULL) { $cfg['logs_path'] = dirname(__DIR__).DIRECTORY_SEPARATOR."logs".DIRECTORY_SEPARATOR; }
-if(!isset($cfg['logs_timezone'])) {
- $GLOBALS['logs_timezone'] = "Europe/Berlin";
-} else {
- $GLOBALS['logs_timezone'] = $cfg['logs_timezone'];
-}
-date_default_timezone_set($GLOBALS['logs_timezone']);
-$GLOBALS['logpath'] = $cfg['logs_path'];
-$GLOBALS['logfile'] = $cfg['logs_path'].'ranksystem.log';
-$GLOBALS['pidfile'] = $cfg['logs_path'].'pid';
-$GLOBALS['autostart'] = $cfg['logs_path'].'autostart_deactivated';
-$GLOBALS['langpath'] = dirname(__DIR__).DIRECTORY_SEPARATOR.'languages'.DIRECTORY_SEPARATOR;
-if(!isset($cfg['default_language']) || $cfg['default_language'] == NULL) {
- $GLOBALS['default_language'] = 'en';
-} else {
- $GLOBALS['default_language'] = $cfg['default_language'];
-}
-$GLOBALS['stylepath'] = dirname(__DIR__).DIRECTORY_SEPARATOR.'styles'.DIRECTORY_SEPARATOR;
-if(isset($cfg['default_style'])) $GLOBALS['style'] = get_style($cfg['default_style']);
-$GLOBALS['avatarpath'] = dirname(__DIR__).DIRECTORY_SEPARATOR.'avatars'.DIRECTORY_SEPARATOR;
-
-require_once(__DIR__.DIRECTORY_SEPARATOR.'phpcommand.php');
-$GLOBALS['phpcommand'] = $phpcommand;
-?>
\ No newline at end of file
+query("SELECT * FROM `$dbname`.`cfg_params`"))) {
+ if (isset($newcfg) && $newcfg != null) {
+ $cfg = $newcfg->fetchAll(PDO::FETCH_KEY_PAIR);
+ if (empty($cfg['webinterface_admin_client_unique_id_list'])) {
+ $cfg['webinterface_admin_client_unique_id_list'] = null;
+ } else {
+ $cfg['webinterface_admin_client_unique_id_list'] = array_flip(explode(',', $cfg['webinterface_admin_client_unique_id_list']));
+ }
+ if (empty($cfg['rankup_excepted_unique_client_id_list'])) {
+ $cfg['rankup_excepted_unique_client_id_list'] = null;
+ } else {
+ $cfg['rankup_excepted_unique_client_id_list'] = array_flip(explode(',', $cfg['rankup_excepted_unique_client_id_list']));
+ }
+ if (empty($cfg['rankup_excepted_group_id_list'])) {
+ $cfg['rankup_excepted_group_id_list'] = null;
+ } else {
+ $cfg['rankup_excepted_group_id_list'] = array_flip(explode(',', $cfg['rankup_excepted_group_id_list']));
+ }
+ if (empty($cfg['rankup_excepted_channel_id_list'])) {
+ $cfg['rankup_excepted_channel_id_list'] = null;
+ } else {
+ $cfg['rankup_excepted_channel_id_list'] = array_flip(explode(',', $cfg['rankup_excepted_channel_id_list']));
+ }
+ if (empty($cfg['rankup_definition'])) {
+ $cfg['rankup_definition'] = null;
+ } else {
+ foreach (explode(',', $cfg['rankup_definition']) as $entry) {
+ if (substr_count($entry, '=>') > 1) {
+ list($time, $group, $keepflag) = explode('=>', $entry);
+ } else {
+ list($time, $group) = explode('=>', $entry);
+ $keepflag = 0;
+ }
+ $addnewvalue1[$time] = ['time'=>$time, 'group'=>$group, 'keep'=>$keepflag];
+ $cfg['rankup_definition'] = $addnewvalue1;
+ }
+ }
+ if (empty($cfg['rankup_boost_definition'])) {
+ $cfg['rankup_boost_definition'] = null;
+ } else {
+ foreach (explode(',', $cfg['rankup_boost_definition']) as $entry) {
+ list($key, $value1, $value2) = explode('=>', $entry);
+ $addnewvalue2[$key] = ['group'=>$key, 'factor'=>$value1, 'time'=>$value2];
+ $cfg['rankup_boost_definition'] = $addnewvalue2;
+ }
+ }
+ if (empty($cfg['stats_api_keys'])) {
+ $cfg['stats_api_keys'] = null;
+ } else {
+ foreach (explode(',', $cfg['stats_api_keys']) as $entry) {
+ list($key, $desc, $perm_bot) = array_pad(explode('=>', $entry), 3, null);
+ if (! $perm_bot) {
+ $perm_bot = 0;
+ }
+ $addnewvalue3[$key] = ['key'=>$key, 'desc'=>$desc, 'perm_bot'=>$perm_bot];
+ $cfg['stats_api_keys'] = $addnewvalue3;
+ }
+ }
+ unset($addnewvalue1, $addnewvalue2, $addnewvalue3, $newcfg);
+ }
+}
+
+if (empty($cfg['logs_debug_level'])) {
+ $GLOBALS['logs_debug_level'] = $cfg['logs_debug_level'] = '5';
+} else {
+ $GLOBALS['logs_debug_level'] = $cfg['logs_debug_level'];
+}
+if (empty($cfg['logs_rotation_size'])) {
+ $GLOBALS['logs_rotation_size'] = $cfg['logs_rotation_size'] = '5';
+} else {
+ $GLOBALS['logs_rotation_size'] = $cfg['logs_rotation_size'];
+}
+
+if (! isset($cfg['logs_path']) || $cfg['logs_path'] == null) {
+ $cfg['logs_path'] = dirname(__DIR__).DIRECTORY_SEPARATOR.'logs'.DIRECTORY_SEPARATOR;
+}
+if (! isset($cfg['logs_timezone'])) {
+ $GLOBALS['logs_timezone'] = 'Europe/Berlin';
+} else {
+ $GLOBALS['logs_timezone'] = $cfg['logs_timezone'];
+}
+date_default_timezone_set($GLOBALS['logs_timezone']);
+$GLOBALS['logpath'] = $cfg['logs_path'];
+$GLOBALS['logfile'] = $cfg['logs_path'].'ranksystem.log';
+$GLOBALS['pidfile'] = $cfg['logs_path'].'pid';
+$GLOBALS['autostart'] = $cfg['logs_path'].'autostart_deactivated';
+$GLOBALS['langpath'] = dirname(__DIR__).DIRECTORY_SEPARATOR.'languages'.DIRECTORY_SEPARATOR;
+if (! isset($cfg['default_language']) || $cfg['default_language'] == null) {
+ $GLOBALS['default_language'] = 'en';
+} else {
+ $GLOBALS['default_language'] = $cfg['default_language'];
+}
+$GLOBALS['stylepath'] = dirname(__DIR__).DIRECTORY_SEPARATOR.'styles'.DIRECTORY_SEPARATOR;
+if (isset($cfg['default_style'])) {
+ $GLOBALS['style'] = get_style($cfg['default_style']);
+}
+$GLOBALS['avatarpath'] = dirname(__DIR__).DIRECTORY_SEPARATOR.'avatars'.DIRECTORY_SEPARATOR;
+
+require_once __DIR__.DIRECTORY_SEPARATOR.'phpcommand.php';
+$GLOBALS['phpcommand'] = $phpcommand;
diff --git a/other/dbconfig.php b/other/dbconfig.php
index 16e07a2..c0b3e9e 100644
--- a/other/dbconfig.php
+++ b/other/dbconfig.php
@@ -1,7 +1,7 @@
\ No newline at end of file
+
+$db['type'] = 'type';
+$db['host'] = 'hostname';
+$db['user'] = 'dbuser';
+$db['pass'] = 'dbpass';
+$db['dbname'] = 'ts3_ranksystem';
diff --git a/other/load_addons_config.php b/other/load_addons_config.php
index 02209f0..4b66577 100644
--- a/other/load_addons_config.php
+++ b/other/load_addons_config.php
@@ -1,14 +1,15 @@
-query("SELECT * FROM `$dbname`.`addons_config`")) === false) {
- if(function_exists('enter_logfile')) {
- enter_logfile($cfg,2,"Error on loading addons config.. Database down, not reachable, corrupt or empty?");
- } else {
- echo 'Error on loading addons config..
Check:
- You have already installed the Ranksystem? Run
install.php first!
- Is the database reachable?
- You have installed all needed PHP extenstions? Have a look here for
Windows or
Linux ?';
- }
- } else {
- return $addons_config->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_UNIQUE|PDO::FETCH_ASSOC);
- }
- //$addons_config['assign_groups_groupids']['value'];
-}
-?>
\ No newline at end of file
+query("SELECT * FROM `$dbname`.`addons_config`")) === false) {
+ if (function_exists('enter_logfile')) {
+ enter_logfile($cfg, 2, 'Error on loading addons config.. Database down, not reachable, corrupt or empty?');
+ } else {
+ echo 'Error on loading addons config..
Check:
- You have already installed the Ranksystem? Run
install.php first!
- Is the database reachable?
- You have installed all needed PHP extenstions? Have a look here for
Windows or
Linux ?';
+ }
+ } else {
+ return $addons_config->fetchAll(PDO::FETCH_GROUP | PDO::FETCH_UNIQUE | PDO::FETCH_ASSOC);
+ }
+ //$addons_config['assign_groups_groupids']['value'];
+}
diff --git a/other/phpcommand.php b/other/phpcommand.php
index 5c3f899..99a3a58 100644
--- a/other/phpcommand.php
+++ b/other/phpcommand.php
@@ -1,30 +1,30 @@
- \" <-- at the beginning and end of the path, see example below
-#$phpcommand = '\"C:\Program Files (x86)\PHP\php.exe\"';
-#$phpcommand = '\"C:\Program Files (x86)\Plesk\Additional\PHP73\php.exe\"';
-##
-##
-## OTHER
-## Synology NAS
-#$phpcommand = '/volume1/@appstore/PHP7.2/usr/local/bin/php72';
-?>
\ No newline at end of file
+//#
+//# LINUX
+//$phpcommand = 'php74';
+//$phpcommand = '/usr/bin/php7.3';
+//$phpcommand = '/usr/bin/php7.4';
+//$phpcommand = '/opt/plesk/php/7.3/bin/php';
+//$phpcommand = '/opt/plesk/php/7.4/bin/php';
+//#
+//#
+//# WINDOWS
+//$phpcommand = 'C:\PHP7\php.exe';
+//$phpcommand = 'C:\wamp\bin\php\php.exe';
+//$phpcommand = 'C:\xampp\php80\php.exe';
+// On blanks or special characters inside the path, you need to escape these with special marks --> \" <-- at the beginning and end of the path, see example below
+//$phpcommand = '\"C:\Program Files (x86)\PHP\php.exe\"';
+//$phpcommand = '\"C:\Program Files (x86)\Plesk\Additional\PHP73\php.exe\"';
+//#
+//#
+//# OTHER
+//# Synology NAS
+//$phpcommand = '/volume1/@appstore/PHP7.2/usr/local/bin/php72';
diff --git a/other/session_handling.php b/other/session_handling.php
index 0e93232..631ce9a 100644
--- a/other/session_handling.php
+++ b/other/session_handling.php
@@ -1,10 +1,10 @@
-
\ No newline at end of file
+
',$lang['imprint'],' ';
- } else {
- echo '
';
+
',$lang['imprint'],' ';
+ } else {
+ echo '
';
}
-?>
\ No newline at end of file
diff --git a/stats/_nav.php b/stats/_nav.php
index ff5d723..7145cb2 100644
--- a/stats/_nav.php
+++ b/stats/_nav.php
@@ -1,188 +1,189 @@
-query("SELECT * FROM `$dbname`.`job_check`")->fetchAll(PDO::FETCH_UNIQUE|PDO::FETCH_ASSOC);
-if((time() - $job_check['last_update']['timestamp']) < 259200 && !isset($_SESSION[$rspathhex.'upinfomsg'])) {
- if(!isset($err_msg)) {
- $err_msg = '
'.sprintf($lang['upinf2'], date("Y-m-d H:i",$job_check['last_update']['timestamp']), ' ', ' '); $err_lvl = 1;
- $_SESSION[$rspathhex.'upinfomsg'] = 1;
- }
-}
-
-if(isset($_POST['username'])) {
- $_GET["search"] = $_POST['usersuche'];
- $_GET["seite"] = 1;
-}
-$filter = $searchstring = NULL;
-if(isset($_GET["search"]) && $_GET["search"] != '') {
- $getstring = htmlspecialchars($_GET['search']);
-}
-if(isset($getstring) && strstr($getstring, 'filter:excepted:')) {
- if(str_replace('filter:excepted:','',$getstring)!='') {
- $searchstring = str_replace('filter:excepted:','',$getstring);
- }
- $filter .= " AND `except` IN ('2','3')";
-} elseif(isset($getstring) && strstr($getstring, 'filter:nonexcepted:')) {
- if(str_replace('filter:nonexcepted:','',$getstring)!='') {
- $searchstring = str_replace('filter:nonexcepted:','',$getstring);
- }
- $filter .= " AND `except` IN ('0','1')";
-} else {
- if(isset($getstring)) {
- $searchstring = $getstring;
- } else {
- $searchstring = '';
- }
- if($cfg['stats_show_excepted_clients_switch'] == 0) {
- $filter .= " AND `except` IN ('0','1')";
- }
-}
-if(isset($getstring) && strstr($getstring, 'filter:online:')) {
- $searchstring = preg_replace('/filter\:online\:/','',$searchstring);
- $filter .= " AND `online`='1'";
-} elseif(isset($getstring) && strstr($getstring, 'filter:nononline:')) {
- $searchstring = preg_replace('/filter\:nononline\:/','',$searchstring);
- $filter .= " AND `online`='0'";
-}
-if(isset($getstring) && strstr($getstring, 'filter:actualgroup:')) {
- preg_match('/filter\:actualgroup\:(.*)\:/',$searchstring,$grpvalue);
- $searchstring = preg_replace('/filter\:actualgroup\:(.*)\:/','',$searchstring);
- $filter .= " AND `grpid`='".$grpvalue[1]."'";
-}
-if(isset($getstring) && strstr($getstring, 'filter:country:')) {
- preg_match('/filter\:country\:(.*)\:/',$searchstring,$grpvalue);
- $searchstring = preg_replace('/filter\:country\:(.*)\:/','',$searchstring);
- $filter .= " AND `nation`='".$grpvalue[1]."'";
-}
-if(isset($getstring) && strstr($getstring, 'filter:lastseen:')) {
- preg_match('/filter\:lastseen\:(.*)\:(.*)\:/',$searchstring,$seenvalue);
- $searchstring = preg_replace('/filter\:lastseen\:(.*)\:(.*)\:/','',$searchstring);
- if(isset($seenvalue[2]) && is_numeric($seenvalue[2])) {
- $lastseen = $seenvalue[2];
- } elseif(isset($seenvalue[2])) {
- $r = date_parse_from_format("Y-m-d H-i",$seenvalue[2]);
- $lastseen = mktime($r['hour'], $r['minute'], $r['second'], $r['month'], $r['day'], $r['year']);
- } else {
- $lastseen = 0;
- }
- if(isset($seenvalue[1]) && ($seenvalue[1] == '<' || $seenvalue[1] == '<')) {
- $operator = '<';
- } elseif(isset($seenvalue[1]) && ($seenvalue[1] == '>' || $seenvalue[1] == '>')) {
- $operator = '>';
- } elseif(isset($seenvalue[1]) && $seenvalue[1] == '!=') {
- $operator = '!=';
- } else {
- $operator = '=';
- }
- $filter .= " AND `lastseen`".$operator."'".$lastseen."'";
-}
-$searchstring = htmlspecialchars_decode($searchstring);
-
-if(isset($getstring)) {
- $dbdata_full = $mysqlcon->prepare("SELECT COUNT(*) FROM `$dbname`.`user` WHERE (`uuid` LIKE :searchvalue OR `cldbid` LIKE :searchvalue OR `name` LIKE :searchvalue)$filter");
- $dbdata_full->bindValue(':searchvalue', '%'.$searchstring.'%', PDO::PARAM_STR);
- $dbdata_full->execute();
- $sumentries = $dbdata_full->fetch(PDO::FETCH_NUM);
- $getstring = rawurlencode($getstring);
-} else {
- $getstring = '';
- $sumentries = $mysqlcon->query("SELECT COUNT(*) FROM `$dbname`.`user`")->fetch(PDO::FETCH_NUM);
-}
-
-if(!isset($_GET["seite"])) {
- $seite = 1;
-} else {
- $_GET["seite"] = preg_replace('/\D/', '', $_GET["seite"]);
- if($_GET["seite"] > 0) {
- $seite = $_GET["seite"];
- } else {
- $seite = 1;
- }
-}
-$adminlogin = 0;
-$sortarr = array_flip(array("active","cldbid","count","grpid","grpsince","idle","lastseen","name","nation","nextup","platform","rank","uuid","version","count_day","count_week","count_month","idle_day","idle_week","idle_month","active_day","active_week","active_month"));
-
-if(isset($_GET['sort']) && isset($sortarr[$_GET['sort']])) {
- $keysort = $_GET['sort'];
-} else {
- $keysort = $cfg['stats_column_default_sort'];
-}
-if(isset($_GET['order']) && $_GET['order'] == 'desc') {
- $keyorder = 'desc';
-} elseif(isset($_GET['order']) && $_GET['order'] == 'asc') {
- $keyorder = 'asc';
-} else {
- $keyorder = $cfg['stats_column_default_order'];
-}
-
-if(isset($_GET['admin'])) {
- if(hash_equals($_SESSION[$rspathhex.'username'], $cfg['webinterface_user']) && hash_equals($_SESSION[$rspathhex.'password'], $cfg['webinterface_pass']) && hash_equals($_SESSION[$rspathhex.'clientip'], getclientip())) {
- $adminlogin = 1;
- }
-}
-
-if(!isset($_GET["user"])) {
- $user_pro_seite = 25;
-} elseif($_GET['user'] == "all") {
- if($sumentries[0] > 1000) {
- $user_pro_seite = 1000;
- } else {
- $user_pro_seite = $sumentries[0];
- }
-} else {
- $_GET["user"] = preg_replace('/\D/', '', $_GET["user"]);
- if($_GET["user"] > 1000) {
- $user_pro_seite = 1000;
- } elseif($_GET["user"] > 0) {
- $user_pro_seite = $_GET["user"];
- } else {
- $user_pro_seite = 25;
- }
-}
-?>
+query("SELECT * FROM `$dbname`.`job_check`")->fetchAll(PDO::FETCH_UNIQUE | PDO::FETCH_ASSOC);
+if ((time() - $job_check['last_update']['timestamp']) < 259200 && ! isset($_SESSION[$rspathhex.'upinfomsg'])) {
+ if (! isset($err_msg)) {
+ $err_msg = '
'.sprintf($lang['upinf2'], date('Y-m-d H:i', $job_check['last_update']['timestamp']), ' ', ' ');
+ $err_lvl = 1;
+ $_SESSION[$rspathhex.'upinfomsg'] = 1;
+ }
+}
+
+if (isset($_POST['username'])) {
+ $_GET['search'] = $_POST['usersuche'];
+ $_GET['seite'] = 1;
+}
+$filter = $searchstring = null;
+if (isset($_GET['search']) && $_GET['search'] != '') {
+ $getstring = htmlspecialchars($_GET['search']);
+}
+if (isset($getstring) && strstr($getstring, 'filter:excepted:')) {
+ if (str_replace('filter:excepted:', '', $getstring) != '') {
+ $searchstring = str_replace('filter:excepted:', '', $getstring);
+ }
+ $filter .= " AND `except` IN ('2','3')";
+} elseif (isset($getstring) && strstr($getstring, 'filter:nonexcepted:')) {
+ if (str_replace('filter:nonexcepted:', '', $getstring) != '') {
+ $searchstring = str_replace('filter:nonexcepted:', '', $getstring);
+ }
+ $filter .= " AND `except` IN ('0','1')";
+} else {
+ if (isset($getstring)) {
+ $searchstring = $getstring;
+ } else {
+ $searchstring = '';
+ }
+ if ($cfg['stats_show_excepted_clients_switch'] == 0) {
+ $filter .= " AND `except` IN ('0','1')";
+ }
+}
+if (isset($getstring) && strstr($getstring, 'filter:online:')) {
+ $searchstring = preg_replace('/filter\:online\:/', '', $searchstring);
+ $filter .= " AND `online`='1'";
+} elseif (isset($getstring) && strstr($getstring, 'filter:nononline:')) {
+ $searchstring = preg_replace('/filter\:nononline\:/', '', $searchstring);
+ $filter .= " AND `online`='0'";
+}
+if (isset($getstring) && strstr($getstring, 'filter:actualgroup:')) {
+ preg_match('/filter\:actualgroup\:(.*)\:/', $searchstring, $grpvalue);
+ $searchstring = preg_replace('/filter\:actualgroup\:(.*)\:/', '', $searchstring);
+ $filter .= " AND `grpid`='".$grpvalue[1]."'";
+}
+if (isset($getstring) && strstr($getstring, 'filter:country:')) {
+ preg_match('/filter\:country\:(.*)\:/', $searchstring, $grpvalue);
+ $searchstring = preg_replace('/filter\:country\:(.*)\:/', '', $searchstring);
+ $filter .= " AND `nation`='".$grpvalue[1]."'";
+}
+if (isset($getstring) && strstr($getstring, 'filter:lastseen:')) {
+ preg_match('/filter\:lastseen\:(.*)\:(.*)\:/', $searchstring, $seenvalue);
+ $searchstring = preg_replace('/filter\:lastseen\:(.*)\:(.*)\:/', '', $searchstring);
+ if (isset($seenvalue[2]) && is_numeric($seenvalue[2])) {
+ $lastseen = $seenvalue[2];
+ } elseif (isset($seenvalue[2])) {
+ $r = date_parse_from_format('Y-m-d H-i', $seenvalue[2]);
+ $lastseen = mktime($r['hour'], $r['minute'], $r['second'], $r['month'], $r['day'], $r['year']);
+ } else {
+ $lastseen = 0;
+ }
+ if (isset($seenvalue[1]) && ($seenvalue[1] == '<' || $seenvalue[1] == '<')) {
+ $operator = '<';
+ } elseif (isset($seenvalue[1]) && ($seenvalue[1] == '>' || $seenvalue[1] == '>')) {
+ $operator = '>';
+ } elseif (isset($seenvalue[1]) && $seenvalue[1] == '!=') {
+ $operator = '!=';
+ } else {
+ $operator = '=';
+ }
+ $filter .= ' AND `lastseen`'.$operator."'".$lastseen."'";
+}
+$searchstring = htmlspecialchars_decode($searchstring);
+
+if (isset($getstring)) {
+ $dbdata_full = $mysqlcon->prepare("SELECT COUNT(*) FROM `$dbname`.`user` WHERE (`uuid` LIKE :searchvalue OR `cldbid` LIKE :searchvalue OR `name` LIKE :searchvalue)$filter");
+ $dbdata_full->bindValue(':searchvalue', '%'.$searchstring.'%', PDO::PARAM_STR);
+ $dbdata_full->execute();
+ $sumentries = $dbdata_full->fetch(PDO::FETCH_NUM);
+ $getstring = rawurlencode($getstring);
+} else {
+ $getstring = '';
+ $sumentries = $mysqlcon->query("SELECT COUNT(*) FROM `$dbname`.`user`")->fetch(PDO::FETCH_NUM);
+}
+
+if (! isset($_GET['seite'])) {
+ $seite = 1;
+} else {
+ $_GET['seite'] = preg_replace('/\D/', '', $_GET['seite']);
+ if ($_GET['seite'] > 0) {
+ $seite = $_GET['seite'];
+ } else {
+ $seite = 1;
+ }
+}
+$adminlogin = 0;
+$sortarr = array_flip(['active', 'cldbid', 'count', 'grpid', 'grpsince', 'idle', 'lastseen', 'name', 'nation', 'nextup', 'platform', 'rank', 'uuid', 'version', 'count_day', 'count_week', 'count_month', 'idle_day', 'idle_week', 'idle_month', 'active_day', 'active_week', 'active_month']);
+
+if (isset($_GET['sort']) && isset($sortarr[$_GET['sort']])) {
+ $keysort = $_GET['sort'];
+} else {
+ $keysort = $cfg['stats_column_default_sort'];
+}
+if (isset($_GET['order']) && $_GET['order'] == 'desc') {
+ $keyorder = 'desc';
+} elseif (isset($_GET['order']) && $_GET['order'] == 'asc') {
+ $keyorder = 'asc';
+} else {
+ $keyorder = $cfg['stats_column_default_order'];
+}
+
+if (isset($_GET['admin'])) {
+ if (hash_equals($_SESSION[$rspathhex.'username'], $cfg['webinterface_user']) && hash_equals($_SESSION[$rspathhex.'password'], $cfg['webinterface_pass']) && hash_equals($_SESSION[$rspathhex.'clientip'], getclientip())) {
+ $adminlogin = 1;
+ }
+}
+
+if (! isset($_GET['user'])) {
+ $user_pro_seite = 25;
+} elseif ($_GET['user'] == 'all') {
+ if ($sumentries[0] > 1000) {
+ $user_pro_seite = 1000;
+ } else {
+ $user_pro_seite = $sumentries[0];
+ }
+} else {
+ $_GET['user'] = preg_replace('/\D/', '', $_GET['user']);
+ if ($_GET['user'] > 1000) {
+ $user_pro_seite = 1000;
+ } elseif ($_GET['user'] > 0) {
+ $user_pro_seite = $_GET['user'];
+ } else {
+ $user_pro_seite = 25;
+ }
+}
+?>
-
+
-
+
TSN Ranksystem - ts-ranksystem.com
-
-';
- }
- switch(basename($_SERVER['SCRIPT_NAME'])) {
- case "index.php":
- ?>
-
-
-
-
-
-
+
+';
+ }
+ switch(basename($_SERVER['SCRIPT_NAME'])) {
+ case 'index.php':
+ ?>
+
+
+
+
+
+
- ';
- }
- if(isset($cfg['stats_show_site_navigation_switch']) && $cfg['stats_show_site_navigation_switch'] == 0) { ?>
-
+ ';
+ }
+ if (isset($cfg['stats_show_site_navigation_switch']) && $cfg['stats_show_site_navigation_switch'] == 0) { ?>
+
@@ -221,16 +222,16 @@
@@ -241,14 +242,14 @@
@@ -258,17 +259,17 @@
@@ -281,43 +282,43 @@
Filter options - Search function
-
-
-
-
-
+
+
+
+
+
filter:excepted:
-
+
filter:nonexcepted:
-
+
filter:online:
-
+
filter:nononline:
-
+
filter:actualgroup:GROUPID :
-
+
filter:country:TS3-COUNTRY-CODE :
-
+
filter:lastseen:OPERATOR :TIME :
-
+
-
+
-
+
@@ -326,145 +327,153 @@
-
+
-
+
-
- ' : '>'); ?>
-
+ ' : '>'); ?>
+
- ' : '>'); ?>
-
+ ' : '>'); ?>
+
- ' : '>'); ?>
-
-
+ ' : '>'); ?>
+
+
-
- ' : 'collapse">'); ?>
- ' : '>'); ?>
-
+
+ ' : 'collapse">'); ?>
+ ' : '>'); ?>
+
- ' : '>'); ?>
-
+ ' : '>'); ?>
+
- ' : '>'); ?>
-
+ ' : '>'); ?>
+
- ' : '>'); ?>
-
+ ' : '>'); ?>
+
- ' : '>'); ?>
-
+ ' : '>'); ?>
+
-';
- }
+';
+ }
?>
\ No newline at end of file
diff --git a/stats/_preload.php b/stats/_preload.php
index 8ba1f13..3397668 100644
--- a/stats/_preload.php
+++ b/stats/_preload.php
@@ -1,27 +1,28 @@
-
\ No newline at end of file
+
This addon is (currently) disabled! ';
- exit;
- }
-
- if(isset($_SESSION[$rspathhex.'tsuid'])) {
- $uuid = $_SESSION[$rspathhex.'tsuid'];
- } else {
- $uuid = "no_uuid_found";
- }
- if(($dbdata = $mysqlcon->query("SELECT `cldgroup` FROM `$dbname`.`user` WHERE `uuid`='$uuid'")->fetch()) === false) {
- $err_msg = print_r($mysqlcon->errorInfo(), true); $err_lvl = 3;
- }
- $cld_groups = array();
- if(isset($dbdata['cldgroup']) && $dbdata['cldgroup'] != '') {
- $cld_groups = explode(',', $dbdata['cldgroup']);
- }
-
- $disabled = '';
- $allowed_groups_arr = array();
-
- $csrf_token = bin2hex(openssl_random_pseudo_bytes(32));
-
- if ($mysqlcon->exec("INSERT INTO `$dbname`.`csrf_token` (`token`,`timestamp`,`sessionid`) VALUES ('$csrf_token','".time()."','".session_id()."')") === false) {
- $err_msg = print_r($mysqlcon->errorInfo(), true);
- $err_lvl = 3;
- }
-
- if (($db_csrf = $mysqlcon->query("SELECT * FROM `$dbname`.`csrf_token` WHERE `sessionid`='".session_id()."'")->fetchALL(PDO::FETCH_UNIQUE|PDO::FETCH_ASSOC)) === false) {
- $err_msg = print_r($mysqlcon->errorInfo(), true);
- $err_lvl = 3;
- }
-
- if(($sqlhisgroup = $mysqlcon->query("SELECT * FROM `$dbname`.`groups`")->fetchAll(PDO::FETCH_ASSOC|PDO::FETCH_UNIQUE)) === false) {
- $err_msg = print_r($mysqlcon->errorInfo(), true); $err_lvl = 3;
- }
-
- if(count($_SESSION[$rspathhex.'multiple']) > 1 and !isset($_SESSION[$rspathhex.'uuid_verified'])) {
- $disabled = 1;
- $err_msg = sprintf($lang['stag0006'], '
', ' '); $err_lvl = 3;
- } elseif ($_SESSION[$rspathhex.'connected'] == 0) {
- $err_msg = sprintf($lang['stag0015'], '
', ' '); $err_lvl = 3;
- $disabled = 1;
- } else {
-
-
- $name = explode(';',$addons_config['assign_groups_name']['value']);
- $alwgr = explode(';',$addons_config['assign_groups_groupids']['value']);
- $limit = explode(';',$addons_config['assign_groups_limit']['value']);
- $excgr = explode(';',$addons_config['assign_groups_excepted_groupids']['value']);
-
- if(isset($_POST['update']) && isset($db_csrf[$_POST['csrf_token']])) {
- if(($sumentries = $mysqlcon->query("SELECT COUNT(*) FROM `$dbname`.`addon_assign_groups` WHERE `uuid`='$uuid'")->fetch(PDO::FETCH_NUM)) === false) {
- $err_msg = print_r($mysqlcon->errorInfo(), true); $err_lvl = 3;
- } else {
- if($sumentries[0] > 0) {
- $err_msg = $lang['stag0007']; $err_lvl = 3;
- } else {
- $set_groups = $err_msg = '';
- $limit_raised = $excepted = 0;
-
- foreach($alwgr as $rowid => $value) {
- $count_limit = $changed_group = 0;
-
- $allowed_groups_arr = explode(',', $alwgr[$rowid]);
- $excepted_groups_arr = explode(',', $excgr[$rowid]);
-
- foreach($allowed_groups_arr as $allowed_group) {
- if(in_array($allowed_group, $cld_groups)) {
- $count_limit++;
- }
- if(isset($_POST[$allowed_group]) && $_POST[$allowed_group] == 1 && !in_array($allowed_group, $cld_groups)) {
- $set_groups .= $allowed_group.',';
- array_push($cld_groups, $allowed_group);
- $count_limit++;
- $changed_group++;
- }
- if(!isset($_POST[$allowed_group]) && in_array($allowed_group, $cld_groups)) {
- $set_groups .= '-'.$allowed_group.',';
- $position = array_search($allowed_group, $cld_groups);
- array_splice($cld_groups, $position, 1);
- $count_limit--;
- $changed_group++;
- }
- }
-
- if(isset($excepted_groups_arr) && $excepted_groups_arr != '') {
- foreach($excepted_groups_arr as $excepted_group) {
- if(in_array($excepted_group, $cld_groups) && $changed_group != 0) {
- $excepted++;
- if($err_msg != '') {
- $err_msg .= '#####';
- $err_lvl .= '#3';
- } else {
- $err_lvl = 3;
- }
- $err_msg .= "
".$name[$rowid]." ".sprintf($lang['stag0019'], $sqlhisgroup[$excepted_group]['sgidname'], $excepted_group);
- break;
- }
- }
- }
-
- if($set_groups != '' && $count_limit > $limit[$rowid]) {
- if($err_msg != '') {
- $err_msg .= '#####';
- $err_lvl .= '#3';
- } else {
- $err_lvl = 3;
- }
- $err_msg .= "
".$name[$rowid]." ".sprintf($lang['stag0009'], $limit[$rowid]);
- $limit_raised = 1;
- }
- }
- $set_groups = substr($set_groups, 0, -1);
-
- if($set_groups != '' && $limit_raised == 0 && $excepted == 0) {
- if ($mysqlcon->exec("INSERT INTO `$dbname`.`addon_assign_groups` SET `uuid`='$uuid',`grpids`='$set_groups'; DELETE FROM `$dbname`.`csrf_token` WHERE `token`='{$_POST['csrf_token']}'") === false) {
- $err_msg = $lang['isntwidbmsg'].print_r($mysqlcon->errorInfo(), true); $err_lvl = 3;
- } elseif($mysqlcon->exec("UPDATE `$dbname`.`job_check` SET `timestamp`=1 WHERE `job_name`='reload_trigger'; ") === false) {
- $err_msg = $lang['isntwidbmsg'].print_r($mysqlcon->errorInfo(), true); $err_lvl = 3;
- } else {
- $err_msg = $lang['stag0008']; $err_lvl = NULL;
- }
- } elseif($limit_raised != 0) {
- #message above generated
- } elseif($excepted > 0) {
- #message above generated
- } else {
- $err_msg = $lang['stag0010']; $err_lvl = 3;
- }
- }
- }
- } elseif(isset($_POST['update'])) {
- echo '
',$lang['errcsrf'],'
';
- rem_session_ts3();
- exit;
- }
- }
- ?>
+
This addon is (currently) disabled! ';
+ exit;
+ }
+
+ if (isset($_SESSION[$rspathhex.'tsuid'])) {
+ $uuid = $_SESSION[$rspathhex.'tsuid'];
+ } else {
+ $uuid = 'no_uuid_found';
+ }
+ if (($dbdata = $mysqlcon->query("SELECT `cldgroup` FROM `$dbname`.`user` WHERE `uuid`='$uuid'")->fetch()) === false) {
+ $err_msg = print_r($mysqlcon->errorInfo(), true);
+ $err_lvl = 3;
+ }
+ $cld_groups = [];
+ if (isset($dbdata['cldgroup']) && $dbdata['cldgroup'] != '') {
+ $cld_groups = explode(',', $dbdata['cldgroup']);
+ }
+
+ $disabled = '';
+ $allowed_groups_arr = [];
+
+ $csrf_token = bin2hex(openssl_random_pseudo_bytes(32));
+
+ if ($mysqlcon->exec("INSERT INTO `$dbname`.`csrf_token` (`token`,`timestamp`,`sessionid`) VALUES ('$csrf_token','".time()."','".session_id()."')") === false) {
+ $err_msg = print_r($mysqlcon->errorInfo(), true);
+ $err_lvl = 3;
+ }
+
+ if (($db_csrf = $mysqlcon->query("SELECT * FROM `$dbname`.`csrf_token` WHERE `sessionid`='".session_id()."'")->fetchALL(PDO::FETCH_UNIQUE | PDO::FETCH_ASSOC)) === false) {
+ $err_msg = print_r($mysqlcon->errorInfo(), true);
+ $err_lvl = 3;
+ }
+
+ if (($sqlhisgroup = $mysqlcon->query("SELECT * FROM `$dbname`.`groups`")->fetchAll(PDO::FETCH_ASSOC | PDO::FETCH_UNIQUE)) === false) {
+ $err_msg = print_r($mysqlcon->errorInfo(), true);
+ $err_lvl = 3;
+ }
+
+ if (count($_SESSION[$rspathhex.'multiple']) > 1 and ! isset($_SESSION[$rspathhex.'uuid_verified'])) {
+ $disabled = 1;
+ $err_msg = sprintf($lang['stag0006'], '
', ' ');
+ $err_lvl = 3;
+ } elseif ($_SESSION[$rspathhex.'connected'] == 0) {
+ $err_msg = sprintf($lang['stag0015'], '
', ' ');
+ $err_lvl = 3;
+ $disabled = 1;
+ } else {
+ $name = explode(';', $addons_config['assign_groups_name']['value']);
+ $alwgr = explode(';', $addons_config['assign_groups_groupids']['value']);
+ $limit = explode(';', $addons_config['assign_groups_limit']['value']);
+ $excgr = explode(';', $addons_config['assign_groups_excepted_groupids']['value']);
+
+ if (isset($_POST['update']) && isset($db_csrf[$_POST['csrf_token']])) {
+ if (($sumentries = $mysqlcon->query("SELECT COUNT(*) FROM `$dbname`.`addon_assign_groups` WHERE `uuid`='$uuid'")->fetch(PDO::FETCH_NUM)) === false) {
+ $err_msg = print_r($mysqlcon->errorInfo(), true);
+ $err_lvl = 3;
+ } else {
+ if ($sumentries[0] > 0) {
+ $err_msg = $lang['stag0007'];
+ $err_lvl = 3;
+ } else {
+ $set_groups = $err_msg = '';
+ $limit_raised = $excepted = 0;
+
+ foreach ($alwgr as $rowid => $value) {
+ $count_limit = $changed_group = 0;
+
+ $allowed_groups_arr = explode(',', $alwgr[$rowid]);
+ $excepted_groups_arr = explode(',', $excgr[$rowid]);
+
+ foreach ($allowed_groups_arr as $allowed_group) {
+ if (in_array($allowed_group, $cld_groups)) {
+ $count_limit++;
+ }
+ if (isset($_POST[$allowed_group]) && $_POST[$allowed_group] == 1 && ! in_array($allowed_group, $cld_groups)) {
+ $set_groups .= $allowed_group.',';
+ array_push($cld_groups, $allowed_group);
+ $count_limit++;
+ $changed_group++;
+ }
+ if (! isset($_POST[$allowed_group]) && in_array($allowed_group, $cld_groups)) {
+ $set_groups .= '-'.$allowed_group.',';
+ $position = array_search($allowed_group, $cld_groups);
+ array_splice($cld_groups, $position, 1);
+ $count_limit--;
+ $changed_group++;
+ }
+ }
+
+ if (isset($excepted_groups_arr) && $excepted_groups_arr != '') {
+ foreach ($excepted_groups_arr as $excepted_group) {
+ if (in_array($excepted_group, $cld_groups) && $changed_group != 0) {
+ $excepted++;
+ if ($err_msg != '') {
+ $err_msg .= '#####';
+ $err_lvl .= '#3';
+ } else {
+ $err_lvl = 3;
+ }
+ $err_msg .= '
'.$name[$rowid].' '.sprintf($lang['stag0019'], $sqlhisgroup[$excepted_group]['sgidname'], $excepted_group);
+ break;
+ }
+ }
+ }
+
+ if ($set_groups != '' && $count_limit > $limit[$rowid]) {
+ if ($err_msg != '') {
+ $err_msg .= '#####';
+ $err_lvl .= '#3';
+ } else {
+ $err_lvl = 3;
+ }
+ $err_msg .= '
'.$name[$rowid].' '.sprintf($lang['stag0009'], $limit[$rowid]);
+ $limit_raised = 1;
+ }
+ }
+ $set_groups = substr($set_groups, 0, -1);
+
+ if ($set_groups != '' && $limit_raised == 0 && $excepted == 0) {
+ if ($mysqlcon->exec("INSERT INTO `$dbname`.`addon_assign_groups` SET `uuid`='$uuid',`grpids`='$set_groups'; DELETE FROM `$dbname`.`csrf_token` WHERE `token`='{$_POST['csrf_token']}'") === false) {
+ $err_msg = $lang['isntwidbmsg'].print_r($mysqlcon->errorInfo(), true);
+ $err_lvl = 3;
+ } elseif ($mysqlcon->exec("UPDATE `$dbname`.`job_check` SET `timestamp`=1 WHERE `job_name`='reload_trigger'; ") === false) {
+ $err_msg = $lang['isntwidbmsg'].print_r($mysqlcon->errorInfo(), true);
+ $err_lvl = 3;
+ } else {
+ $err_msg = $lang['stag0008'];
+ $err_lvl = null;
+ }
+ } elseif ($limit_raised != 0) {
+ //message above generated
+ } elseif ($excepted > 0) {
+ //message above generated
+ } else {
+ $err_msg = $lang['stag0010'];
+ $err_lvl = 3;
+ }
+ }
+ }
+ } elseif (isset($_POST['update'])) {
+ echo '
',$lang['errcsrf'],'
';
+ rem_session_ts3();
+ exit;
+ }
+ }
+ ?>
-
+
-
+
-
diff --git a/stats/index.php b/stats/index.php
index 6e556f2..5b6374f 100644
--- a/stats/index.php
+++ b/stats/index.php
@@ -1,39 +1,45 @@
-query("SELECT * FROM `$dbname`.`stats_server`")->fetch()) === false) {
- $err_msg = print_r($mysqlcon->errorInfo(), true); $err_lvl = 3;
- }
-
- if(($groupslist = $mysqlcon->query("SELECT * FROM `$dbname`.`groups` WHERE `sgid`=0")->fetchAll(PDO::FETCH_UNIQUE|PDO::FETCH_ASSOC)) === false) {
- $err_msg = print_r($mysqlcon->errorInfo(), true); $err_lvl = 3;
- }
- ?>
+query("SELECT * FROM `$dbname`.`stats_server`")->fetch()) === false) {
+ $err_msg = print_r($mysqlcon->errorInfo(), true);
+ $err_lvl = 3;
+ }
+
+ if (($groupslist = $mysqlcon->query("SELECT * FROM `$dbname`.`groups` WHERE `sgid`=0")->fetchAll(PDO::FETCH_UNIQUE | PDO::FETCH_ASSOC)) === false) {
+ $err_msg = print_r($mysqlcon->errorInfo(), true);
+ $err_lvl = 3;
+ }
+ ?>
@@ -93,14 +103,22 @@
@@ -115,14 +133,22 @@
@@ -136,15 +162,15 @@
-
+
@@ -311,102 +337,137 @@
-
+
-
- '.$lang['stix0024'].''; } else { echo ''.$lang['stix0025'].' '; } ?>
+
+ '.$lang['stix0024'].'';
+ } else {
+ echo ''.$lang['stix0025'].' ';
+ } ?>
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
- '.$lang['stix0032'].''.(new DateTime("@0"))->diff($serveruptime)->format($cfg['default_date_format']).') '; } else { echo $lang['stix0033']; } ?>
+
+ '.$lang['stix0032'].''.(new DateTime('@0'))->diff($serveruptime)->format($cfg['default_date_format']).') ';
+ } else {
+ echo $lang['stix0033'];
+ } ?>
-
-
+
+
-
+
-
- ';
- } else { echo $sql_res['server_name']; } ?>
+
+ ';
+ } else {
+ echo $sql_res['server_name'];
+ } ?>
-
- ">
-
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
@@ -416,60 +477,60 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
- ';
- } else {
- echo ' ';
- }
- if (isset($nation[$sql_res['country_nation_name_2']])) {
- echo ' ';
- } else {
- echo ' ';
- }
- if (isset($nation[$sql_res['country_nation_name_3']])) {
- echo ' ';
- } else {
- echo ' ';
- }
- if (isset($nation[$sql_res['country_nation_name_4']])) {
- echo ' ';
- } else {
- echo ' ';
- }
- if (isset($nation[$sql_res['country_nation_name_5']])) {
- echo ' ';
- } else {
- echo ' ';
- }
- ?>
-
-
-
-
-
-
-
-
-
+ ';
+ } else {
+ echo ' ';
+ }
+ if (isset($nation[$sql_res['country_nation_name_2']])) {
+ echo ' ';
+ } else {
+ echo ' ';
+ }
+ if (isset($nation[$sql_res['country_nation_name_3']])) {
+ echo ' ';
+ } else {
+ echo ' ';
+ }
+ if (isset($nation[$sql_res['country_nation_name_4']])) {
+ echo ' ';
+ } else {
+ echo ' ';
+ }
+ if (isset($nation[$sql_res['country_nation_name_5']])) {
+ echo ' ';
+ } else {
+ echo ' ';
+ }
+ ?>
+
+
+
+
+
+
+
+
+
@@ -497,9 +558,10 @@
-
+