diff --git a/.codecov.yml b/.codecov.yml deleted file mode 100644 index 26cec6c2..00000000 --- a/.codecov.yml +++ /dev/null @@ -1,4 +0,0 @@ -codecov: - notify: - require_ci_to_pass: no - diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 280f411c..539d79c5 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -48,7 +48,7 @@ strings in -### New settings and database-layout changnes +### New settings and database-layout changes If you add new settings or layout changes, please make sure you add these to * `install/froxlor.sql` diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index ff27e343..910e6594 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,6 +1,6 @@ # Bug report vs. support request If you're unsure of whether your problem is a bug or a configuration error -* contact us via IRC in #froxlor on freenode +* contact us via IRC in #froxlor on irc.libera.chat * or post a thread in our forum at https://forum.froxlor.org As a rule of thumb: before reporting an issue diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..facf73f6 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,40 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**As a rule of thumb: before reporting an issue** +* see if it hasn't been [reported](https://github.com/Froxlor/froxlor/issues) (and possibly already been [fixed](https://github.com/Froxlor/froxlor/issues?utf8=✓&q=is:issue%20is:closed)) first +* try with the git master + +**Describe the bug** +A clear and concise description of what the bug is. + +**System information** +* Froxlor version: $version/$gitSHA1 +* Web server: apache2/nginx/lighttpd +* DNS server: Bind/PowerDNS (standalone)/PowerDNS (Bind-backend) +* POP/IMAP server: Courier/Dovecot +* SMTP server: postfix/exim +* FTP server: proftpd/pureftpd +* OS/Version: ... + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Logfiles** +If applicable, add log-entries to help explain your problem. + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000..bbcbbe7d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/workflows/build-apidocs.yml b/.github/workflows/build-apidocs.yml new file mode 100644 index 00000000..0e6e9df7 --- /dev/null +++ b/.github/workflows/build-apidocs.yml @@ -0,0 +1,14 @@ +name: build-docs + +on: + release: + types: [published] + +jobs: + build_docs: + runs-on: ubuntu-latest + steps: + - env: + GITHUB_TOKEN: ${{ secrets.ORG_GITHUB_TOKEN }} + run: | + gh workflow run --repo Froxlor/Documentation build-docs -f ref=${{github.ref_name}} diff --git a/.github/workflows/build-mariadb.yml b/.github/workflows/build-mariadb.yml new file mode 100644 index 00000000..2808dd6e --- /dev/null +++ b/.github/workflows/build-mariadb.yml @@ -0,0 +1,80 @@ +name: Froxlor-CI-MariaDB +on: ['push', 'pull_request', 'create'] + +jobs: + froxlor: + name: Froxlor (PHP ${{ matrix.php-versions }}, MariaDB ${{ matrix.mariadb-version }}) + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + php-versions: ['7.4', '8.0'] + mariadb-version: [10.5, 10.4] + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup PHP, with composer and extensions + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + tools: composer:v2 + extensions: mbstring, xml, ctype, pdo_mysql, mysql, curl, json, zip, session, filter, posix, openssl, fileinfo, bcmath + + - name: Install tools + run: sudo apt-get install -y ant + + - name: Adjust firewall + run: | + sudo ufw allow out 3306/tcp + sudo ufw allow in 3306/tcp + + - name: Setup MariaDB + uses: getong/mariadb-action@v1.1 + with: + mariadb version: ${{ matrix.mariadb-version }} + mysql database: 'froxlor010' + mysql root password: 'fr0xl0r.TravisCI' + + - name: Wait for database + run: sleep 15 + + - name: Setup databases + run: | + mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI -e "CREATE USER 'froxlor010'@'%' IDENTIFIED BY 'fr0xl0r.TravisCI';" + mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI -e "GRANT ALL ON froxlor010.* TO 'froxlor010'@'%';" + mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI froxlor010 < install/froxlor.sql + + - name: Run testing + run: ant quick-build + +# - name: irc push +# uses: rectalogic/notify-irc@v1 +# if: github.event_name == 'push' +# with: +# channel: "#froxlor" +# server: "irc.libera.chat" +# nickname: froxlor-ci +# message: | +# ${{ github.actor }} pushed ${{ github.event.ref }} ${{ github.event.compare }} +# ${{ join(github.event.commits.*.message) }} + +# - name: irc pull request +# uses: rectalogic/notify-irc@v1 +# if: github.event_name == 'pull_request' +# with: +# channel: "#froxlor" +# server: "irc.libera.chat" +# nickname: froxlor-ci +# message: | +# ${{ github.actor }} opened PR ${{ github.event.pull_request.html_url }} + +# - name: irc tag created +# uses: rectalogic/notify-irc@v1 +# if: github.event_name == 'create' && github.event.ref_type == 'tag' +# with: +# channel: "#froxlor" +# server: "irc.libera.chat" +# nickname: froxlor-ci +# message: | +# ${{ github.actor }} tagged ${{ github.repository }} ${{ github.event.ref }} diff --git a/.github/workflows/build-mysql.yml b/.github/workflows/build-mysql.yml new file mode 100644 index 00000000..1bee12cf --- /dev/null +++ b/.github/workflows/build-mysql.yml @@ -0,0 +1,57 @@ +name: Froxlor-CI-MySQL +on: ['push', 'pull_request', 'create'] + +jobs: + froxlor: + name: Froxlor (PHP ${{ matrix.php-versions }}, MySQL ${{ matrix.mysql-version }}) + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + php-versions: ['7.4', '8.0'] + mysql-version: [8.0, 5.7] + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup PHP, with composer and extensions + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + tools: composer:v2 + extensions: mbstring, xml, ctype, pdo_mysql, mysql, curl, json, zip, session, filter, posix, openssl, fileinfo, bcmath + + - name: Install tools + run: sudo apt-get install -y ant + + - name: Adjust firewall + run: | + sudo ufw allow out 3306/tcp + sudo ufw allow in 3306/tcp + + - name: Setup MySQL + uses: samin/mysql-action@v1.3 + with: + mysql version: ${{ matrix.mysql-version }} + mysql database: 'froxlor010' + mysql root password: 'fr0xl0r.TravisCI' + + - name: Wait for database + run: sleep 15 + + - name: Setup database (8.0) + if: matrix.mysql-version == '8.0' + run: | + mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI -e "CREATE USER 'froxlor010'@'%' IDENTIFIED WITH mysql_native_password BY 'fr0xl0r.TravisCI';" + mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI -e "GRANT ALL ON froxlor010.* TO 'froxlor010'@'%';" + mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI froxlor010 < install/froxlor.sql + + - name: Setup database (5.7) + if: matrix.mysql-version == '5.7' + run: | + mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI -e "CREATE USER 'froxlor010'@'%' IDENTIFIED BY 'fr0xl0r.TravisCI';" + mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI -e "GRANT ALL ON froxlor010.* TO 'froxlor010'@'%';" + mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI froxlor010 < install/froxlor.sql + + - name: Run testing + run: ant quick-build diff --git a/.gitignore b/.gitignore index 8a488e1a..bd5f215b 100644 --- a/.gitignore +++ b/.gitignore @@ -12,10 +12,11 @@ logs/* .well-known .idea *.iml +img/ !templates/Maketank/ !templates/Froxlor/ !templates/Sparkle/ !templates/misc/ -templates/Froxlor/assets/img/logo_custom.png +templates/Sparkle/assets/css/custom.css vendor/ diff --git a/.travis.yml b/.travis.yml index 4148f43a..e0cb1aa3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -52,13 +52,10 @@ install: - mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI froxlor010 < install/froxlor.sql script: - - ant phpunit - -after_success: - - bash <(curl -s https://codecov.io/bash) -f "build/logs/clover.xml" + - ant phpunit-no-coverage notifications: - irc: "irc.freenode.org#froxlor" + irc: "irc.libera.chat#froxlor" webhooks: urls: - https://webhooks.gitter.im/e/bdf91d1c3f745e51f796 diff --git a/2fa.php b/2fa.php index dd73110b..9bd5f2cd 100644 --- a/2fa.php +++ b/2fa.php @@ -38,7 +38,7 @@ if (AREA == 'admin') { } $success_message = ""; -$tfa = new \Froxlor\FroxlorTwoFactorAuth('Froxlor'); +$tfa = new \Froxlor\FroxlorTwoFactorAuth('Froxlor ' . Settings::Get('system.hostname')); // do the delete and then just show a success-message if ($action == 'delete') { diff --git a/README.md b/README.md index 51b9d3d8..9407c022 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ -[![Build Status](https://travis-ci.com/Froxlor/Froxlor.svg?branch=master)](https://travis-ci.com/Froxlor/Froxlor) -[![Gitter](https://badges.gitter.im/Froxlor/community.svg)](https://gitter.im/Froxlor/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) +[![Froxlor-CI](https://github.com/Froxlor/Froxlor/actions/workflows/build-mariadb.yml/badge.svg?branch=master)](https://github.com/Froxlor/Froxlor/actions/workflows/build-mariadb.yml) +[![Froxlor-CI](https://github.com/Froxlor/Froxlor/actions/workflows/build-mysql.yml/badge.svg?branch=master)](https://github.com/Froxlor/Froxlor/actions/workflows/build-mysql.yml) +[![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.froxlor.org) # Froxlor @@ -20,16 +21,20 @@ Developed by experienced server administrators, this panel simplifies the effort 9. Have fun! ### Detailed installation -https://github.com/Froxlor/Froxlor/wiki/Install-froxlor-from-tarball +https://docs.froxlor.org/general/installation/index.html ## Help You may find help in the following places: +### Discord + +The froxlor community discord server can be found here: https://discord.froxlor.org + ### IRC -froxlor may be found on freenode.net, channel #froxlor: -irc://chat.freenode.net/froxlor +froxlor may be found on libera.chat, channel #froxlor: +irc://irc.libera.chat/froxlor ### Forum @@ -37,12 +42,12 @@ The community is located on https://forum.froxlor.org/ ### Wiki -More documentation may be found in the froxlor - wiki: -https://github.com/Froxlor/Froxlor/wiki +More documentation may be found in the froxlor - documentation: +https://docs.froxlor.org/ ## License -May be found in COPYING +May be found in [COPYING](COPYING) ## Downloads @@ -51,7 +56,7 @@ https://files.froxlor.org/releases/froxlor-latest.tar.gz [MD5](https://files.fro ### Debian repository -[HowTo](https://github.com/Froxlor/Froxlor/wiki/Install-froxlor-on-debian) +[HowTo](https://docs.froxlor.org/general/installation/aptpackage.html) ``` apt-get -y install apt-transport-https lsb-release ca-certificates @@ -61,7 +66,7 @@ echo "deb https://deb.froxlor.org/debian $(lsb_release -sc) main" > /etc/apt/sou ### Ubuntu repository -[HowTo](https://github.com/Froxlor/Froxlor/wiki/Install-froxlor-on-ubuntu) +[HowTo](https://docs.froxlor.org/general/installation/aptpackage.html) ``` apt-get -y install apt-transport-https lsb-release ca-certificates diff --git a/actions/admin/settings/100.panel.php b/actions/admin/settings/100.panel.php index ffbb9f4f..7f8cc794 100644 --- a/actions/admin/settings/100.panel.php +++ b/actions/admin/settings/100.panel.php @@ -77,14 +77,6 @@ return array( 'default' => false, 'save_method' => 'storeSettingField' ), - 'panel_no_robots' => array( - 'label' => $lng['serversettings']['no_robots'], - 'settinggroup' => 'panel', - 'varname' => 'no_robots', - 'type' => 'bool', - 'default' => true, - 'save_method' => 'storeSettingField' - ), 'panel_paging' => array( 'label' => $lng['serversettings']['paging'], 'settinggroup' => 'panel', @@ -257,7 +249,7 @@ return array( 'extras' => $lng['menue']['extras']['extras'], 'extras.directoryprotection' => $lng['menue']['extras']['extras'] . " / " . $lng['menue']['extras']['directoryprotection'], 'extras.pathoptions' => $lng['menue']['extras']['extras'] . " / " . $lng['menue']['extras']['pathoptions'], - 'extras.logger' => $lng['menue']['extras']['extras'] . " / " . $lng['menue']['logger']['logger'], + 'extras.logger' => $lng['menue']['extras']['extras'] . " / " . $lng['admin']['loggersystem'], 'extras.backup' => $lng['menue']['extras']['extras'] . " / " . $lng['menue']['extras']['backup'], 'traffic' => $lng['menue']['traffic']['traffic'], 'traffic.http' => $lng['menue']['traffic']['traffic'] . " / HTTP", @@ -265,7 +257,71 @@ return array( 'traffic.mail' => $lng['menue']['traffic']['traffic'] . " / Mail" ), 'save_method' => 'storeSettingField' - ) + ), + 'panel_imprint_url' => array( + 'label' => $lng['serversettings']['imprint_url'], + 'settinggroup' => 'panel', + 'varname' => 'imprint_url', + 'type' => 'string', + 'string_type' => 'url', + 'string_emptyallowed' => true, + 'default' => '', + 'save_method' => 'storeSettingField' + ), + 'panel_terms_url' => array( + 'label' => $lng['serversettings']['terms_url'], + 'settinggroup' => 'panel', + 'varname' => 'terms_url', + 'type' => 'string', + 'string_type' => 'url', + 'string_emptyallowed' => true, + 'default' => '', + 'save_method' => 'storeSettingField' + ), + 'panel_privacy_url' => array( + 'label' => $lng['serversettings']['privacy_url'], + 'settinggroup' => 'panel', + 'varname' => 'privacy_url', + 'type' => 'string', + 'string_type' => 'url', + 'string_emptyallowed' => true, + 'default' => '', + 'save_method' => 'storeSettingField' + ), + 'panel_logo_overridetheme' => array( + 'label' => $lng['serversettings']['logo_overridetheme'], + 'settinggroup' => 'panel', + 'varname' => 'logo_overridetheme', + 'type' => 'bool', + 'default' => false, + 'save_method' => 'storeSettingField' + ), + 'panel_logo_overridecustom' => array( + 'label' => $lng['serversettings']['logo_overridecustom'], + 'settinggroup' => 'panel', + 'varname' => 'logo_overridecustom', + 'type' => 'bool', + 'default' => false, + 'save_method' => 'storeSettingField' + ), + 'panel_logo_image_header' => array( + 'label' => $lng['serversettings']['logo_image_header'], + 'settinggroup' => 'panel', + 'varname' => 'logo_image_header', + 'type' => 'image', + 'image_name' => 'logo_header', + 'default' => '', + 'save_method' => 'storeSettingImage' + ), + 'panel_logo_image_login' => array( + 'label' => $lng['serversettings']['logo_image_login'], + 'settinggroup' => 'panel', + 'varname' => 'logo_image_login', + 'type' => 'image', + 'image_name' => 'logo_login', + 'default' => '', + 'save_method' => 'storeSettingImage' + ), ) ) ) diff --git a/actions/admin/settings/110.accounts.php b/actions/admin/settings/110.accounts.php index 71628dec..8eaee480 100644 --- a/actions/admin/settings/110.accounts.php +++ b/actions/admin/settings/110.accounts.php @@ -205,9 +205,21 @@ return array( 'default' => false, 'cronmodule' => 'froxlor/backup', 'save_method' => 'storeSettingField' - ) + ), + 'system_createstdsubdom_default' => array( + 'label' => $lng['serversettings']['createstdsubdom_default'], + 'settinggroup' => 'system', + 'varname' => 'createstdsubdom_default', + 'type' => 'option', + 'default' => '1', + 'option_mode' => 'one', + 'option_options' => array( + '0' => $lng['panel']['no'], + '1' => $lng['panel']['yes'] + ), + 'save_method' => 'storeSettingField' + ), ) ) ) ); - diff --git a/actions/admin/settings/120.system.php b/actions/admin/settings/120.system.php index c76774b7..5ec88db0 100644 --- a/actions/admin/settings/120.system.php +++ b/actions/admin/settings/120.system.php @@ -270,6 +270,28 @@ return array( 'default' => true, 'save_method' => 'storeSettingField' ), + 'system_domaindefaultalias' => array( + 'label' => $lng['admin']['domaindefaultalias'], + 'settinggroup' => 'system', + 'varname' => 'domaindefaultalias', + 'type' => 'option', + 'default' => '0', + 'option_mode' => 'one', + 'option_options' => array( + '0' => $lng['domains']['serveraliasoption_wildcard'], + '1' => $lng['domains']['serveraliasoption_www'], + '2' => $lng['domains']['serveraliasoption_none'] + ), + 'save_method' => 'storeSettingField' + ), + 'hide_incompatible_settings' => array( + 'label' => $lng['serversettings']['hide_incompatible_settings'], + 'settinggroup' => 'system', + 'varname' => 'hide_incompatible_settings', + 'type' => 'bool', + 'default' => false, + 'save_method' => 'storeSettingField' + ), ) ) ) diff --git a/actions/admin/settings/131.ssl.php b/actions/admin/settings/131.ssl.php index 609b0879..2d30bf3c 100644 --- a/actions/admin/settings/131.ssl.php +++ b/actions/admin/settings/131.ssl.php @@ -35,7 +35,7 @@ return array( 'settinggroup' => 'system', 'varname' => 'ssl_protocols', 'type' => 'option', - 'default' => 'TLSv1,TLSv1.2', + 'default' => 'TLSv1.2', 'option_mode' => 'multiple', 'option_options' => array( 'TLSv1' => 'TLSv1', @@ -122,10 +122,7 @@ return array( 'type' => 'bool', 'default' => true, 'save_method' => 'storeSettingField', - 'visible' => \Froxlor\Settings::Get('system.use_ssl') && (\Froxlor\Settings::Get('system.webserver') == "nginx" || (\Froxlor\Settings::Get('system.webserver') == "apache2" && \Froxlor\Settings::Get('system.apache24') == 1)) && call_user_func(array( - '\Froxlor\Settings\FroxlorVhostSettings', - 'hasVhostContainerEnabled' - ), true) + 'visible' => \Froxlor\Settings::Get('system.use_ssl') && (\Froxlor\Settings::Get('system.webserver') == "nginx" || (\Froxlor\Settings::Get('system.webserver') == "apache2" && \Froxlor\Settings::Get('system.apache24') == 1)) ), 'system_leenabled' => array( 'label' => $lng['serversettings']['leenabled'], @@ -136,6 +133,15 @@ return array( 'cronmodule' => 'froxlor/letsencrypt', 'save_method' => 'storeSettingField' ), + 'system_acmeshpath' => array( + 'label' => $lng['serversettings']['acmeshpath'], + 'settinggroup' => 'system', + 'varname' => 'acmeshpath', + 'type' => 'string', + 'string_type' => 'file', + 'default' => '/root/.acme.sh/acme.sh', + 'save_method' => 'storeSettingField' + ), 'system_letsencryptacmeconf' => array( 'label' => $lng['serversettings']['letsencryptacmeconf'], 'settinggroup' => 'system', @@ -145,6 +151,9 @@ return array( 'default' => '/etc/apache2/conf-enabled/acme.conf', 'save_method' => 'storeSettingField' ), + /** + * currently the only option anyway + * 'system_leapiversion' => array( 'label' => $lng['serversettings']['leapiversion'], 'settinggroup' => 'system', @@ -157,16 +166,20 @@ return array( ), 'save_method' => 'storeSettingField' ), + */ 'system_letsencryptca' => array( 'label' => $lng['serversettings']['letsencryptca'], 'settinggroup' => 'system', 'varname' => 'letsencryptca', 'type' => 'option', - 'default' => 'production', + 'default' => 'letsencrypt', 'option_mode' => 'one', 'option_options' => array( - 'testing' => 'https://acme-staging-v0' . \Froxlor\Settings::Get('system.leapiversion') . '.api.letsencrypt.org (Test)', - 'production' => 'https://acme-v0' . \Froxlor\Settings::Get('system.leapiversion') . '.api.letsencrypt.org (Live)' + 'letsencrypt_test' => 'Let\'s Encrypt (Test / Staging)', + 'letsencrypt' => 'Let\'s Encrypt (Live)', + 'buypass_test' => 'Buypass (Test / Staging)', + 'buypass' => 'Buypass (Live)', + 'zerossl' => 'ZeroSSL (Live)' ), 'save_method' => 'storeSettingField' ), @@ -217,11 +230,11 @@ return array( 'save_method' => 'storeSettingField' ), 'system_disable_le_selfcheck' => array( - 'label' => $lng['serversettings']['disable_le_selfcheck'], + 'label' => $lng['serversettings']['le_domain_dnscheck'], 'settinggroup' => 'system', - 'varname' => 'disable_le_selfcheck', + 'varname' => 'le_domain_dnscheck', 'type' => 'bool', - 'default' => false, + 'default' => true, 'save_method' => 'storeSettingField' ) ) diff --git a/actions/admin/settings/160.nameserver.php b/actions/admin/settings/160.nameserver.php index 67260bfa..625089b7 100644 --- a/actions/admin/settings/160.nameserver.php +++ b/actions/admin/settings/160.nameserver.php @@ -99,6 +99,19 @@ return array( 'default' => '', 'save_method' => 'storeSettingField' ), + 'system_powerdns_mode' => array( + 'label' => $lng['serversettings']['powerdns_mode'], + 'settinggroup' => 'system', + 'varname' => 'powerdns_mode', + 'type' => 'option', + 'default' => 'Native', + 'option_mode' => 'one', + 'option_options' => array( + 'Native' => 'Native', + 'Master' => 'Master' + ), + 'save_method' => 'storeSettingField' + ), 'system_dns_createmailentry' => array( 'label' => $lng['serversettings']['mail_also_with_mxservers'], 'settinggroup' => 'system', @@ -132,6 +145,16 @@ return array( 'int_min' => 3600, /* 1 hour */ 'int_max' => 2147483647, /* integer max */ 'save_method' => 'storeSettingField' + ), + 'system_soaemail' => array( + 'label' => $lng['serversettings']['soaemail'], + 'settinggroup' => 'system', + 'varname' => 'soaemail', + 'type' => 'string', + 'string_type' => 'mail', + 'string_emptyallowed' => true, + 'default' => '', + 'save_method' => 'storeSettingField' ) ) ) diff --git a/actions/admin/settings/180.dkim.php b/actions/admin/settings/180.dkim.php index 36625d16..76f74ff6 100644 --- a/actions/admin/settings/180.dkim.php +++ b/actions/admin/settings/180.dkim.php @@ -39,6 +39,15 @@ return array( 'default' => '/etc/postfix/dkim/', 'save_method' => 'storeSettingField' ), + 'dkim_privkeysuffix' => array( + 'label' => $lng['dkim']['privkeysuffix'], + 'settinggroup' => 'dkim', + 'varname' => 'privkeysuffix', + 'type' => 'string', + 'string_regexp' => '/^[a-z0-9\._]+$/i', + 'default' => '.priv', + 'save_method' => 'storeSettingField' + ), 'dkim_domains' => array( 'label' => $lng['dkim']['dkim_domains'], 'settinggroup' => 'dkim', diff --git a/actions/admin/settings/210.security.php b/actions/admin/settings/210.security.php index 62542c67..1cecb59e 100644 --- a/actions/admin/settings/210.security.php +++ b/actions/admin/settings/210.security.php @@ -82,7 +82,20 @@ return array( 'string_emptyallowed' => true, 'default' => '', 'save_method' => 'storeSettingField' - ) + ), + 'system_froxlorusergroup' => array( + 'label' => $lng['serversettings']['froxlorusergroup'], + 'settinggroup' => 'system', + 'varname' => 'froxlorusergroup', + 'type' => 'string', + 'default' => '', + 'save_method' => 'storeSettingField', + 'plausibility_check_method' => array( + '\\Froxlor\\Validate\\Check', + 'checkLocalGroup' + ), + 'visible' => \Froxlor\Settings::Get('system.nssextrausers') + ), ) ) ) diff --git a/admin_admins.php b/admin_admins.php index c18bb3fc..3c8031d8 100644 --- a/admin_admins.php +++ b/admin_admins.php @@ -107,7 +107,7 @@ if ($page == 'admins' && $userinfo['change_serversettings'] == '1') { $count ++; } - $admincount = $paging->getEntries(); + $admincount = $result['count'] . " / " . $paging->getEntries(); eval("echo \"" . \Froxlor\UI\Template::getTemplate("admins/admins") . "\";"); } elseif ($action == 'su') { @@ -129,7 +129,7 @@ if ($page == 'admins' && $userinfo['change_serversettings'] == '1') { 'userid' => $userinfo['userid'] )); - $s = md5(uniqid(microtime(), 1)); + $s = \Froxlor\Froxlor::genSessionId(); $ins_stmt = Database::prepare(" INSERT INTO `" . TABLE_PANEL_SESSIONS . "` SET `hash` = :hash, `userid` = :userid, `ipaddress` = :ip, diff --git a/admin_apcuinfo.php b/admin_apcuinfo.php index a0b0f937..b616b0a5 100644 --- a/admin_apcuinfo.php +++ b/admin_apcuinfo.php @@ -67,6 +67,9 @@ if ($page == 'showinfo') { $uptime_duration = duration($cache['start_time']); $size_vars = bsize($cache['mem_size']); + $num_hits_and_misses = $cache['num_hits'] + $cache['num_misses']; + $num_hits_and_misses = 0 >= $num_hits_and_misses ? 1 : $num_hits_and_misses; + // check for possible empty values that are used in the templates if (! isset($cache['file_upload_progress'])) { $cache['file_upload_progress'] = $lng['logger']['unknown']; @@ -84,10 +87,10 @@ if ($page == 'showinfo') { $freemem = bsize($mem_avail) . sprintf(" (%.1f%%)", $mem_avail * 100 / $mem_size); $usedmem = bsize($mem_used) . sprintf(" (%.1f%%)", $mem_used * 100 / $mem_size); - $hits = $cache['num_hits'] . @sprintf(" (%.1f%%)", $cache['num_hits'] * 100 / ($cache['num_hits'] + $cache['num_misses'])); - $misses = $cache['num_misses'] . @sprintf(" (%.1f%%)", $cache['num_misses'] * 100 / ($cache['num_hits'] + $cache['num_misses'])); + $hits = $cache['num_hits'] . @sprintf(" (%.1f%%)", $cache['num_hits'] * 100 / $num_hits_and_misses); + $misses = $cache['num_misses'] . @sprintf(" (%.1f%%)", $cache['num_misses'] * 100 / $num_hits_and_misses); - // Fragementation: (freeseg - 1) / total_seg + // Fragmentation: (freeseg - 1) / total_seg $nseg = $freeseg = $fragsize = $freetotal = 0; for ($i = 0; $i < $mem['num_seg']; $i ++) { $ptr = 0; diff --git a/admin_configfiles.php b/admin_configfiles.php index 1e14ddcf..594b7d2c 100644 --- a/admin_configfiles.php +++ b/admin_configfiles.php @@ -38,13 +38,43 @@ if ($userinfo['change_serversettings'] == '1') { // try to convert namserver hosts to ip's $ns_ips = ""; + $known_ns_ips = []; if (Settings::Get('system.nameservers') != '') { $nameservers = explode(',', Settings::Get('system.nameservers')); foreach ($nameservers as $nameserver) { $nameserver = trim($nameserver); + // DNS servers might be multi homed; allow transfer from all ip + // addresses of the DNS server $nameserver_ips = \Froxlor\PhpHelper::gethostbynamel6($nameserver); - if (is_array($nameserver_ips) && count($nameserver_ips) > 0) { - $ns_ips .= implode(",", $nameserver_ips); + // append dot to hostname + if (substr($nameserver, - 1, 1) != '.') { + $nameserver .= '.'; + } + // ignore invalid responses + if (! is_array($nameserver_ips)) { + // act like \Froxlor\PhpHelper::gethostbynamel6() and return unmodified hostname on error + $nameserver_ips = array( + $nameserver + ); + } else { + $known_ns_ips = array_merge($known_ns_ips, $nameserver_ips); + } + if (!empty($ns_ips)) { + $ns_ips .= ','; + } + $ns_ips .= implode(",", $nameserver_ips); + } + } + + // AXFR server + if (Settings::Get('system.axfrservers') != '') { + $axfrservers = explode(',', Settings::Get('system.axfrservers')); + foreach ($axfrservers as $axfrserver) { + if (!in_array(trim($axfrserver), $known_ns_ips)) { + if (!empty($ns_ips)) { + $ns_ips .= ','; + } + $ns_ips .= trim($axfrserver); } } } @@ -59,7 +89,6 @@ if ($userinfo['change_serversettings'] == '1') { '' => Settings::Get('system.ipaddress'), '' => Settings::Get('system.nameservers'), '' => $ns_ips, - '' => Settings::Get('system.axfrservers'), '' => Settings::Get('system.vmail_homedir'), '' => Settings::Get('system.vmail_uid'), '' => Settings::Get('system.vmail_gid'), diff --git a/admin_customers.php b/admin_customers.php index f641684a..ac393f73 100644 --- a/admin_customers.php +++ b/admin_customers.php @@ -150,7 +150,7 @@ if ($page == 'customers' && $userinfo['customers'] != '0') { $count ++; } - $customercount = $paging->getEntries(); + $customercount = $result['count'] . " / " . $paging->getEntries(); eval("echo \"" . \Froxlor\UI\Template::getTemplate("customers/customers") . "\";"); } elseif ($action == 'su' && $id != 0) { try { @@ -178,7 +178,7 @@ if ($page == 'customers' && $userinfo['customers'] != '0') { 'hash' => $s )); - $s = md5(uniqid(microtime(), 1)); + $s = \Froxlor\Froxlor::genSessionId(); $insert = Database::prepare(" INSERT INTO `" . TABLE_PANEL_SESSIONS . "` SET `hash` = :hash, diff --git a/admin_domains.php b/admin_domains.php index fa9686a7..fc88f711 100644 --- a/admin_domains.php +++ b/admin_domains.php @@ -39,7 +39,7 @@ if ($page == 'domains' || $page == 'overview') { $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "viewed admin_domains"); $fields = array( - 'd.domain' => $lng['domains']['domainname'], + 'd.domain_ace' => $lng['domains']['domainname'], 'c.name' => $lng['customer']['name'], 'c.firstname' => $lng['customer']['firstname'], 'c.company' => $lng['customer']['company'], @@ -80,7 +80,7 @@ if ($page == 'domains' || $page == 'overview') { $count++; } - $domainscount = $paging->getEntries(); + $domainscount = $result['count'] . " / " . $paging->getEntries(); // Display the list eval("echo \"" . \Froxlor\UI\Template::getTemplate("domains/domains") . "\";"); @@ -290,9 +290,9 @@ if ($page == 'domains' || $page == 'overview') { // create serveralias options $serveraliasoptions = ""; - $serveraliasoptions .= \Froxlor\UI\HTML::makeoption($lng['domains']['serveraliasoption_wildcard'], '0', '0', true, true); - $serveraliasoptions .= \Froxlor\UI\HTML::makeoption($lng['domains']['serveraliasoption_www'], '1', '0', true, true); - $serveraliasoptions .= \Froxlor\UI\HTML::makeoption($lng['domains']['serveraliasoption_none'], '2', '0', true, true); + $serveraliasoptions .= \Froxlor\UI\HTML::makeoption($lng['domains']['serveraliasoption_wildcard'], '0', Settings::Get('system.domaindefaultalias'), true, true); + $serveraliasoptions .= \Froxlor\UI\HTML::makeoption($lng['domains']['serveraliasoption_www'], '1', Settings::Get('system.domaindefaultalias'), true, true); + $serveraliasoptions .= \Froxlor\UI\HTML::makeoption($lng['domains']['serveraliasoption_none'], '2', Settings::Get('system.domaindefaultalias'), true, true); $subcanemaildomain = \Froxlor\UI\HTML::makeoption($lng['admin']['subcanemaildomain']['never'], '0', '0', true, true); $subcanemaildomain .= \Froxlor\UI\HTML::makeoption($lng['admin']['subcanemaildomain']['choosableno'], '1', '0', true, true); @@ -428,7 +428,7 @@ if ($page == 'domains' || $page == 'overview') { $customer = Database::pexecute_first($customer_stmt, array( 'customerid' => $result['customerid'] )); - $result['customername'] = \Froxlor\User::getCorrectFullUserDetails($customer) . ' (' . $customer['loginname'] . ')'; + $result['customername'] = \Froxlor\User::getCorrectFullUserDetails($customer); } if ($userinfo['customers_see_all'] == '1') { @@ -594,6 +594,10 @@ if ($page == 'domains' || $page == 'overview') { } $result = \Froxlor\PhpHelper::htmlentitiesArray($result); + if (Settings::Get('panel.allow_domain_change_customer') != '1') { + $result['customername'] .= ' (' . $customer['loginname'] . ')'; + } $domain_edit_data = include_once dirname(__FILE__) . '/lib/formfields/admin/domains/formfield.domains_edit.php'; $domain_edit_form = \Froxlor\UI\HtmlForm::genHTMLForm($domain_edit_data); @@ -616,7 +620,6 @@ if ($page == 'domains' || $page == 'overview') { if (isset($_POST['send']) && $_POST['send'] == 'send') { - $customerid = intval($_POST['customerid']); $separator = \Froxlor\Validate\Validate::validate($_POST['separator'], 'separator'); $offset = (int) \Froxlor\Validate\Validate::validate($_POST['offset'], 'offset', "/[0-9]/i"); @@ -625,7 +628,7 @@ if ($page == 'domains' || $page == 'overview') { $result = array(); try { - $bulk = new \Froxlor\Bulk\DomainBulkAction($file_name, $customerid); + $bulk = new \Froxlor\Bulk\DomainBulkAction($file_name, $userinfo); $result = $bulk->doImport($separator, $offset); } catch (Exception $e) { \Froxlor\UI\Response::standard_error('domain_import_error', $e->getMessage()); @@ -637,8 +640,8 @@ if ($page == 'domains' || $page == 'overview') { // update customer/admin counters \Froxlor\User::updateCounters(false); - \Froxlor\System\Cronjob::inserttask('1'); - \Froxlor\System\Cronjob::inserttask('4'); + \Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST); + \Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS); $result_str = $result['imported'] . ' / ' . $result['all'] . (! empty($result['note']) ? ' (' . $result['note'] . ')' : ''); \Froxlor\UI\Response::standard_success('domain_import_successfully', $result_str, array( @@ -647,19 +650,6 @@ if ($page == 'domains' || $page == 'overview') { 'page' => 'domains' )); } else { - $customers = \Froxlor\UI\HTML::makeoption($lng['panel']['please_choose'], 0, 0, true); - $result_customers_stmt = Database::prepare(" - SELECT `customerid`, `loginname`, `name`, `firstname`, `company` - FROM `" . TABLE_PANEL_CUSTOMERS . "` " . ($userinfo['customers_see_all'] ? '' : " WHERE `adminid` = '" . (int) $userinfo['adminid'] . "' ") . " ORDER BY `name` ASC"); - $params = array(); - if ($userinfo['customers_see_all'] == '0') { - $params['adminid'] = $userinfo['adminid']; - } - Database::pexecute($result_customers_stmt, $params); - - while ($row_customer = $result_customers_stmt->fetch(PDO::FETCH_ASSOC)) { - $customers .= \Froxlor\UI\HTML::makeoption(\Froxlor\User::getCorrectFullUserDetails($row_customer) . ' (' . $row_customer['loginname'] . ')', $row_customer['customerid']); - } $domain_import_data = include_once dirname(__FILE__) . '/lib/formfields/admin/domains/formfield.domains_import.php'; $domain_import_form = \Froxlor\UI\HtmlForm::genHTMLForm($domain_import_data); diff --git a/admin_index.php b/admin_index.php index 3415d14f..a91bae05 100644 --- a/admin_index.php +++ b/admin_index.php @@ -57,6 +57,12 @@ if (isset($_POST['id'])) { if ($page == 'overview') { $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "viewed admin_index"); + $params = []; + if ($userinfo['customers_see_all'] == '0') { + $params = [ + 'adminid' => $userinfo['adminid'] + ]; + } $overview_stmt = Database::prepare("SELECT COUNT(*) AS `number_customers`, SUM(`diskspace_used`) AS `diskspace_used`, SUM(`mysqls_used`) AS `mysqls_used`, @@ -68,20 +74,18 @@ if ($page == 'overview') { SUM(`subdomains_used`) AS `subdomains_used`, SUM(`traffic_used`) AS `traffic_used` FROM `" . TABLE_PANEL_CUSTOMERS . "`" . ($userinfo['customers_see_all'] ? '' : " WHERE `adminid` = :adminid ")); - $overview = Database::pexecute_first($overview_stmt, array( - 'adminid' => $userinfo['adminid'] - )); + $overview = Database::pexecute_first($overview_stmt, $params); $dec_places = Settings::Get('panel.decimal_places'); - $overview['traffic_used'] = round($overview['traffic_used'] / (1024 * 1024), $dec_places); - $overview['diskspace_used'] = round($overview['diskspace_used'] / 1024, $dec_places); + $overview['traffic_bytes_used'] = $overview['traffic_used'] * 1024; + $overview['traffic_used'] = \Froxlor\PhpHelper::sizeReadable($overview['traffic_used'] * 1024, null, 'bi'); + $overview['diskspace_bytes_used'] = $overview['diskspace_used'] * 1024; + $overview['diskspace_used'] = \Froxlor\PhpHelper::sizeReadable($overview['diskspace_used'] * 1024, null, 'bi'); $number_domains_stmt = Database::prepare(" SELECT COUNT(*) AS `number_domains` FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `parentdomainid`='0'" . ($userinfo['customers_see_all'] ? '' : " AND `adminid` = :adminid")); - $number_domains = Database::pexecute_first($number_domains_stmt, array( - 'adminid' => $userinfo['adminid'] - )); + $number_domains = Database::pexecute_first($number_domains_stmt, $params); $overview['number_domains'] = $number_domains['number_domains']; @@ -111,11 +115,17 @@ if ($page == 'overview') { } $dec_places = Settings::Get('panel.decimal_places'); - $userinfo['diskspace'] = round($userinfo['diskspace'] / 1024, $dec_places); - $userinfo['diskspace_used'] = round($userinfo['diskspace_used'] / 1024, $dec_places); - $userinfo['traffic'] = round($userinfo['traffic'] / (1024 * 1024), $dec_places); - $userinfo['traffic_used'] = round($userinfo['traffic_used'] / (1024 * 1024), $dec_places); - $userinfo = \Froxlor\PhpHelper::strReplaceArray('-1', $lng['customer']['unlimited'], $userinfo, 'customers domains diskspace traffic mysqls emails email_accounts email_forwarders email_quota ftps subdomains'); + // get everything in bytes for the percentage calculation on the dashboard + $userinfo['diskspace_bytes'] = ($userinfo['diskspace'] > -1) ? $userinfo['diskspace'] * 1024 : -1; + $userinfo['diskspace_bytes_used'] = $userinfo['diskspace_used'] * 1024; + $userinfo['traffic_bytes'] = ($userinfo['traffic'] > -1) ? $userinfo['traffic'] * 1024 : - 1; + $userinfo['traffic_bytes_used'] = $userinfo['traffic_used'] * 1024; + + $userinfo['diskspace'] = ($userinfo['diskspace'] > -1) ? \Froxlor\PhpHelper::sizeReadable($userinfo['diskspace'] * 1024, null, 'bi') : - 1; + $userinfo['diskspace_used'] = \Froxlor\PhpHelper::sizeReadable($userinfo['diskspace_used'] * 1024, null, 'bi'); + $userinfo['traffic'] = ($userinfo['traffic'] > -1) ? \Froxlor\PhpHelper::sizeReadable($userinfo['traffic'] * 1024, null, 'bi') : - 1; + $userinfo['traffic_used'] = \Froxlor\PhpHelper::sizeReadable($userinfo['traffic_used'] * 1024, null, 'bi'); + $userinfo = \Froxlor\PhpHelper::strReplaceArray('-1', $lng['customer']['unlimited'], $userinfo, 'customers domains diskspace diskspace_bytes traffic traffic_bytes mysqls emails email_accounts email_forwarders email_quota ftps subdomains'); $userinfo['custom_notes'] = ($userinfo['custom_notes'] != '') ? nl2br($userinfo['custom_notes']) : ''; @@ -183,8 +193,12 @@ if ($page == 'overview') { \Froxlor\UI\Response::standard_error('oldpasswordnotcorrect'); } - $new_password = \Froxlor\Validate\Validate::validate($_POST['new_password'], 'new password'); - $new_password_confirm = \Froxlor\Validate\Validate::validate($_POST['new_password_confirm'], 'new password confirm'); + try { + $new_password = \Froxlor\System\Crypt::validatePassword($_POST['new_password'], 'new password'); + $new_password_confirm = \Froxlor\System\Crypt::validatePassword($_POST['new_password_confirm'], 'new password confirm'); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } if ($old_password == '') { \Froxlor\UI\Response::standard_error(array( diff --git a/admin_ipsandports.php b/admin_ipsandports.php index 6b64ae8f..84006fb0 100644 --- a/admin_ipsandports.php +++ b/admin_ipsandports.php @@ -160,5 +160,14 @@ if ($page == 'ipsandports' || $page == 'overview') { eval("echo \"" . \Froxlor\UI\Template::getTemplate("ipsandports/ipsandports_edit") . "\";"); } } + } elseif ($action == 'jqCheckIP') { + $ip = $_POST['ip'] ?? ""; + if ((filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) || filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) && filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE | FILTER_FLAG_NO_PRIV_RANGE) == false) { + // returns notice if private network detected so we can display it + echo json_encode($lng['admin']['ipsandports']['ipnote']); + } else { + echo 0; + } + exit(); } } diff --git a/admin_message.php b/admin_message.php index 6f06156b..ce84da88 100644 --- a/admin_message.php +++ b/admin_message.php @@ -32,10 +32,10 @@ if ($page == 'message') { $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, 'viewed panel_message'); if (isset($_POST['send']) && $_POST['send'] == 'send') { - if ($_POST['receipient'] == 0 && $userinfo['customers_see_all'] == '1') { + if ($_POST['recipient'] == 0 && $userinfo['customers_see_all'] == '1') { $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, 'sending messages to admins'); $result = Database::query('SELECT `name`, `email` FROM `' . TABLE_PANEL_ADMINS . "`"); - } elseif ($_POST['receipient'] == 1) { + } elseif ($_POST['recipient'] == 1) { if ($userinfo['customers_see_all'] == '1') { $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, 'sending messages to ALL customers'); $result = Database::query('SELECT `firstname`, `name`, `company`, `email` FROM `' . TABLE_PANEL_CUSTOMERS . "`"); @@ -49,7 +49,7 @@ if ($page == 'message') { )); } } else { - \Froxlor\UI\Response::standard_error('noreceipientsgiven'); + \Froxlor\UI\Response::standard_error('norecipientsgiven'); } $subject = $_POST['subject']; @@ -105,7 +105,7 @@ if ($page == 'message') { $sentitems = isset($_GET['sentitems']) ? (int) $_GET['sentitems'] : 0; if ($sentitems == 0) { - $successmessage = $lng['message']['noreceipients']; + $successmessage = $lng['message']['norecipients']; } else { $successmessage = str_replace('%s', $sentitems, $lng['message']['success']); } @@ -116,12 +116,12 @@ if ($page == 'message') { } $action = ''; - $receipients = ''; + $recipients = ''; if ($userinfo['customers_see_all'] == '1') { - $receipients .= \Froxlor\UI\HTML::makeoption($lng['panel']['reseller'], 0); + $recipients .= \Froxlor\UI\HTML::makeoption($lng['panel']['reseller'], 0); } - $receipients .= \Froxlor\UI\HTML::makeoption($lng['panel']['customer'], 1); + $recipients .= \Froxlor\UI\HTML::makeoption($lng['panel']['customer'], 1); eval("echo \"" . \Froxlor\UI\Template::getTemplate('message/message') . "\";"); } diff --git a/admin_opcacheinfo.php b/admin_opcacheinfo.php index b6afbb51..85b8a8f3 100644 --- a/admin_opcacheinfo.php +++ b/admin_opcacheinfo.php @@ -22,7 +22,7 @@ require './lib/init.php'; if ($action == 'reset' && function_exists('opcache_reset') && $userinfo['change_serversettings'] == '1') { opcache_reset(); - $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "reseted OPcache"); + $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "reset OPcache"); header('Location: ' . $linker->getLink(array( 'section' => 'opcacheinfo', 'page' => 'showinfo' diff --git a/admin_settings.php b/admin_settings.php index 4e9aba21..162fe4d3 100644 --- a/admin_settings.php +++ b/admin_settings.php @@ -66,11 +66,11 @@ if ($page == 'overview' && $userinfo['change_serversettings'] == '1') { 'page' => $page ), $_part, $settings_all, $settings_part, $only_enabledisable)) { $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "rebuild configfiles due to changed setting"); - \Froxlor\System\Cronjob::inserttask('1'); + \Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST); // Using nameserver, insert a task which rebuilds the server config - \Froxlor\System\Cronjob::inserttask('4'); + \Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS); // cron.d file - \Froxlor\System\Cronjob::inserttask('99'); + \Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_CRON); \Froxlor\UI\Response::standard_success('settingssaved', '', array( 'filename' => $filename, @@ -146,12 +146,12 @@ if ($page == 'overview' && $userinfo['change_serversettings'] == '1') { if (isset($_POST['send']) && $_POST['send'] == 'send') { $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "rebuild configfiles"); - \Froxlor\System\Cronjob::inserttask('1'); - \Froxlor\System\Cronjob::inserttask('10'); + \Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST); + \Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::CREATE_QUOTA); // Using nameserver, insert a task which rebuilds the server config - \Froxlor\System\Cronjob::inserttask('4'); + \Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS); // cron.d file - \Froxlor\System\Cronjob::inserttask('99'); + \Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_CRON); \Froxlor\UI\Response::standard_success('rebuildingconfigs', '', array( 'filename' => 'admin_index.php' diff --git a/admin_traffic.php b/admin_traffic.php index a7f22f4f..942f47cb 100644 --- a/admin_traffic.php +++ b/admin_traffic.php @@ -56,6 +56,26 @@ if ($page == 'overview' || $page == 'customers') { $maxyears = date("Y") - $minyear['year']; } + $params = []; + if ($userinfo['customers_see_all'] == '0') { + $params = [ + 'id' => $userinfo['adminid'] + ]; + } + $customer_name_list_stmt = Database::prepare(" + SELECT `customerid`,`company`,`name`,`firstname` + FROM `" . TABLE_PANEL_CUSTOMERS . "` + WHERE `deactivated`='0'" . ($userinfo['customers_see_all'] ? '' : " AND `adminid` = :id") . " + ORDER BY name" + ); + + $traffic_list_stmt = Database::prepare(" + SELECT month, SUM(http+ftp_up+ftp_down+mail)*1024 AS traffic + FROM `" . TABLE_PANEL_TRAFFIC . "` + WHERE year = :year AND `customerid` = :id + GROUP BY month ORDER BY month" + ); + for ($years = 0; $years <= $maxyears; $years ++) { $overview['year'] = date("Y") - $years; @@ -76,14 +96,7 @@ if ($page == 'overview' || $page == 'customers') { 'dec' => 0 ); - $customer_name_list_stmt = Database::prepare(" - SELECT `customerid`,`company`,`name`,`firstname` - FROM `" . TABLE_PANEL_CUSTOMERS . "` - WHERE `deactivated`='0'" . ($userinfo['customers_see_all'] ? '' : " AND `adminid` = :id") . " - ORDER BY name"); - Database::pexecute($customer_name_list_stmt, array( - 'id' => $userinfo['adminid'] - )); + Database::pexecute($customer_name_list_stmt, $params); while ($customer_name = $customer_name_list_stmt->fetch(PDO::FETCH_ASSOC)) { @@ -104,11 +117,6 @@ if ($page == 'overview' || $page == 'customers') { 'dec' => '-' ); - $traffic_list_stmt = Database::prepare(" - SELECT month, SUM(http+ftp_up+ftp_down+mail)*1024 AS traffic - FROM `" . TABLE_PANEL_TRAFFIC . "` - WHERE year = :year AND `customerid` = :id - GROUP BY month ORDER BY month"); Database::pexecute($traffic_list_stmt, array( 'year' => (date("Y") - $years), 'id' => $customer_name['customerid'] diff --git a/admin_updates.php b/admin_updates.php index 2b0e3420..9f6357df 100644 --- a/admin_updates.php +++ b/admin_updates.php @@ -65,7 +65,7 @@ if ($page == 'overview') { eval("echo \"" . \Froxlor\UI\Template::getTemplate('update/update_end') . "\";"); \Froxlor\User::updateCounters(); - \Froxlor\System\Cronjob::inserttask('1'); + \Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST); @chmod(\Froxlor\Froxlor::getInstallDir() . '/lib/userdata.inc.php', 0440); $successful_update = true; diff --git a/api.php b/api.php index 02ddc2c5..3409a492 100644 --- a/api.php +++ b/api.php @@ -1,4 +1,6 @@ xss_clean($request); + // validate content try { $decoded_request = stripcslashes_deep($decoded_request); diff --git a/api_keys.php b/api_keys.php index 0c3126e5..1a110ce4 100644 --- a/api_keys.php +++ b/api_keys.php @@ -127,7 +127,7 @@ if ($action == 'delete') { $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed api::api_keys"); -// select all my (accessable) certificates +// select all my (accessible) certificates $keys_stmt_query = "SELECT ak.*, c.loginname, a.loginname as adminname FROM `" . TABLE_API_KEYS . "` ak LEFT JOIN `" . TABLE_PANEL_CUSTOMERS . "` c ON `c`.`customerid` = `ak`.`customerid` diff --git a/build.xml b/build.xml index e489f847..01c8dad4 100644 --- a/build.xml +++ b/build.xml @@ -6,21 +6,20 @@ - - @@ -59,7 +57,6 @@ - @@ -257,7 +254,7 @@ - @@ -269,18 +266,6 @@ - - - - - - - - - diff --git a/composer.json b/composer.json index b6445f0a..b1e6f0b1 100644 --- a/composer.json +++ b/composer.json @@ -25,12 +25,12 @@ "issues": "https://github.com/Froxlor/Froxlor/issues", "forum": "https://forum.froxlor.org/", "wiki": "https://github.com/Froxlor/Froxlor/wiki", - "irc": "irc://chat.freenode.net/froxlor", + "irc": "irc://irc.libera.chat/froxlor", "source": "https://github.com/Froxlor/Froxlor", "docs": "https://github.com/Froxlor/Froxlor/wiki" }, "require": { - "php": ">=7.0", + "php": "^7.1 || ^8.0", "ext-session": "*", "ext-ctype": "*", "ext-pdo": "*", @@ -43,22 +43,23 @@ "ext-curl": "*", "ext-json": "*", "ext-openssl": "*", + "ext-fileinfo": "*", "phpmailer/phpmailer": "~6.0", "monolog/monolog": "^1.24", "robthree/twofactorauth": "^1.6", - "froxlor/idna-convert-legacy": "^2.1" - }, + "froxlor/idna-convert-legacy": "^2.1", + "voku/anti-xss": "^4.1" + }, "require-dev": { - "phpunit/phpunit": "8.4.1", - "php": ">=7.3", + "phpunit/phpunit": "^9", "ext-pcntl": "*", "phpcompatibility/php-compatibility": "*", "squizlabs/php_codesniffer": "*", - "pdepend/pdepend": "^2.5", - "sebastian/phpcpd": "^4.1", - "theseer/phpdox": "^0.12.0", - "phploc/phploc": "^5.0", - "phpmd/phpmd": "^2.6" + "pdepend/pdepend": "^2.9", + "sebastian/phpcpd": "^6.0", + "phploc/phploc": "^7.0", + "phpmd/phpmd": "^2.10", + "phpunit/php-timer" : "^5" }, "suggest": { "ext-bcmath": "*", diff --git a/composer.lock b/composer.lock index 12069d86..e026863c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "a7ba15333ffb4a758ea65039b589545b", + "content-hash": "85144894a3d797cd463442147120549f", "packages": [ { "name": "froxlor/idna-convert-legacy", @@ -57,20 +57,23 @@ "idna", "php" ], + "support": { + "source": "https://github.com/Froxlor/idna-convert-legacy/tree/v2.1.2" + }, "time": "2019-12-31T12:16:30+00:00" }, { "name": "monolog/monolog", - "version": "1.25.3", + "version": "1.26.1", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "fa82921994db851a8becaf3787a9e73c5976b6f1" + "reference": "c6b00f05152ae2c9b04a448f99c7590beb6042f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/fa82921994db851a8becaf3787a9e73c5976b6f1", - "reference": "fa82921994db851a8becaf3787a9e73c5976b6f1", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/c6b00f05152ae2c9b04a448f99c7590beb6042f5", + "reference": "c6b00f05152ae2c9b04a448f99c7590beb6042f5", "shasum": "" }, "require": { @@ -84,11 +87,10 @@ "aws/aws-sdk-php": "^2.4.9 || ^3.0", "doctrine/couchdb": "~1.0@dev", "graylog2/gelf-php": "~1.0", - "jakub-onderka/php-parallel-lint": "0.9", "php-amqplib/php-amqplib": "~2.4", "php-console/php-console": "^3.1.3", + "phpstan/phpstan": "^0.12.59", "phpunit/phpunit": "~4.5", - "phpunit/phpunit-mock-objects": "2.3.0", "ruflin/elastica": ">=0.90 <3.0", "sentry/sentry": "^0.13", "swiftmailer/swiftmailer": "^5.3|^6.0" @@ -107,11 +109,6 @@ "sentry/sentry": "Allow sending log messages to a Sentry server" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, "autoload": { "psr-4": { "Monolog\\": "src/Monolog" @@ -135,34 +132,54 @@ "logging", "psr-3" ], - "time": "2019-12-20T14:15:16+00:00" + "support": { + "issues": "https://github.com/Seldaek/monolog/issues", + "source": "https://github.com/Seldaek/monolog/tree/1.26.1" + }, + "funding": [ + { + "url": "https://github.com/Seldaek", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/monolog/monolog", + "type": "tidelift" + } + ], + "time": "2021-05-28T08:32:12+00:00" }, { "name": "phpmailer/phpmailer", - "version": "v6.1.4", + "version": "v6.5.3", "source": { "type": "git", "url": "https://github.com/PHPMailer/PHPMailer.git", - "reference": "c5e61d0729507049cec9673aa1a679f9adefd683" + "reference": "baeb7cde6b60b1286912690ab0693c7789a31e71" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/c5e61d0729507049cec9673aa1a679f9adefd683", - "reference": "c5e61d0729507049cec9673aa1a679f9adefd683", + "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/baeb7cde6b60b1286912690ab0693c7789a31e71", + "reference": "baeb7cde6b60b1286912690ab0693c7789a31e71", "shasum": "" }, "require": { "ext-ctype": "*", "ext-filter": "*", + "ext-hash": "*", "php": ">=5.5.0" }, "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", "doctrine/annotations": "^1.2", - "friendsofphp/php-cs-fixer": "^2.2", - "phpunit/phpunit": "^4.8 || ^5.7" + "php-parallel-lint/php-console-highlighter": "^0.5.0", + "php-parallel-lint/php-parallel-lint": "^1.3", + "phpcompatibility/php-compatibility": "^9.3.5", + "roave/security-advisories": "dev-latest", + "squizlabs/php_codesniffer": "^3.6.0", + "yoast/phpunit-polyfills": "^1.0.0" }, "suggest": { - "ext-mbstring": "Needed to send email in multibyte encoding charset", + "ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses", "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", "league/oauth2-google": "Needed for Google XOAUTH2 authentication", "psr/log": "For optional PSR-3 debug logging", @@ -197,20 +214,30 @@ } ], "description": "PHPMailer is a full-featured email creation and transfer class for PHP", - "time": "2019-12-10T11:17:38+00:00" + "support": { + "issues": "https://github.com/PHPMailer/PHPMailer/issues", + "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.5.3" + }, + "funding": [ + { + "url": "https://github.com/Synchro", + "type": "github" + } + ], + "time": "2021-11-25T16:34:11+00:00" }, { "name": "psr/log", - "version": "1.1.2", + "version": "1.1.4", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801" + "reference": "d49695b909c3b7628b6289db5479a1c204601f11" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/446d54b4cb6bf489fc9d75f55843658e6f25d801", - "reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801", + "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11", "shasum": "" }, "require": { @@ -234,7 +261,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common interface for logging libraries", @@ -244,28 +271,36 @@ "psr", "psr-3" ], - "time": "2019-11-01T11:05:21+00:00" + "support": { + "source": "https://github.com/php-fig/log/tree/1.1.4" + }, + "time": "2021-05-03T11:20:27+00:00" }, { "name": "robthree/twofactorauth", - "version": "1.6.7", + "version": "1.8.1", "source": { "type": "git", "url": "https://github.com/RobThree/TwoFactorAuth.git", - "reference": "3407c33775391fa8c36f7d766f26c5e59a736374" + "reference": "5afcb45282f1c75562a48d479ecd1732c9bdb11b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/RobThree/TwoFactorAuth/zipball/3407c33775391fa8c36f7d766f26c5e59a736374", - "reference": "3407c33775391fa8c36f7d766f26c5e59a736374", + "url": "https://api.github.com/repos/RobThree/TwoFactorAuth/zipball/5afcb45282f1c75562a48d479ecd1732c9bdb11b", + "reference": "5afcb45282f1c75562a48d479ecd1732c9bdb11b", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=5.6.0" }, "require-dev": { + "php-parallel-lint/php-parallel-lint": "^1.2", "phpunit/phpunit": "@stable" }, + "suggest": { + "bacon/bacon-qr-code": "Needed for BaconQrCodeProvider provider", + "endroid/qr-code": "Needed for EndroidQrCodeProvider" + }, "type": "library", "autoload": { "psr-4": { @@ -295,30 +330,781 @@ "php", "tfa" ], - "time": "2019-06-21T08:51:04+00:00" + "support": { + "issues": "https://github.com/RobThree/TwoFactorAuth/issues", + "source": "https://github.com/RobThree/TwoFactorAuth" + }, + "funding": [ + { + "url": "https://paypal.me/robiii", + "type": "custom" + }, + { + "url": "https://github.com/RobThree", + "type": "github" + } + ], + "time": "2021-10-20T12:19:55+00:00" + }, + { + "name": "symfony/polyfill-iconv", + "version": "v1.24.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-iconv.git", + "reference": "f1aed619e28cb077fc83fac8c4c0383578356e40" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/f1aed619e28cb077fc83fac8c4c0383578356e40", + "reference": "f1aed619e28cb077fc83fac8c4c0383578356e40", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-iconv": "*" + }, + "suggest": { + "ext-iconv": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Iconv\\": "" + }, + "files": [ + "bootstrap.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": "Symfony polyfill for the Iconv extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "iconv", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-iconv/tree/v1.24.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-01-04T09:04:05+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.24.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "81b86b50cf841a64252b439e738e97f4a34e2783" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/81b86b50cf841a64252b439e738e97f4a34e2783", + "reference": "81b86b50cf841a64252b439e738e97f4a34e2783", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + }, + "files": [ + "bootstrap.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": "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.24.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": "2021-11-23T21:10:46+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.24.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8590a5f561694770bdcd3f9b5c69dde6945028e8", + "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "files": [ + "bootstrap.php" + ], + "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.24.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": "2021-02-19T12:13:01+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.24.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0abb51d2f102e00a4eefcf46ba7fec406d245825", + "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.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": "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.24.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": "2021-11-30T18:21:41+00:00" + }, + { + "name": "symfony/polyfill-php72", + "version": "v1.24.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php72.git", + "reference": "9a142215a36a3888e30d0a9eeea9766764e96976" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9a142215a36a3888e30d0a9eeea9766764e96976", + "reference": "9a142215a36a3888e30d0a9eeea9766764e96976", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php72\\": "" + }, + "files": [ + "bootstrap.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": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php72/tree/v1.24.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": "2021-05-27T09:17:38+00:00" + }, + { + "name": "voku/anti-xss", + "version": "4.1.35", + "source": { + "type": "git", + "url": "https://github.com/voku/anti-xss.git", + "reference": "4d7ec2816cd6eeebb7d5abbde8b0349f66709496" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/voku/anti-xss/zipball/4d7ec2816cd6eeebb7d5abbde8b0349f66709496", + "reference": "4d7ec2816cd6eeebb7d5abbde8b0349f66709496", + "shasum": "" + }, + "require": { + "php": ">=7.0.0", + "voku/portable-utf8": "~6.0.0" + }, + "require-dev": { + "phpunit/phpunit": "~6.0 || ~7.0 || ~9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "voku\\helper\\": "src/voku/helper/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "EllisLab Dev Team", + "homepage": "http://ellislab.com/" + }, + { + "name": "Lars Moelleken", + "email": "lars@moelleken.org", + "homepage": "https://www.moelleken.org/" + } + ], + "description": "anti xss-library", + "homepage": "https://github.com/voku/anti-xss", + "keywords": [ + "anti-xss", + "clean", + "security", + "xss" + ], + "support": { + "issues": "https://github.com/voku/anti-xss/issues", + "source": "https://github.com/voku/anti-xss/tree/4.1.35" + }, + "funding": [ + { + "url": "https://www.paypal.me/moelleken", + "type": "custom" + }, + { + "url": "https://github.com/voku", + "type": "github" + }, + { + "url": "https://opencollective.com/anti-xss", + "type": "open_collective" + }, + { + "url": "https://www.patreon.com/voku", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/voku/anti-xss", + "type": "tidelift" + } + ], + "time": "2021-12-08T15:20:33+00:00" + }, + { + "name": "voku/portable-ascii", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/voku/portable-ascii.git", + "reference": "9bd89e83cecdf8c37b64909454249eaed98b2c89" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/voku/portable-ascii/zipball/9bd89e83cecdf8c37b64909454249eaed98b2c89", + "reference": "9bd89e83cecdf8c37b64909454249eaed98b2c89", + "shasum": "" + }, + "require": { + "php": ">=7.0.0" + }, + "require-dev": { + "phpunit/phpunit": "~6.0 || ~7.0 || ~9.0" + }, + "suggest": { + "ext-intl": "Use Intl for transliterator_transliterate() support" + }, + "type": "library", + "autoload": { + "psr-4": { + "voku\\": "src/voku/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Lars Moelleken", + "homepage": "http://www.moelleken.org/" + } + ], + "description": "Portable ASCII library - performance optimized (ascii) string functions for php.", + "homepage": "https://github.com/voku/portable-ascii", + "keywords": [ + "ascii", + "clean", + "php" + ], + "support": { + "issues": "https://github.com/voku/portable-ascii/issues", + "source": "https://github.com/voku/portable-ascii/tree/2.0.0" + }, + "funding": [ + { + "url": "https://www.paypal.me/moelleken", + "type": "custom" + }, + { + "url": "https://github.com/voku", + "type": "github" + }, + { + "url": "https://opencollective.com/portable-ascii", + "type": "open_collective" + }, + { + "url": "https://www.patreon.com/voku", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/voku/portable-ascii", + "type": "tidelift" + } + ], + "time": "2022-01-24T18:59:03+00:00" + }, + { + "name": "voku/portable-utf8", + "version": "6.0.2", + "source": { + "type": "git", + "url": "https://github.com/voku/portable-utf8.git", + "reference": "17fc93430f64873ba7812893deb24e7644d31b71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/voku/portable-utf8/zipball/17fc93430f64873ba7812893deb24e7644d31b71", + "reference": "17fc93430f64873ba7812893deb24e7644d31b71", + "shasum": "" + }, + "require": { + "php": ">=7.0.0", + "symfony/polyfill-iconv": "~1.0", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php72": "~1.0", + "voku/portable-ascii": "~2.0.0" + }, + "require-dev": { + "phpunit/phpunit": "~6.0 || ~7.0 || ~9.0" + }, + "suggest": { + "ext-ctype": "Use Ctype for e.g. hexadecimal digit detection", + "ext-fileinfo": "Use Fileinfo for better binary file detection", + "ext-iconv": "Use iconv for best performance", + "ext-intl": "Use Intl for best performance", + "ext-json": "Use JSON for string detection", + "ext-mbstring": "Use Mbstring for best performance" + }, + "type": "library", + "autoload": { + "psr-4": { + "voku\\": "src/voku/" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "(Apache-2.0 or GPL-2.0)" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Hamid Sarfraz", + "homepage": "http://pageconfig.com/" + }, + { + "name": "Lars Moelleken", + "homepage": "http://www.moelleken.org/" + } + ], + "description": "Portable UTF-8 library - performance optimized (unicode) string functions for php.", + "homepage": "https://github.com/voku/portable-utf8", + "keywords": [ + "UTF", + "clean", + "php", + "unicode", + "utf-8", + "utf8" + ], + "support": { + "issues": "https://github.com/voku/portable-utf8/issues", + "source": "https://github.com/voku/portable-utf8/tree/6.0.2" + }, + "funding": [ + { + "url": "https://www.paypal.me/moelleken", + "type": "custom" + }, + { + "url": "https://github.com/voku", + "type": "github" + }, + { + "url": "https://opencollective.com/portable-utf8", + "type": "open_collective" + }, + { + "url": "https://www.patreon.com/voku", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/voku/portable-utf8", + "type": "tidelift" + } + ], + "time": "2022-01-24T19:06:57+00:00" } ], "packages-dev": [ { - "name": "composer/xdebug-handler", - "version": "1.4.0", + "name": "composer/pcre", + "version": "1.0.1", "source": { "type": "git", - "url": "https://github.com/composer/xdebug-handler.git", - "reference": "cbe23383749496fe0f373345208b79568e4bc248" + "url": "https://github.com/composer/pcre.git", + "reference": "67a32d7d6f9f560b726ab25a061b38ff3a80c560" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/cbe23383749496fe0f373345208b79568e4bc248", - "reference": "cbe23383749496fe0f373345208b79568e4bc248", + "url": "https://api.github.com/repos/composer/pcre/zipball/67a32d7d6f9f560b726ab25a061b38ff3a80c560", + "reference": "67a32d7d6f9f560b726ab25a061b38ff3a80c560", "shasum": "" }, "require": { - "php": "^5.3.2 || ^7.0 || ^8.0", - "psr/log": "^1.0" + "php": "^5.3.2 || ^7.0 || ^8.0" }, "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 8" + "phpstan/phpstan": "^1.3", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.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/1.0.1" + }, + "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-01-21T20:24:37+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "0c1a3925ec58a4ec98e992b9c7d171e9e184be0a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/0c1a3925ec58a4ec98e992b9c7d171e9e184be0a", + "reference": "0c1a3925ec58a4ec98e992b9c7d171e9e184be0a", + "shasum": "" + }, + "require": { + "composer/pcre": "^1", + "php": "^5.3.2 || ^7.0 || ^8.0", + "psr/log": "^1 || ^2 || ^3" + }, + "require-dev": { + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^4.2 || ^5.0 || ^6.0" }, "type": "library", "autoload": { @@ -341,40 +1127,54 @@ "Xdebug", "performance" ], - "time": "2019-11-06T16:40:04+00:00" + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/2.0.4" + }, + "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-01-04T17:06:45+00:00" }, { "name": "doctrine/instantiator", - "version": "1.3.0", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "ae466f726242e637cebdd526a7d991b9433bacf1" + "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/ae466f726242e637cebdd526a7d991b9433bacf1", - "reference": "ae466f726242e637cebdd526a7d991b9433bacf1", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b", + "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b", "shasum": "" }, "require": { - "php": "^7.1" + "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^6.0", + "doctrine/coding-standard": "^8.0", "ext-pdo": "*", "ext-phar": "*", - "phpbench/phpbench": "^0.13", - "phpstan/phpstan-phpunit": "^0.11", - "phpstan/phpstan-shim": "^0.11", - "phpunit/phpunit": "^7.0" + "phpbench/phpbench": "^0.13 || 1.0.0-alpha2", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, "autoload": { "psr-4": { "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" @@ -388,7 +1188,7 @@ { "name": "Marco Pivetta", "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/" + "homepage": "https://ocramius.github.io/" } ], "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", @@ -397,27 +1197,42 @@ "constructor", "instantiate" ], - "time": "2019-10-21T16:45:58+00:00" + "support": { + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/1.4.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%2Finstantiator", + "type": "tidelift" + } + ], + "time": "2020-11-10T18:47:58+00:00" }, { "name": "myclabs/deep-copy", - "version": "1.9.4", + "version": "1.10.2", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "579bb7356d91f9456ccd505f24ca8b667966a0a7" + "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/579bb7356d91f9456ccd505f24ca8b667966a0a7", - "reference": "579bb7356d91f9456ccd505f24ca8b667966a0a7", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220", + "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220", "shasum": "" }, "require": { - "php": "^7.1" - }, - "replace": { - "myclabs/deep-copy": "self.version" + "php": "^7.1 || ^8.0" }, "require-dev": { "doctrine/collections": "^1.0", @@ -445,20 +1260,30 @@ "object", "object graph" ], - "time": "2019-12-15T19:12:40+00:00" + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.10.2" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2020-11-13T09:40:50+00:00" }, { "name": "nikic/php-parser", - "version": "v4.3.0", + "version": "v4.13.2", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "9a9981c347c5c49d6dfe5cf826bb882b824080dc" + "reference": "210577fe3cf7badcc5814d99455df46564f3c077" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/9a9981c347c5c49d6dfe5cf826bb882b824080dc", - "reference": "9a9981c347c5c49d6dfe5cf826bb882b824080dc", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/210577fe3cf7badcc5814d99455df46564f3c077", + "reference": "210577fe3cf7badcc5814d99455df46564f3c077", "shasum": "" }, "require": { @@ -466,8 +1291,8 @@ "php": ">=7.0" }, "require-dev": { - "ircmaxell/php-yacc": "0.0.5", - "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0" + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" }, "bin": [ "bin/php-parse" @@ -475,7 +1300,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.9-dev" } }, "autoload": { @@ -497,20 +1322,24 @@ "parser", "php" ], - "time": "2019-11-08T13:50:10+00:00" + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.2" + }, + "time": "2021-11-30T19:35:32+00:00" }, { "name": "pdepend/pdepend", - "version": "2.6.1", + "version": "2.10.2", "source": { "type": "git", "url": "https://github.com/pdepend/pdepend.git", - "reference": "395b0f356bc0881ef88864bffb4ba1423ca0d111" + "reference": "c8c1d2af43fb8c2b5387d50e9c42a9c56de13686" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pdepend/pdepend/zipball/395b0f356bc0881ef88864bffb4ba1423ca0d111", - "reference": "395b0f356bc0881ef88864bffb4ba1423ca0d111", + "url": "https://api.github.com/repos/pdepend/pdepend/zipball/c8c1d2af43fb8c2b5387d50e9c42a9c56de13686", + "reference": "c8c1d2af43fb8c2b5387d50e9c42a9c56de13686", "shasum": "" }, "require": { @@ -520,9 +1349,9 @@ "symfony/filesystem": "^2.3.0|^3|^4|^5" }, "require-dev": { - "easy-doc/easy-doc": "0.0.0 || ^1.2.3", + "easy-doc/easy-doc": "0.0.0|^1.2.3", "gregwar/rst": "^1.0", - "phpunit/phpunit": "^4.8.35|^5.7", + "phpunit/phpunit": "^4.8.36|^5.7.27", "squizlabs/php_codesniffer": "^2.0.0" }, "bin": [ @@ -544,32 +1373,43 @@ "BSD-3-Clause" ], "description": "Official version of pdepend to be handled with Composer", - "time": "2019-12-21T16:33:56+00:00" + "support": { + "issues": "https://github.com/pdepend/pdepend/issues", + "source": "https://github.com/pdepend/pdepend/tree/2.10.2" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/pdepend/pdepend", + "type": "tidelift" + } + ], + "time": "2021-11-16T20:05:32+00:00" }, { "name": "phar-io/manifest", - "version": "1.0.3", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/phar-io/manifest.git", - "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4" + "reference": "97803eca37d319dfa7826cc2437fc020857acb53" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", - "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53", "shasum": "" }, "require": { "ext-dom": "*", "ext-phar": "*", - "phar-io/version": "^2.0", - "php": "^5.6 || ^7.0" + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -599,24 +1439,28 @@ } ], "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "time": "2018-07-08T19:23:20+00:00" + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.3" + }, + "time": "2021-07-20T11:28:43+00:00" }, { "name": "phar-io/version", - "version": "2.0.1", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/phar-io/version.git", - "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6" + "reference": "bae7c545bef187884426f042434e561ab1ddb182" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6", - "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6", + "url": "https://api.github.com/repos/phar-io/version/zipball/bae7c545bef187884426f042434e561ab1ddb182", + "reference": "bae7c545bef187884426f042434e561ab1ddb182", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0" + "php": "^7.2 || ^8.0" }, "type": "library", "autoload": { @@ -646,7 +1490,11 @@ } ], "description": "Library for handling version information and constraints", - "time": "2018-07-08T19:19:57+00:00" + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.1.0" + }, + "time": "2021-02-23T14:00:09+00:00" }, { "name": "phpcompatibility/php-compatibility", @@ -704,32 +1552,33 @@ "phpcs", "standards" ], + "support": { + "issues": "https://github.com/PHPCompatibility/PHPCompatibility/issues", + "source": "https://github.com/PHPCompatibility/PHPCompatibility" + }, "time": "2019-12-27T09:44:58+00:00" }, { "name": "phpdocumentor/reflection-common", - "version": "2.0.0", + "version": "2.2.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a" + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/63a995caa1ca9e5590304cd845c15ad6d482a62a", - "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", "shasum": "" }, "require": { - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "~6" + "php": "^7.2 || ^8.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.x-dev" + "dev-2.x": "2.x-dev" } }, "autoload": { @@ -756,45 +1605,46 @@ "reflection", "static analysis" ], - "time": "2018-08-07T13:53:10+00:00" + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, + "time": "2020-06-27T09:03:43+00:00" }, { "name": "phpdocumentor/reflection-docblock", - "version": "4.3.4", + "version": "5.3.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "da3fd972d6bafd628114f7e7e036f45944b62e9c" + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/da3fd972d6bafd628114f7e7e036f45944b62e9c", - "reference": "da3fd972d6bafd628114f7e7e036f45944b62e9c", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", "shasum": "" }, "require": { - "php": "^7.0", - "phpdocumentor/reflection-common": "^1.0.0 || ^2.0.0", - "phpdocumentor/type-resolver": "~0.4 || ^1.0.0", - "webmozart/assert": "^1.0" + "ext-filter": "*", + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^1.3", + "webmozart/assert": "^1.9.1" }, "require-dev": { - "doctrine/instantiator": "^1.0.5", - "mockery/mockery": "^1.0", - "phpdocumentor/type-resolver": "0.4.*", - "phpunit/phpunit": "^6.4" + "mockery/mockery": "~1.3.2", + "psalm/phar": "^4.8" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.x-dev" + "dev-master": "5.x-dev" } }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] + "phpDocumentor\\Reflection\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -805,38 +1655,45 @@ { "name": "Mike van Riel", "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "account@ijaap.nl" } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2019-12-28T18:55:12+00:00" + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" + }, + "time": "2021-10-19T17:43:47+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "1.0.1", + "version": "1.6.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9" + "reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/2e32a6d48972b2c1976ed5d8967145b6cec4a4a9", - "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/93ebd0014cab80c4ea9f5e297ea48672f1b87706", + "reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706", "shasum": "" }, "require": { - "php": "^7.1", + "php": "^7.2 || ^8.0", "phpdocumentor/reflection-common": "^2.0" }, "require-dev": { - "ext-tokenizer": "^7.1", - "mockery/mockery": "~1", - "phpunit/phpunit": "^7.0" + "ext-tokenizer": "*", + "psalm/phar": "^4.8" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.x-dev" + "dev-1.x": "1.x-dev" } }, "autoload": { @@ -855,27 +1712,33 @@ } ], "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "time": "2019-08-22T18:11:29+00:00" + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.0" + }, + "time": "2022-01-04T19:58:01+00:00" }, { "name": "phploc/phploc", - "version": "5.0.0", + "version": "7.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phploc.git", - "reference": "5b714ccb7cb8ca29ccf9caf6eb1aed0131d3a884" + "reference": "af0d5fc84f3f7725513ba59cdcbe670ac2a4532a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phploc/zipball/5b714ccb7cb8ca29ccf9caf6eb1aed0131d3a884", - "reference": "5b714ccb7cb8ca29ccf9caf6eb1aed0131d3a884", + "url": "https://api.github.com/repos/sebastianbergmann/phploc/zipball/af0d5fc84f3f7725513ba59cdcbe670ac2a4532a", + "reference": "af0d5fc84f3f7725513ba59cdcbe670ac2a4532a", "shasum": "" }, "require": { - "php": "^7.2", - "sebastian/finder-facade": "^1.1", - "sebastian/version": "^2.0", - "symfony/console": "^4.0" + "ext-dom": "*", + "ext-json": "*", + "php": ">=7.3", + "phpunit/php-file-iterator": "^3.0", + "sebastian/cli-parser": "^1.0", + "sebastian/version": "^3.0" }, "bin": [ "phploc" @@ -883,7 +1746,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "5.0-dev" + "dev-master": "7.0-dev" } }, "autoload": { @@ -904,32 +1767,44 @@ ], "description": "A tool for quickly measuring the size of a PHP project.", "homepage": "https://github.com/sebastianbergmann/phploc", - "time": "2019-03-16T10:41:19+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/phploc/issues", + "source": "https://github.com/sebastianbergmann/phploc/tree/7.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-12-07T05:51:20+00:00" }, { "name": "phpmd/phpmd", - "version": "2.8.1", + "version": "2.11.1", "source": { "type": "git", "url": "https://github.com/phpmd/phpmd.git", - "reference": "5664b95d484797582f5af9536238deb9ecde58a1" + "reference": "08b60a2eb7e14c23f46ff8865b510ae08b75d0fd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpmd/phpmd/zipball/5664b95d484797582f5af9536238deb9ecde58a1", - "reference": "5664b95d484797582f5af9536238deb9ecde58a1", + "url": "https://api.github.com/repos/phpmd/phpmd/zipball/08b60a2eb7e14c23f46ff8865b510ae08b75d0fd", + "reference": "08b60a2eb7e14c23f46ff8865b510ae08b75d0fd", "shasum": "" }, "require": { - "composer/xdebug-handler": "^1.0", + "composer/xdebug-handler": "^1.0 || ^2.0", "ext-xml": "*", - "pdepend/pdepend": "^2.6", + "pdepend/pdepend": "^2.10.2", "php": ">=5.3.9" }, "require-dev": { "easy-doc/easy-doc": "0.0.0 || ^1.3.2", + "ext-json": "*", + "ext-simplexml": "*", "gregwar/rst": "^1.0", - "mikey179/vfsstream": "^1.6.4", + "mikey179/vfsstream": "^1.6.8", "phpunit/phpunit": "^4.8.36 || ^5.7.27", "squizlabs/php_codesniffer": "^2.0" }, @@ -974,37 +1849,48 @@ "phpmd", "pmd" ], - "time": "2019-12-27T11:09:06+00:00" + "support": { + "irc": "irc://irc.freenode.org/phpmd", + "issues": "https://github.com/phpmd/phpmd/issues", + "source": "https://github.com/phpmd/phpmd/tree/2.11.1" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/phpmd/phpmd", + "type": "tidelift" + } + ], + "time": "2021-12-17T11:25:43+00:00" }, { "name": "phpspec/prophecy", - "version": "1.10.1", + "version": "v1.15.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "cbe1df668b3fe136bcc909126a0f529a78d4cbbc" + "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/cbe1df668b3fe136bcc909126a0f529a78d4cbbc", - "reference": "cbe1df668b3fe136bcc909126a0f529a78d4cbbc", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13", + "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.0.2", - "php": "^5.3|^7.0", - "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0", - "sebastian/comparator": "^1.2.3|^2.0|^3.0", - "sebastian/recursion-context": "^1.0|^2.0|^3.0" + "doctrine/instantiator": "^1.2", + "php": "^7.2 || ~8.0, <8.2", + "phpdocumentor/reflection-docblock": "^5.2", + "sebastian/comparator": "^3.0 || ^4.0", + "sebastian/recursion-context": "^3.0 || ^4.0" }, "require-dev": { - "phpspec/phpspec": "^2.5 || ^3.2", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" + "phpspec/phpspec": "^6.0 || ^7.0", + "phpunit/phpunit": "^8.0 || ^9.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.10.x-dev" + "dev-master": "1.x-dev" } }, "autoload": { @@ -1037,44 +1923,52 @@ "spy", "stub" ], - "time": "2019-12-22T21:05:45+00:00" + "support": { + "issues": "https://github.com/phpspec/prophecy/issues", + "source": "https://github.com/phpspec/prophecy/tree/v1.15.0" + }, + "time": "2021-12-08T12:19:24+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "7.0.10", + "version": "9.2.10", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "f1884187926fbb755a9aaf0b3836ad3165b478bf" + "reference": "d5850aaf931743067f4bfc1ae4cbd06468400687" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f1884187926fbb755a9aaf0b3836ad3165b478bf", - "reference": "f1884187926fbb755a9aaf0b3836ad3165b478bf", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/d5850aaf931743067f4bfc1ae4cbd06468400687", + "reference": "d5850aaf931743067f4bfc1ae4cbd06468400687", "shasum": "" }, "require": { "ext-dom": "*", + "ext-libxml": "*", "ext-xmlwriter": "*", - "php": "^7.2", - "phpunit/php-file-iterator": "^2.0.2", - "phpunit/php-text-template": "^1.2.1", - "phpunit/php-token-stream": "^3.1.1", - "sebastian/code-unit-reverse-lookup": "^1.0.1", - "sebastian/environment": "^4.2.2", - "sebastian/version": "^2.0.1", - "theseer/tokenizer": "^1.1.3" + "nikic/php-parser": "^4.13.0", + "php": ">=7.3", + "phpunit/php-file-iterator": "^3.0.3", + "phpunit/php-text-template": "^2.0.2", + "sebastian/code-unit-reverse-lookup": "^2.0.2", + "sebastian/complexity": "^2.0", + "sebastian/environment": "^5.1.2", + "sebastian/lines-of-code": "^1.0.3", + "sebastian/version": "^3.0.1", + "theseer/tokenizer": "^1.2.0" }, "require-dev": { - "phpunit/phpunit": "^8.2.2" + "phpunit/phpunit": "^9.3" }, "suggest": { - "ext-xdebug": "^2.7.2" + "ext-pcov": "*", + "ext-xdebug": "*" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "7.0-dev" + "dev-master": "9.2-dev" } }, "autoload": { @@ -1100,32 +1994,42 @@ "testing", "xunit" ], - "time": "2019-11-20T13:55:58+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.10" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-12-05T09:12:13+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "2.0.2", + "version": "3.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "050bedf145a257b1ff02746c31894800e5122946" + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/050bedf145a257b1ff02746c31894800e5122946", - "reference": "050bedf145a257b1ff02746c31894800e5122946", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", "shasum": "" }, "require": { - "php": "^7.1" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^7.1" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -1150,26 +2054,107 @@ "filesystem", "iterator" ], - "time": "2018-09-13T20:33:42+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-12-02T12:48:52+00:00" }, { - "name": "phpunit/php-text-template", - "version": "1.2.1", + "name": "phpunit/php-invoker", + "version": "3.1.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.3" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcntl": "*" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:58:55+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, "autoload": { "classmap": [ "src/" @@ -1191,32 +2176,42 @@ "keywords": [ "template" ], - "time": "2015-06-21T13:50:34+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T05:33:50+00:00" }, { "name": "phpunit/php-timer", - "version": "2.1.2", + "version": "5.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "1038454804406b0b5f5f520358e78c1c2f71501e" + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/1038454804406b0b5f5f520358e78c1c2f71501e", - "reference": "1038454804406b0b5f5f520358e78c1c2f71501e", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", "shasum": "" }, "require": { - "php": "^7.1" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^7.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "5.0-dev" } }, "autoload": { @@ -1240,105 +2235,69 @@ "keywords": [ "timer" ], - "time": "2019-06-07T04:22:29+00:00" - }, - { - "name": "phpunit/php-token-stream", - "version": "3.1.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "995192df77f63a59e47f025390d2d1fdf8f425ff" + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/995192df77f63a59e47f025390d2d1fdf8f425ff", - "reference": "995192df77f63a59e47f025390d2d1fdf8f425ff", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": "^7.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ + "funding": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "url": "https://github.com/sebastianbergmann", + "type": "github" } ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "https://github.com/sebastianbergmann/php-token-stream/", - "keywords": [ - "tokenizer" - ], - "time": "2019-09-17T06:23:10+00:00" + "time": "2020-10-26T13:16:10+00:00" }, { "name": "phpunit/phpunit", - "version": "8.4.1", + "version": "9.5.13", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "366a4a0f2b971fd43b7c351d621e8dd7d7131869" + "reference": "597cb647654ede35e43b137926dfdfef0fb11743" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/366a4a0f2b971fd43b7c351d621e8dd7d7131869", - "reference": "366a4a0f2b971fd43b7c351d621e8dd7d7131869", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/597cb647654ede35e43b137926dfdfef0fb11743", + "reference": "597cb647654ede35e43b137926dfdfef0fb11743", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.2.0", + "doctrine/instantiator": "^1.3.1", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", "ext-mbstring": "*", "ext-xml": "*", "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.9.1", - "phar-io/manifest": "^1.0.3", - "phar-io/version": "^2.0.1", - "php": "^7.2", - "phpspec/prophecy": "^1.8.1", - "phpunit/php-code-coverage": "^7.0.7", - "phpunit/php-file-iterator": "^2.0.2", - "phpunit/php-text-template": "^1.2.1", - "phpunit/php-timer": "^2.1.2", - "sebastian/comparator": "^3.0.2", - "sebastian/diff": "^3.0.2", - "sebastian/environment": "^4.2.2", - "sebastian/exporter": "^3.1.1", - "sebastian/global-state": "^3.0.0", - "sebastian/object-enumerator": "^3.0.3", - "sebastian/resource-operations": "^2.0.1", - "sebastian/type": "^1.1.3", - "sebastian/version": "^2.0.1" + "myclabs/deep-copy": "^1.10.1", + "phar-io/manifest": "^2.0.3", + "phar-io/version": "^3.0.2", + "php": ">=7.3", + "phpspec/prophecy": "^1.12.1", + "phpunit/php-code-coverage": "^9.2.7", + "phpunit/php-file-iterator": "^3.0.5", + "phpunit/php-invoker": "^3.1.1", + "phpunit/php-text-template": "^2.0.3", + "phpunit/php-timer": "^5.0.2", + "sebastian/cli-parser": "^1.0.1", + "sebastian/code-unit": "^1.0.6", + "sebastian/comparator": "^4.0.5", + "sebastian/diff": "^4.0.3", + "sebastian/environment": "^5.1.3", + "sebastian/exporter": "^4.0.3", + "sebastian/global-state": "^5.0.1", + "sebastian/object-enumerator": "^4.0.3", + "sebastian/resource-operations": "^3.0.3", + "sebastian/type": "^2.3.4", + "sebastian/version": "^3.0.2" }, "require-dev": { - "ext-pdo": "*" + "ext-pdo": "*", + "phpspec/prophecy-phpunit": "^2.0.1" }, "suggest": { "ext-soap": "*", - "ext-xdebug": "*", - "phpunit/php-invoker": "^2.0.0" + "ext-xdebug": "*" }, "bin": [ "phpunit" @@ -1346,12 +2305,15 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "8.4-dev" + "dev-master": "9.5-dev" } }, "autoload": { "classmap": [ "src/" + ], + "files": [ + "src/Framework/Assert/Functions.php" ] }, "notification-url": "https://packagist.org/downloads/", @@ -1372,31 +2334,40 @@ "testing", "xunit" ], - "time": "2019-10-07T12:57:41+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.13" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-01-24T07:33:35+00:00" }, { "name": "psr/container", - "version": "1.0.0", + "version": "1.1.2", "source": { "type": "git", "url": "https://github.com/php-fig/container.git", - "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", - "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", + "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=7.4.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, "autoload": { "psr-4": { "Psr\\Container\\": "src/" @@ -1409,7 +2380,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common Container Interface (PHP FIG PSR-11)", @@ -1421,32 +2392,148 @@ "container-interop", "psr" ], - "time": "2017-02-14T16:28:37+00:00" + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/1.1.2" + }, + "time": "2021-11-05T16:50:12+00:00" }, { - "name": "sebastian/code-unit-reverse-lookup", + "name": "sebastian/cli-parser", "version": "1.0.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", - "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^5.7 || ^6.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:08:49+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "1.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:08:54+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" } }, "autoload": { @@ -1466,34 +2553,44 @@ ], "description": "Looks up which function or method a line of code belongs to", "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "time": "2017-03-04T06:30:41+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:30:19+00:00" }, { "name": "sebastian/comparator", - "version": "3.0.2", + "version": "4.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da" + "reference": "55f4261989e546dc112258c7a75935a81a7ce382" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/5de4fc177adf9bce8df98d8d141a7559d7ccf6da", - "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55f4261989e546dc112258c7a75935a81a7ce382", + "reference": "55f4261989e546dc112258c7a75935a81a7ce382", "shasum": "" }, "require": { - "php": "^7.1", - "sebastian/diff": "^3.0", - "sebastian/exporter": "^3.1" + "php": ">=7.3", + "sebastian/diff": "^4.0", + "sebastian/exporter": "^4.0" }, "require-dev": { - "phpunit/phpunit": "^7.1" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -1506,6 +2603,10 @@ "BSD-3-Clause" ], "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" @@ -1517,10 +2618,6 @@ { "name": "Bernhard Schussek", "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" } ], "description": "Provides the functionality to compare PHP values for equality", @@ -1530,33 +2627,43 @@ "compare", "equality" ], - "time": "2018-07-12T15:12:46+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T15:49:45+00:00" }, { - "name": "sebastian/diff", - "version": "3.0.2", + "name": "sebastian/complexity", + "version": "2.0.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29" + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/720fcc7e9b5cf384ea68d9d930d480907a0c1a29", - "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", "shasum": "" }, "require": { - "php": "^7.1" + "nikic/php-parser": "^4.7", + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^7.5 || ^8.0", - "symfony/process": "^2 || ^3.3 || ^4" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "2.0-dev" } }, "autoload": { @@ -1570,12 +2677,69 @@ ], "authors": [ { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - }, + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T15:52:27+00:00" + }, + { + "name": "sebastian/diff", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.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", @@ -1586,27 +2750,37 @@ "unidiff", "unified diff" ], - "time": "2019-02-04T06:01:07+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:10:38+00:00" }, { "name": "sebastian/environment", - "version": "4.2.3", + "version": "5.1.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "464c90d7bdf5ad4e8a6aea15c091fec0603d4368" + "reference": "388b6ced16caa751030f6a69e588299fa09200ac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/464c90d7bdf5ad4e8a6aea15c091fec0603d4368", - "reference": "464c90d7bdf5ad4e8a6aea15c091fec0603d4368", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/388b6ced16caa751030f6a69e588299fa09200ac", + "reference": "388b6ced16caa751030f6a69e588299fa09200ac", "shasum": "" }, "require": { - "php": "^7.1" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^7.5" + "phpunit/phpunit": "^9.3" }, "suggest": { "ext-posix": "*" @@ -1614,7 +2788,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.2-dev" + "dev-master": "5.1-dev" } }, "autoload": { @@ -1639,34 +2813,44 @@ "environment", "hhvm" ], - "time": "2019-11-20T08:46:58+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:52:38+00:00" }, { "name": "sebastian/exporter", - "version": "3.1.2", + "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e" + "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/68609e1261d215ea5b21b7987539cbfbe156ec3e", - "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/65e8b7db476c5dd267e65eea9cab77584d3cfff9", + "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9", "shasum": "" }, "require": { - "php": "^7.0", - "sebastian/recursion-context": "^3.0" + "php": ">=7.3", + "sebastian/recursion-context": "^4.0" }, "require-dev": { "ext-mbstring": "*", - "phpunit/phpunit": "^6.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1.x-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -1701,74 +2885,45 @@ } ], "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "http://www.github.com/sebastianbergmann/exporter", + "homepage": "https://www.github.com/sebastianbergmann/exporter", "keywords": [ "export", "exporter" ], - "time": "2019-09-14T09:02:43+00:00" - }, - { - "name": "sebastian/finder-facade", - "version": "1.2.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/finder-facade.git", - "reference": "4a3174709c2dc565fe5fb26fcf827f6a1fc7b09f" + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.4" }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/finder-facade/zipball/4a3174709c2dc565fe5fb26fcf827f6a1fc7b09f", - "reference": "4a3174709c2dc565fe5fb26fcf827f6a1fc7b09f", - "shasum": "" - }, - "require": { - "symfony/finder": "~2.3|~3.0|~4.0", - "theseer/fdomdocument": "~1.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ + "funding": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "url": "https://github.com/sebastianbergmann", + "type": "github" } ], - "description": "FinderFacade is a convenience wrapper for Symfony's Finder component.", - "homepage": "https://github.com/sebastianbergmann/finder-facade", - "time": "2017-11-18T17:31:49+00:00" + "time": "2021-11-11T14:18:36+00:00" }, { "name": "sebastian/global-state", - "version": "3.0.0", + "version": "5.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4" + "reference": "23bd5951f7ff26f12d4e3242864df3e08dec4e49" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4", - "reference": "edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/23bd5951f7ff26f12d4e3242864df3e08dec4e49", + "reference": "23bd5951f7ff26f12d4e3242864df3e08dec4e49", "shasum": "" }, "require": { - "php": "^7.2", - "sebastian/object-reflector": "^1.1.1", - "sebastian/recursion-context": "^3.0" + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" }, "require-dev": { "ext-dom": "*", - "phpunit/phpunit": "^8.0" + "phpunit/phpunit": "^9.3" }, "suggest": { "ext-uopz": "*" @@ -1776,7 +2931,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "5.0-dev" } }, "autoload": { @@ -1799,34 +2954,101 @@ "keywords": [ "global state" ], - "time": "2019-02-01T05:30:01+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-06-11T13:31:12+00:00" }, { - "name": "sebastian/object-enumerator", - "version": "3.0.3", + "name": "sebastian/lines-of-code", + "version": "1.0.3", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", - "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", "shasum": "" }, "require": { - "php": "^7.0", - "sebastian/object-reflector": "^1.1.1", - "sebastian/recursion-context": "^3.0" + "nikic/php-parser": "^4.6", + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0.x-dev" + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-28T06:42:11+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" } }, "autoload": { @@ -1846,173 +3068,37 @@ ], "description": "Traverses array structures and object graphs to enumerate all referenced objects", "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "time": "2017-08-03T12:35:26+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:12:34+00:00" }, { "name": "sebastian/object-reflector", - "version": "1.1.1", + "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "773f97c67f28de00d397be301821b06708fca0be" + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", - "reference": "773f97c67f28de00d397be301821b06708fca0be", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", "shasum": "" }, "require": { - "php": "^7.0" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Allows reflection of object attributes, including inherited and non-public ones", - "homepage": "https://github.com/sebastianbergmann/object-reflector/", - "time": "2017-03-29T09:07:27+00:00" - }, - { - "name": "sebastian/phpcpd", - "version": "4.1.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpcpd.git", - "reference": "0d9afa762f2400de077b2192f4a9d127de0bb78e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpcpd/zipball/0d9afa762f2400de077b2192f4a9d127de0bb78e", - "reference": "0d9afa762f2400de077b2192f4a9d127de0bb78e", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "php": "^7.1", - "phpunit/php-timer": "^2.0", - "sebastian/finder-facade": "^1.1", - "sebastian/version": "^1.0|^2.0", - "symfony/console": "^2.7|^3.0|^4.0" - }, - "bin": [ - "phpcpd" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Copy/Paste Detector (CPD) for PHP code.", - "homepage": "https://github.com/sebastianbergmann/phpcpd", - "time": "2018-09-17T17:17:27+00:00" - }, - { - "name": "sebastian/recursion-context", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", - "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2017-03-03T06:23:57+00:00" - }, - { - "name": "sebastian/resource-operations", - "version": "2.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/4d7a795d35b889bf80a0cc04e08d77cedfa917a9", - "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9", - "shasum": "" - }, - "require": { - "php": "^7.1" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { @@ -2035,34 +3121,223 @@ "email": "sebastian@phpunit.de" } ], - "description": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "time": "2018-10-04T04:07:39+00:00" + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:14:26+00:00" }, { - "name": "sebastian/type", - "version": "1.1.3", + "name": "sebastian/phpcpd", + "version": "6.0.3", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/type.git", - "reference": "3aaaa15fa71d27650d62a948be022fe3b48541a3" + "url": "https://github.com/sebastianbergmann/phpcpd.git", + "reference": "f3683aa0db2e8e09287c2bb33a595b2873ea9176" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/3aaaa15fa71d27650d62a948be022fe3b48541a3", - "reference": "3aaaa15fa71d27650d62a948be022fe3b48541a3", + "url": "https://api.github.com/repos/sebastianbergmann/phpcpd/zipball/f3683aa0db2e8e09287c2bb33a595b2873ea9176", + "reference": "f3683aa0db2e8e09287c2bb33a595b2873ea9176", "shasum": "" }, "require": { - "php": "^7.2" + "ext-dom": "*", + "php": ">=7.3", + "phpunit/php-file-iterator": "^3.0", + "phpunit/php-timer": "^5.0", + "sebastian/cli-parser": "^1.0", + "sebastian/version": "^3.0" + }, + "bin": [ + "phpcpd" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Copy/Paste Detector (CPD) for PHP code.", + "homepage": "https://github.com/sebastianbergmann/phpcpd", + "support": { + "issues": "https://github.com/sebastianbergmann/phpcpd/issues", + "source": "https://github.com/sebastianbergmann/phpcpd/tree/6.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-12-07T05:39:23+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", + "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", + "shasum": "" + }, + "require": { + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^8.2" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1-dev" + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:17:30+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "support": { + "issues": "https://github.com/sebastianbergmann/resource-operations/issues", + "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:45:17+00:00" + }, + { + "name": "sebastian/type", + "version": "2.3.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b8cd8a1c753c90bc1a0f5372170e3e489136f914", + "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3-dev" } }, "autoload": { @@ -2083,29 +3358,39 @@ ], "description": "Collection of value objects that represent the types of the PHP type system", "homepage": "https://github.com/sebastianbergmann/type", - "time": "2019-07-02T08:10:15+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/2.3.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-06-15T12:49:02+00:00" }, { "name": "sebastian/version", - "version": "2.0.1", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + "reference": "c6c1022351a901512170118436c764e473f6de8c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", + "reference": "c6c1022351a901512170118436c764e473f6de8c", "shasum": "" }, "require": { - "php": ">=5.6" + "php": ">=7.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -2126,20 +3411,30 @@ ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", - "time": "2016-10-03T07:35:21+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:39:44+00:00" }, { "name": "squizlabs/php_codesniffer", - "version": "3.5.3", + "version": "3.6.2", "source": { "type": "git", "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "557a1fc7ac702c66b0bbfe16ab3d55839ef724cb" + "reference": "5e4e71592f69da17871dba6e80dd51bce74a351a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/557a1fc7ac702c66b0bbfe16ab3d55839ef724cb", - "reference": "557a1fc7ac702c66b0bbfe16ab3d55839ef724cb", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/5e4e71592f69da17871dba6e80dd51bce74a351a", + "reference": "5e4e71592f69da17871dba6e80dd51bce74a351a", "shasum": "" }, "require": { @@ -2177,46 +3472,49 @@ "phpcs", "standards" ], - "time": "2019-12-04T04:46:47+00:00" + "support": { + "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", + "source": "https://github.com/squizlabs/PHP_CodeSniffer", + "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" + }, + "time": "2021-12-12T21:44:58+00:00" }, { "name": "symfony/config", - "version": "v5.0.2", + "version": "v5.4.2", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "7f930484966350906185ba0a604728f7898b7ba0" + "reference": "2e082dae50da563c639119b7b52347a2a3db4ba5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/7f930484966350906185ba0a604728f7898b7ba0", - "reference": "7f930484966350906185ba0a604728f7898b7ba0", + "url": "https://api.github.com/repos/symfony/config/zipball/2e082dae50da563c639119b7b52347a2a3db4ba5", + "reference": "2e082dae50da563c639119b7b52347a2a3db4ba5", "shasum": "" }, "require": { - "php": "^7.2.5", - "symfony/filesystem": "^4.4|^5.0", - "symfony/polyfill-ctype": "~1.8" + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/filesystem": "^4.4|^5.0|^6.0", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-php80": "^1.16", + "symfony/polyfill-php81": "^1.22" }, "conflict": { "symfony/finder": "<4.4" }, "require-dev": { - "symfony/event-dispatcher": "^4.4|^5.0", - "symfony/finder": "^4.4|^5.0", - "symfony/messenger": "^4.4|^5.0", - "symfony/service-contracts": "^1.1|^2", - "symfony/yaml": "^4.4|^5.0" + "symfony/event-dispatcher": "^4.4|^5.0|^6.0", + "symfony/finder": "^4.4|^5.0|^6.0", + "symfony/messenger": "^4.4|^5.0|^6.0", + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/yaml": "^4.4|^5.0|^6.0" }, "suggest": { "symfony/yaml": "To use the yaml reference dumper" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\Config\\": "" @@ -2239,119 +3537,64 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Config Component", + "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com", - "time": "2019-12-18T13:50:31+00:00" - }, - { - "name": "symfony/console", - "version": "v4.4.2", - "source": { - "type": "git", - "url": "https://github.com/symfony/console.git", - "reference": "82437719dab1e6bdd28726af14cb345c2ec816d0" + "support": { + "source": "https://github.com/symfony/config/tree/v5.4.2" }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/82437719dab1e6bdd28726af14cb345c2ec816d0", - "reference": "82437719dab1e6bdd28726af14cb345c2ec816d0", - "shasum": "" - }, - "require": { - "php": "^7.1.3", - "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php73": "^1.8", - "symfony/service-contracts": "^1.1|^2" - }, - "conflict": { - "symfony/dependency-injection": "<3.4", - "symfony/event-dispatcher": "<4.3|>=5", - "symfony/lock": "<4.4", - "symfony/process": "<3.3" - }, - "provide": { - "psr/log-implementation": "1.0" - }, - "require-dev": { - "psr/log": "~1.0", - "symfony/config": "^3.4|^4.0|^5.0", - "symfony/dependency-injection": "^3.4|^4.0|^5.0", - "symfony/event-dispatcher": "^4.3", - "symfony/lock": "^4.4|^5.0", - "symfony/process": "^3.4|^4.0|^5.0", - "symfony/var-dumper": "^4.3|^5.0" - }, - "suggest": { - "psr/log": "For using the console logger", - "symfony/event-dispatcher": "", - "symfony/lock": "", - "symfony/process": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Console\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ + "funding": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "url": "https://symfony.com/sponsor", + "type": "custom" }, { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "description": "Symfony Console Component", - "homepage": "https://symfony.com", - "time": "2019-12-17T10:32:23+00:00" + "time": "2021-12-15T11:06:13+00:00" }, { "name": "symfony/dependency-injection", - "version": "v5.0.2", + "version": "v5.4.2", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "f9dbfbf487d08f60b1c83220edcd16559d1e40a2" + "reference": "ba94559be9738d77cd29e24b5d81cf3b89b7d628" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/f9dbfbf487d08f60b1c83220edcd16559d1e40a2", - "reference": "f9dbfbf487d08f60b1c83220edcd16559d1e40a2", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/ba94559be9738d77cd29e24b5d81cf3b89b7d628", + "reference": "ba94559be9738d77cd29e24b5d81cf3b89b7d628", "shasum": "" }, "require": { - "php": "^7.2.5", - "psr/container": "^1.0", + "php": ">=7.2.5", + "psr/container": "^1.1.1", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-php80": "^1.16", + "symfony/polyfill-php81": "^1.22", "symfony/service-contracts": "^1.1.6|^2" }, "conflict": { - "symfony/config": "<5.0", + "ext-psr": "<1.1|>=2", + "symfony/config": "<5.3", "symfony/finder": "<4.4", "symfony/proxy-manager-bridge": "<4.4", "symfony/yaml": "<4.4" }, "provide": { "psr/container-implementation": "1.0", - "symfony/service-implementation": "1.0" + "symfony/service-implementation": "1.0|2.0" }, "require-dev": { - "symfony/config": "^5.0", - "symfony/expression-language": "^4.4|^5.0", - "symfony/yaml": "^4.4|^5.0" + "symfony/config": "^5.3|^6.0", + "symfony/expression-language": "^4.4|^5.0|^6.0", + "symfony/yaml": "^4.4|^5.0|^6.0" }, "suggest": { "symfony/config": "", @@ -2361,11 +3604,6 @@ "symfony/yaml": "" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\DependencyInjection\\": "" @@ -2388,34 +3626,115 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony DependencyInjection Component", + "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", - "time": "2019-12-19T16:01:11+00:00" + "support": { + "source": "https://github.com/symfony/dependency-injection/tree/v5.4.2" + }, + "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": "2021-12-29T10:10:35+00:00" }, { - "name": "symfony/filesystem", - "version": "v5.0.2", + "name": "symfony/deprecation-contracts", + "version": "v2.5.0", "source": { "type": "git", - "url": "https://github.com/symfony/filesystem.git", - "reference": "1d71f670bc5a07b9ccc97dc44f932177a322d4e6" + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/1d71f670bc5a07b9ccc97dc44f932177a322d4e6", - "reference": "1d71f670bc5a07b9ccc97dc44f932177a322d4e6", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/6f981ee24cf69ee7ce9736146d1c57c2780598a8", + "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8", "shasum": "" }, "require": { - "php": "^7.2.5", - "symfony/polyfill-ctype": "~1.8" + "php": ">=7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.0-dev" + "dev-main": "2.5-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/v2.5.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": "2021-07-12T14:48:14+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v5.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "731f917dc31edcffec2c6a777f3698c33bea8f01" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/731f917dc31edcffec2c6a777f3698c33bea8f01", + "reference": "731f917dc31edcffec2c6a777f3698c33bea8f01", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8", + "symfony/polyfill-php80": "^1.16" + }, + "type": "library", "autoload": { "psr-4": { "Symfony\\Component\\Filesystem\\": "" @@ -2438,75 +3757,46 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Filesystem Component", + "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", - "time": "2019-11-26T23:25:11+00:00" - }, - { - "name": "symfony/finder", - "version": "v4.4.2", - "source": { - "type": "git", - "url": "https://github.com/symfony/finder.git", - "reference": "ce8743441da64c41e2a667b8eb66070444ed911e" + "support": { + "source": "https://github.com/symfony/filesystem/tree/v5.4.0" }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/ce8743441da64c41e2a667b8eb66070444ed911e", - "reference": "ce8743441da64c41e2a667b8eb66070444ed911e", - "shasum": "" - }, - "require": { - "php": "^7.1.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Finder\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ + "funding": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "url": "https://symfony.com/sponsor", + "type": "custom" }, { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "description": "Symfony Finder Component", - "homepage": "https://symfony.com", - "time": "2019-11-17T21:56:56+00:00" + "time": "2021-10-28T13:39:27+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.13.1", + "version": "v1.24.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "f8f0b461be3385e56d6de3dbb5a0df24c0c275e3" + "reference": "30885182c981ab175d4d034db0f6f469898070ab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/f8f0b461be3385e56d6de3dbb5a0df24c0c275e3", - "reference": "f8f0b461be3385e56d6de3dbb5a0df24c0c275e3", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab", + "reference": "30885182c981ab175d4d034db0f6f469898070ab", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" }, "suggest": { "ext-ctype": "For best performance" @@ -2514,7 +3804,11 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.13-dev" + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" } }, "autoload": { @@ -2547,40 +3841,61 @@ "polyfill", "portable" ], - "time": "2019-11-27T13:56:44+00:00" + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.24.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": "2021-10-20T20:35:02+00:00" }, { - "name": "symfony/polyfill-mbstring", - "version": "v1.13.1", + "name": "symfony/polyfill-php80", + "version": "v1.24.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "7b4aab9743c30be783b73de055d24a39cf4b954f" + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/7b4aab9743c30be783b73de055d24a39cf4b954f", - "reference": "7b4aab9743c30be783b73de055d24a39cf4b954f", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/57b712b08eddb97c762a8caa32c84e037892d2e9", + "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9", "shasum": "" }, "require": { - "php": ">=5.3.3" - }, - "suggest": { - "ext-mbstring": "For best performance" + "php": ">=7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.13-dev" + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" } }, "autoload": { "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" + "Symfony\\Polyfill\\Php80\\": "" }, "files": [ "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" ] }, "notification-url": "https://packagist.org/downloads/", @@ -2588,6 +3903,10 @@ "MIT" ], "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, { "name": "Nicolas Grekas", "email": "p@tchwork.com" @@ -2597,43 +3916,63 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill for the Mbstring extension", + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", "homepage": "https://symfony.com", "keywords": [ "compatibility", - "mbstring", "polyfill", "portable", "shim" ], - "time": "2019-11-27T14:18:11+00:00" + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.24.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": "2021-09-13T13:58:33+00:00" }, { - "name": "symfony/polyfill-php73", - "version": "v1.13.1", + "name": "symfony/polyfill-php81", + "version": "v1.24.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "4b0e2222c55a25b4541305a053013d5647d3a25f" + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "5de4ba2d41b15f9bd0e19b2ab9674135813ec98f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/4b0e2222c55a25b4541305a053013d5647d3a25f", - "reference": "4b0e2222c55a25b4541305a053013d5647d3a25f", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/5de4ba2d41b15f9bd0e19b2ab9674135813ec98f", + "reference": "5de4ba2d41b15f9bd0e19b2ab9674135813ec98f", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.13-dev" + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" } }, "autoload": { "psr-4": { - "Symfony\\Polyfill\\Php73\\": "" + "Symfony\\Polyfill\\Php81\\": "" }, "files": [ "bootstrap.php" @@ -2656,7 +3995,7 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", + "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", "homepage": "https://symfony.com", "keywords": [ "compatibility", @@ -2664,25 +4003,46 @@ "portable", "shim" ], - "time": "2019-11-27T16:25:15+00:00" + "support": { + "source": "https://github.com/symfony/polyfill-php81/tree/v1.24.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": "2021-09-13T13:58:11+00:00" }, { "name": "symfony/service-contracts", - "version": "v2.0.1", + "version": "v2.5.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "144c5e51266b281231e947b51223ba14acf1a749" + "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/144c5e51266b281231e947b51223ba14acf1a749", - "reference": "144c5e51266b281231e947b51223ba14acf1a749", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc", + "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc", "shasum": "" }, "require": { - "php": "^7.2.5", - "psr/container": "^1.0" + "php": ">=7.2.5", + "psr/container": "^1.1", + "symfony/deprecation-contracts": "^2.1" + }, + "conflict": { + "ext-psr": "<1.1|>=2" }, "suggest": { "symfony/service-implementation": "" @@ -2690,7 +4050,11 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "2.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" } }, "autoload": { @@ -2722,205 +4086,44 @@ "interoperability", "standards" ], - "time": "2019-11-18T17:27:11+00:00" - }, - { - "name": "theseer/directoryscanner", - "version": "1.3.2", - "source": { - "type": "git", - "url": "https://github.com/theseer/DirectoryScanner.git", - "reference": "549aa9fdbc47d50365db42d9ade35fdef65f854c" + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v2.5.0" }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/DirectoryScanner/zipball/549aa9fdbc47d50365db42d9ade35fdef65f854c", - "reference": "549aa9fdbc47d50365db42d9ade35fdef65f854c", - "shasum": "" - }, - "require": { - "php": ">=5.3.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-2-Clause" - ], - "authors": [ + "funding": [ { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - } - ], - "description": "A recursive directory scanner and filter", - "time": "2015-03-24T21:28:20+00:00" - }, - { - "name": "theseer/fdomdocument", - "version": "1.6.6", - "source": { - "type": "git", - "url": "https://github.com/theseer/fDOMDocument.git", - "reference": "6e8203e40a32a9c770bcb62fe37e68b948da6dca" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/fDOMDocument/zipball/6e8203e40a32a9c770bcb62fe37e68b948da6dca", - "reference": "6e8203e40a32a9c770bcb62fe37e68b948da6dca", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "lib-libxml": "*", - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ + "url": "https://symfony.com/sponsor", + "type": "custom" + }, { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "lead" - } - ], - "description": "The classes contained within this repository extend the standard DOM to use exceptions at all occasions of errors instead of PHP warnings or notices. They also add various custom methods and shortcuts for convenience and to simplify the usage of DOM.", - "homepage": "https://github.com/theseer/fDOMDocument", - "time": "2017-06-30T11:53:12+00:00" - }, - { - "name": "theseer/fxsl", - "version": "1.1.1", - "source": { - "type": "git", - "url": "https://github.com/theseer/fXSL.git", - "reference": "a9246376c713156e55c080782d4104bb07d4b899" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/fXSL/zipball/a9246376c713156e55c080782d4104bb07d4b899", - "reference": "a9246376c713156e55c080782d4104bb07d4b899", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-libxml": "*", - "ext-xsl": "*", - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-2-Clause" - ], - "authors": [ + "url": "https://github.com/fabpot", + "type": "github" + }, { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "description": "An XSL wrapper / extension to the PHP 5.x XSLTProcessor with Exception and extended Callback support", - "time": "2014-11-27T20:08:52+00:00" - }, - { - "name": "theseer/phpdox", - "version": "0.12.0", - "source": { - "type": "git", - "url": "https://github.com/theseer/phpdox.git", - "reference": "a46438e723a2b5bfd6ea4f299ecc0c7a1db1112c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/phpdox/zipball/a46438e723a2b5bfd6ea4f299ecc0c7a1db1112c", - "reference": "a46438e723a2b5bfd6ea4f299ecc0c7a1db1112c", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-fileinfo": "*", - "ext-iconv": "*", - "ext-mbstring": "*", - "ext-tokenizer": "*", - "ext-xsl": "*", - "nikic/php-parser": "^4.2", - "php": ">=7.1", - "phpunit/php-timer": "^2.0", - "theseer/directoryscanner": "^1.3.0", - "theseer/fdomdocument": "^1.6", - "theseer/fxsl": "^1.1" - }, - "bin": [ - "phpdox" - ], - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - } - ], - "description": "A fast Documentation generator for PHP Code using standard technology (SRC, DOCBLOCK, XML and XSLT) with event based processing", - "time": "2019-03-13T09:34:17+00:00" + "time": "2021-11-04T16:48:04+00:00" }, { "name": "theseer/tokenizer", - "version": "1.1.3", + "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9" + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/11336f6f84e16a720dae9d8e6ed5019efa85a0f9", - "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", "shasum": "" }, "require": { "ext-dom": "*", "ext-tokenizer": "*", "ext-xmlwriter": "*", - "php": "^7.0" + "php": "^7.2 || ^8.0" }, "type": "library", "autoload": { @@ -2940,33 +4143,49 @@ } ], "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", - "time": "2019-06-13T22:48:21+00:00" + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.2.1" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2021-07-28T10:34:58+00:00" }, { "name": "webmozart/assert", - "version": "1.6.0", + "version": "1.10.0", "source": { "type": "git", - "url": "https://github.com/webmozart/assert.git", - "reference": "573381c0a64f155a0d9a23f4b0c797194805b925" + "url": "https://github.com/webmozarts/assert.git", + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/573381c0a64f155a0d9a23f4b0c797194805b925", - "reference": "573381c0a64f155a0d9a23f4b0c797194805b925", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25", + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0", + "php": "^7.2 || ^8.0", "symfony/polyfill-ctype": "^1.8" }, "conflict": { - "vimeo/psalm": "<3.6.0" + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<4.6.1 || 4.6.2" }, "require-dev": { - "phpunit/phpunit": "^4.8.36 || ^7.5.13" + "phpunit/phpunit": "^8.5.13" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, "autoload": { "psr-4": { "Webmozart\\Assert\\": "src/" @@ -2988,7 +4207,11 @@ "check", "validate" ], - "time": "2019-11-24T13:36:37+00:00" + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.10.0" + }, + "time": "2021-03-09T10:59:23+00:00" } ], "aliases": [], @@ -2997,7 +4220,7 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">=7.0", + "php": "^7.1 || ^8.0", "ext-session": "*", "ext-ctype": "*", "ext-pdo": "*", @@ -3009,10 +4232,11 @@ "ext-mbstring": "*", "ext-curl": "*", "ext-json": "*", - "ext-openssl": "*" + "ext-openssl": "*", + "ext-fileinfo": "*" }, "platform-dev": { - "php": ">=7.3", "ext-pcntl": "*" - } + }, + "plugin-api-version": "2.2.0" } diff --git a/customer_domains.php b/customer_domains.php index ba285c95..26fe3833 100644 --- a/customer_domains.php +++ b/customer_domains.php @@ -42,7 +42,7 @@ if ($page == 'overview') { if ($action == '') { $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed customer_domains::domains"); $fields = array( - 'd.domain' => $lng['domains']['domainname'], + 'd.domain_ace' => $lng['domains']['domainname'], 'd.aliasdomain' => $lng['domains']['aliasdomain'] ); try { diff --git a/customer_email.php b/customer_email.php index d86372ac..d7ec2f80 100644 --- a/customer_email.php +++ b/customer_email.php @@ -19,7 +19,6 @@ define('AREA', 'customer'); require './lib/init.php'; -use Froxlor\Api\Commands\SubDomains; use Froxlor\Database\Database; use Froxlor\Settings; use Froxlor\Api\Commands\Emails as Emails; @@ -44,7 +43,7 @@ if ($page == 'overview') { if ($action == '') { $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed customer_email::emails"); $fields = array( - 'd.domain' => $lng['domains']['domainname'], + 'd.domain_ace' => $lng['domains']['domainname'], 'm.email_full' => $lng['emails']['emailaddress'], 'm.destination' => $lng['emails']['forwarders'] ); @@ -76,7 +75,7 @@ if ($page == 'overview') { $emails[$row['domain']][$row['email_full']] = $row; } - if ($paging->sortfield == 'd.domain' && $paging->sortorder == 'desc') { + if ($paging->sortfield == 'd.domain_ace' && $paging->sortorder == 'desc') { krsort($emails); } else { ksort($emails); @@ -129,16 +128,15 @@ if ($page == 'overview') { } } - $json_result = SubDomains::getLocal($userinfo, [ - 'sql_search' => [ - 'd.isemaildomain' => [ - 'value' => 1, - 'op' => '=' - ] - ] - ])->listing(); - $result = json_decode($json_result, true)['data']; - $emaildomains_count = $result['count']; + $result_stmt = Database::prepare(" + SELECT COUNT(`id`) as emaildomains + FROM `" . TABLE_PANEL_DOMAINS . "` + WHERE `customerid`= :cid AND `isemaildomain` = '1' + "); + $result2 = Database::pexecute_first($result_stmt, array( + "cid" => $userinfo['customerid'] + )); + $emaildomains_count = $result2['emaildomains']; eval("echo \"" . \Froxlor\UI\Template::getTemplate("email/emails") . "\";"); } elseif ($action == 'delete' && $id != 0) { @@ -155,7 +153,8 @@ if ($page == 'overview') { if (isset($_POST['send']) && $_POST['send'] == 'send') { try { Emails::getLocal($userinfo, array( - 'id' => $id + 'id' => $id, + 'delete_userfiles' => ($_POST['delete_userfiles'] ?? 0) ))->delete(); } catch (Exception $e) { \Froxlor\UI\Response::dynamic_error($e->getMessage()); @@ -196,7 +195,7 @@ if ($page == 'overview') { $result_stmt = Database::prepare("SELECT `id`, `domain`, `customerid` FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `customerid`= :cid AND `isemaildomain`='1' - ORDER BY `domain` ASC"); + ORDER BY `domain_ace` ASC"); Database::pexecute($result_stmt, array( "cid" => $userinfo['customerid'] )); diff --git a/customer_index.php b/customer_index.php index a164a16e..56a9afc7 100644 --- a/customer_index.php +++ b/customer_index.php @@ -93,22 +93,30 @@ if ($page == 'overview') { 'cid' => $userinfo['customerid'] )); - if ($usages) - { - $userinfo['diskspace_used'] = round($usages['webspace'] / 1024, Settings::Get('panel.decimal_places')); - $userinfo['mailspace_used'] = round($usages['mail'] / 1024, Settings::Get('panel.decimal_places')); - $userinfo['dbspace_used'] = round($usages['mysql'] / 1024, Settings::Get('panel.decimal_places')); - $userinfo['total_used'] = round(($usages['webspace'] + $usages['mail'] + $usages['mysql']) / 1024, Settings::Get('panel.decimal_places')); + // get everything in bytes for the percentage calculation on the dashboard + $userinfo['diskspace_bytes'] = ($userinfo['diskspace'] > -1) ? $userinfo['diskspace'] * 1024 : -1; + $userinfo['traffic_bytes'] = ($userinfo['traffic'] > -1) ? $userinfo['traffic'] * 1024 : - 1; + $userinfo['traffic_bytes_used'] = $userinfo['traffic_used'] * 1024; + + if ($usages) { + $userinfo['diskspace_used'] = \Froxlor\PhpHelper::sizeReadable($usages['webspace'] * 1024, null, 'bi'); + $userinfo['mailspace_used'] = \Froxlor\PhpHelper::sizeReadable($usages['mail'] * 1024, null, 'bi'); + $userinfo['dbspace_used'] = \Froxlor\PhpHelper::sizeReadable($usages['mysql'] * 1024, null, 'bi'); + $userinfo['total_used'] = \Froxlor\PhpHelper::sizeReadable(($usages['webspace'] + $usages['mail'] + $usages['mysql']) * 1024, null, 'bi'); + $userinfo['diskspace_bytes_used'] = $usages['webspace'] * 1024; + $userinfo['total_bytes_used'] = ($usages['webspace'] + $usages['mail'] + $usages['mysql']) * 1024; } else { $userinfo['diskspace_used'] = 0; $userinfo['mailspace_used'] = 0; $userinfo['dbspace_used'] = 0; $userinfo['total_used'] = 0; + $userinfo['diskspace_bytes_used'] = 0; + $userinfo['total_bytes_used'] = 0; } - $userinfo['diskspace'] = round($userinfo['diskspace'] / 1024, Settings::Get('panel.decimal_places')); - $userinfo['traffic'] = round($userinfo['traffic'] / (1024 * 1024), Settings::Get('panel.decimal_places')); - $userinfo['traffic_used'] = round($userinfo['traffic_used'] / (1024 * 1024), Settings::Get('panel.decimal_places')); - $userinfo = \Froxlor\PhpHelper::strReplaceArray('-1', $lng['customer']['unlimited'], $userinfo, 'diskspace traffic mysqls emails email_accounts email_forwarders email_quota ftps subdomains'); + $userinfo['diskspace'] = ($userinfo['diskspace'] > -1) ? \Froxlor\PhpHelper::sizeReadable($userinfo['diskspace'] * 1024, null, 'bi') : - 1; + $userinfo['traffic'] = ($userinfo['traffic'] > -1) ? \Froxlor\PhpHelper::sizeReadable($userinfo['traffic'] * 1024, null, 'bi') : - 1; + $userinfo['traffic_used'] = \Froxlor\PhpHelper::sizeReadable($userinfo['traffic_used'] * 1024, null, 'bi'); + $userinfo = \Froxlor\PhpHelper::strReplaceArray('-1', $lng['customer']['unlimited'], $userinfo, 'diskspace diskspace_bytes traffic traffic_bytes mysqls emails email_accounts email_forwarders email_quota ftps subdomains'); $userinfo['custom_notes'] = ($userinfo['custom_notes'] != '') ? nl2br($userinfo['custom_notes']) : ''; @@ -123,19 +131,25 @@ if ($page == 'overview') { if ($userinfo['perlenabled'] == '1') $se[] = "Perl/CGI"; if ($userinfo['api_allowed'] == '1') - $se[] = 'API'; + $se[] = 'API'; $services_enabled = implode(", ", $se); eval("echo \"" . \Froxlor\UI\Template::getTemplate('index/index') . "\";"); } elseif ($page == 'change_password') { + if (isset($_POST['send']) && $_POST['send'] == 'send') { $old_password = \Froxlor\Validate\Validate::validate($_POST['old_password'], 'old password'); + if (! \Froxlor\System\Crypt::validatePasswordLogin($userinfo, $old_password, TABLE_PANEL_CUSTOMERS, 'customerid')) { \Froxlor\UI\Response::standard_error('oldpasswordnotcorrect'); } - $new_password = \Froxlor\System\Crypt::validatePassword($_POST['new_password'], 'new password'); - $new_password_confirm = \Froxlor\System\Crypt::validatePassword($_POST['new_password_confirm'], 'new password confirm'); + try { + $new_password = \Froxlor\System\Crypt::validatePassword($_POST['new_password'], 'new password'); + $new_password_confirm = \Froxlor\System\Crypt::validatePassword($_POST['new_password_confirm'], 'new password confirm'); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } if ($old_password == '') { \Froxlor\UI\Response::standard_error(array( diff --git a/customer_mysql.php b/customer_mysql.php index 08eca699..40e84575 100644 --- a/customer_mysql.php +++ b/customer_mysql.php @@ -85,10 +85,12 @@ if ($page == 'overview') { $mbdata_stmt = Database::prepare("SELECT SUM(data_length + index_length) as MB FROM information_schema.TABLES WHERE table_schema = :table_schema GROUP BY table_schema"); - Database::pexecute($mbdata_stmt, array( + $mbdata = Database::pexecute_first($mbdata_stmt, array( "table_schema" => $row['databasename'] )); - $mbdata = $mbdata_stmt->fetch(PDO::FETCH_ASSOC); + if (!$mbdata) { + $mbdata = array('MB' => 0); + } $row['size'] = \Froxlor\PhpHelper::sizeReadable($mbdata['MB'], 'GiB', 'bi', '%01.' . (int) Settings::Get('panel.decimal_places') . 'f %s'); eval("\$mysqls.=\"" . \Froxlor\UI\Template::getTemplate('mysql/mysqls_database') . "\";"); $count ++; diff --git a/customer_traffic.php b/customer_traffic.php index 933ffd99..fdb73394 100644 --- a/customer_traffic.php +++ b/customer_traffic.php @@ -86,22 +86,18 @@ if (! is_null($month) && ! is_null($year)) { if (extension_loaded('bcmath')) { $traf['ftptext'] = bcdiv($row['ftp_up'], 1024, Settings::Get('panel.decimal_places')) . " MiB up/ " . bcdiv($row['ftp_down'], 1024, Settings::Get('panel.decimal_places')) . " MiB down (FTP)"; - $traf['httptext'] = bcdiv($http, 1024, Settings::Get('panel.decimal_places')) . " MiB (HTTP)"; - $traf['mailtext'] = bcdiv($mail, 1024, Settings::Get('panel.decimal_places')) . " MiB (Mail)"; $traf['ftp'] = bcdiv($ftp, 1024, Settings::Get('panel.decimal_places')); - $traf['http'] = bcdiv($http, 1024, Settings::Get('panel.decimal_places')); - $traf['mail'] = bcdiv($mail, 1024, Settings::Get('panel.decimal_places')); - $traf['byte'] = bcdiv($traf['byte'], 1024, Settings::Get('panel.decimal_places')); } else { $traf['ftptext'] = round($row['ftp_up'] / 1024, Settings::Get('panel.decimal_places')) . " MiB up/ " . round($row['ftp_down'] / 1024, Settings::Get('panel.decimal_places')) . " MiB down (FTP)"; - $traf['httptext'] = round($http / 1024, Settings::Get('panel.decimal_places')) . " MiB (HTTP)"; - $traf['mailtext'] = round($mail / 1024, Settings::Get('panel.decimal_places')) . " MiB (Mail)"; - $traf['http'] = round($http, Settings::Get('panel.decimal_places')); - $traf['ftp'] = round($ftp, Settings::Get('panel.decimal_places')); - $traf['mail'] = round($mail, Settings::Get('panel.decimal_places')); - $traf['byte'] = round($traf['byte'] / 1024, Settings::Get('panel.decimal_places')); + $traf['ftp'] = round($ftp / 1024, Settings::Get('panel.decimal_places')); } + getReadableTraffic($traf,'httptext', $http, 1024, "MiB (HTTP)"); + getReadableTraffic($traf,'http', $http, 1024); + getReadableTraffic($traf,'mailtext', $mail, 1024, "MiB (Mail)"); + getReadableTraffic($traf,'mail', $mail, 1024); + getReadableTraffic($traf,'byte', $traf['byte'], (1024 * 1024)); + eval("\$traffic.=\"" . \Froxlor\UI\Template::getTemplate('traffic/traffic_month') . "\";"); $show = $lng['traffic']['months'][intval($row['month'])] . ' ' . $row['year']; } @@ -142,22 +138,18 @@ if (! is_null($month) && ! is_null($year)) { if (extension_loaded('bcmath')) { $traf['ftptext'] = bcdiv($ftp_up, 1024, Settings::Get('panel.decimal_places')) . " MiB up/ " . bcdiv($ftp_down, 1024, Settings::Get('panel.decimal_places')) . " MiB down (FTP)"; - $traf['httptext'] = bcdiv($http, 1024, Settings::Get('panel.decimal_places')) . " MiB (HTTP)"; - $traf['mailtext'] = bcdiv($mail, 1024, Settings::Get('panel.decimal_places')) . " MiB (Mail)"; $traf['ftp'] = bcdiv(($ftp_up + $ftp_down), 1024, Settings::Get('panel.decimal_places')); - $traf['http'] = bcdiv($http, 1024, Settings::Get('panel.decimal_places')); - $traf['mail'] = bcdiv($mail, 1024, Settings::Get('panel.decimal_places')); - $traf['byte'] = bcdiv($traf['byte'], 1024 * 1024, Settings::Get('panel.decimal_places')); } else { $traf['ftptext'] = round($ftp_up / 1024, Settings::Get('panel.decimal_places')) . " MiB up/ " . round($ftp_down / 1024, Settings::Get('panel.decimal_places')) . " MiB down (FTP)"; - $traf['httptext'] = round($http / 1024, Settings::Get('panel.decimal_places')) . " MiB (HTTP)"; - $traf['mailtext'] = round($mail / 1024, Settings::Get('panel.decimal_places')) . " MiB (Mail)"; $traf['ftp'] = round(($ftp_up + $ftp_down) / 1024, Settings::Get('panel.decimal_places')); - $traf['http'] = round($http / 1024, Settings::Get('panel.decimal_places')); - $traf['mail'] = round($mail / 1024, Settings::Get('panel.decimal_places')); - $traf['byte'] = round($traf['byte'] / (1024 * 1024), Settings::Get('panel.decimal_places')); } + getReadableTraffic($traf,'httptext', $http, 1024, "MiB (HTTP)"); + getReadableTraffic($traf,'http', $http, 1024); + getReadableTraffic($traf,'mailtext', $mail, 1024, "MiB (Mail)"); + getReadableTraffic($traf,'mail', $mail, 1024); + getReadableTraffic($traf,'byte', $traf['byte'], (1024 * 1024)); + eval("\$traffic.=\"" . \Froxlor\UI\Template::getTemplate('traffic/traffic_traffic') . "\";"); } @@ -167,3 +159,12 @@ if (! is_null($month) && ! is_null($year)) { eval("echo \"" . \Froxlor\UI\Template::getTemplate('traffic/traffic') . "\";"); } + +function getReadableTraffic(&$traf, $index, $value, $divisor, $desc = "") +{ + if (extension_loaded('bcmath')) { + $traf[$index] = bcdiv($value, $divisor,Settings::Get('panel.decimal_places')).(!empty($desc) ? " ".$desc : ""); + } else { + $traf[$index] = round($value / $divisor, Settings::Get('panel.decimal_places')).(!empty($desc) ? " ".$desc : ""); + } +} diff --git a/dns_editor.php b/dns_editor.php index a9df2eec..a5d25eac 100644 --- a/dns_editor.php +++ b/dns_editor.php @@ -19,7 +19,6 @@ if (! defined('AREA')) { * */ -use Froxlor\Database\Database; use Froxlor\Api\Commands\DomainZones as DomainZones; // This file is being included in admin_domains and customer_domains @@ -36,18 +35,6 @@ $ttl = isset($_POST['record']['ttl']) ? (int) $_POST['record']['ttl'] : 18000; // get domain-name $domain = \Froxlor\Dns\Dns::getAllowedDomainEntry($domain_id, AREA, $userinfo); -// select all entries -try { - // get list - $json_result = DomainZones::getLocal($userinfo, [ - 'id' => $domain_id - ])->listing(); -} catch (Exception $e) { - \Froxlor\UI\Response::dynamic_error($e->getMessage()); -} -$result = json_decode($json_result, true)['data']; -$dom_entries = $result['list']; - $errors = ""; $success_message = ""; @@ -63,8 +50,9 @@ if ($action == 'add_record' && ! empty($_POST)) { 'ttl' => $ttl ))->add(); $success_message = $lng['success']['dns_record_added']; + $record = $prio = $content = ""; } catch (Exception $e) { - \Froxlor\UI\Response::dynamic_error($e->getMessage()); + $errors = str_replace("\n", "
", $e->getMessage()); } } elseif ($action == 'delete') { // remove entry @@ -75,26 +63,26 @@ if ($action == 'add_record' && ! empty($_POST)) { 'entry_id' => $entry_id, 'id' => $domain_id ))->delete(); + // success message (inline) + $success_message = $lng['success']['dns_record_deleted']; } catch (Exception $e) { $errors = str_replace("\n", "
", $e->getMessage()); } - - if (empty($errors)) { - // remove deleted entry from internal data array (no reread of DB necessary) - $_t = $dom_entries; - foreach ($_t as $idx => $entry) { - if ($entry['id'] == $entry_id) { - unset($dom_entries[$idx]); - break; - } - } - unset($_t); - // success message (inline) - $success_message = $lng['success']['dns_record_deleted']; - } } } +// select all entries +try { + // get list + $json_result = DomainZones::getLocal($userinfo, [ + 'id' => $domain_id + ])->listing(); +} catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); +} +$result = json_decode($json_result, true)['data']; +$dom_entries = $result['list']; + // show editor $record_list = ""; $existing_entries = ""; diff --git a/index.php b/index.php index bfc6282a..07a96e82 100644 --- a/index.php +++ b/index.php @@ -28,6 +28,12 @@ if ($action == '') { } if (session_status() == PHP_SESSION_NONE) { + ini_set("session.name", "s"); + ini_set("url_rewriter.tags", ""); + ini_set("session.use_cookies", false); + ini_set("session.cookie_httponly", true); + ini_set("session.cookie_secure", $is_ssl); + session_id('login'); session_start(); } @@ -114,7 +120,7 @@ if ($action == '2fa_entercode') { )); $row = $stmt->fetch(PDO::FETCH_ASSOC); - if ($row['customer'] == $loginname) { + if ($row && $row['customer'] == $loginname) { $table = "`" . TABLE_PANEL_CUSTOMERS . "`"; $uid = 'customerid'; $adminsession = '0'; @@ -142,7 +148,7 @@ if ($action == '2fa_entercode') { "loginname" => $loginname )); $row3 = $stmt->fetch(PDO::FETCH_ASSOC); - if ($row3['customer'] == $loginname) { + if ($row3 && $row3['customer'] == $loginname) { $table = "`" . TABLE_PANEL_CUSTOMERS . "`"; $uid = 'customerid'; $adminsession = '0'; @@ -181,7 +187,7 @@ if ($action == '2fa_entercode') { $row = $stmt->fetch(PDO::FETCH_ASSOC); } - if ($row['admin'] == $loginname) { + if ($row && $row['admin'] == $loginname) { $table = "`" . TABLE_PANEL_ADMINS . "`"; $uid = 'adminid'; $adminsession = '1'; @@ -372,6 +378,8 @@ if ($action == '2fa_entercode') { $lastscript = ""; if (isset($_REQUEST['script']) && $_REQUEST['script'] != "") { $lastscript = $_REQUEST['script']; + $lastscript = str_replace("..", "", $lastscript); + $lastscript = htmlspecialchars($lastscript, ENT_QUOTES); if (! file_exists(__DIR__ . "/" . $lastscript)) { $lastscript = ""; @@ -393,7 +401,7 @@ if ($action == 'forgotpwd') { if (isset($_POST['send']) && $_POST['send'] == 'send') { $loginname = \Froxlor\Validate\Validate::validate($_POST['loginname'], 'loginname'); $email = \Froxlor\Validate\Validate::validateEmail($_POST['loginemail'], 'email'); - $result_stmt = Database::prepare("SELECT `adminid`, `customerid`, `firstname`, `name`, `company`, `email`, `loginname`, `def_language`, `deactivated` FROM `" . TABLE_PANEL_CUSTOMERS . "` + $result_stmt = Database::prepare("SELECT `adminid`, `customerid`, `customernumber`, `firstname`, `name`, `company`, `email`, `loginname`, `def_language`, `deactivated` FROM `" . TABLE_PANEL_CUSTOMERS . "` WHERE `loginname`= :loginname AND `email`= :email"); Database::pexecute($result_stmt, array( @@ -481,6 +489,10 @@ if ($action == 'forgotpwd') { $replace_arr = array( 'SALUTATION' => \Froxlor\User::getCorrectUserSalutation($user), + 'NAME' => $user['name'], + 'FIRSTNAME' => $user['firstname'] ?? "", + 'COMPANY' => $user['company'] ?? "", + 'CUSTOMER_NO' => $user['customernumber'] ?? 0, 'USERNAME' => $loginname, 'LINK' => $activationlink ); @@ -598,21 +610,18 @@ if ($action == 'resetpwd') { )); if ($result !== false) { - if ($result['admin'] == 1) { - $new_password = \Froxlor\Validate\Validate::validate($_POST['new_password'], 'new password'); - $new_password_confirm = \Froxlor\Validate\Validate::validate($_POST['new_password_confirm'], 'new password confirm'); - } else { - $new_password = \Froxlor\System\Crypt::validatePassword($_POST['new_password'], 'new password'); - $new_password_confirm = \Froxlor\System\Crypt::validatePassword($_POST['new_password_confirm'], 'new password confirm'); + try { + $new_password = \Froxlor\System\Crypt::validatePassword($_POST['new_password'], true); + $new_password_confirm = \Froxlor\System\Crypt::validatePassword($_POST['new_password_confirm'], true); + } catch (Exception $e) { + $message = $e->getMessage(); } - if ($new_password == '') { - $message = $new_password; - } elseif ($new_password_confirm == '') { - $message = $new_password_confirm; - } elseif ($new_password != $new_password_confirm) { - $message = $new_password . " != " . $new_password_confirm; - } else { + if (empty($message) && (empty($new_password) || $new_password != $new_password_confirm)) { + $message = $lng['error']['newpasswordconfirmerror']; + } + + if (empty($message)) { // Update user password if ($result['admin'] == 1) { $stmt = Database::prepare("UPDATE `" . TABLE_PANEL_ADMINS . "` @@ -668,7 +677,7 @@ function finishLogin($userinfo) global $version, $dbversion, $remote_addr, $http_user_agent, $languages; if (isset($userinfo['userid']) && $userinfo['userid'] != '') { - $s = md5(uniqid(microtime(), 1)); + $s = \Froxlor\Froxlor::genSessionId(); if (isset($_POST['language'])) { $language = \Froxlor\Validate\Validate::validate($_POST['language'], 'language'); diff --git a/install/froxlor.sql b/install/froxlor.sql index a0ff604e..5b5a8b0a 100644 --- a/install/froxlor.sql +++ b/install/froxlor.sql @@ -15,10 +15,10 @@ CREATE TABLE `ftp_groups` ( DROP TABLE IF EXISTS `ftp_users`; CREATE TABLE `ftp_users` ( `id` int(20) NOT NULL auto_increment, - `username` varchar(255) NOT NULL default '', + `username` varchar(255) NOT NULL, `uid` int(5) NOT NULL default '0', `gid` int(5) NOT NULL default '0', - `password` varchar(128) NOT NULL default '', + `password` varchar(128) NOT NULL, `homedir` varchar(255) NOT NULL default '', `shell` varchar(255) NOT NULL default '/bin/false', `login_enabled` enum('N','Y') NOT NULL default 'N', @@ -71,6 +71,7 @@ CREATE TABLE `mail_virtual` ( `customerid` int(11) NOT NULL default '0', `popaccountid` int(11) NOT NULL default '0', `iscatchall` tinyint(1) unsigned NOT NULL default '0', + `description` varchar(255) NOT NULL DEFAULT '', PRIMARY KEY (`id`), KEY `email` (`email`) ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci; @@ -84,14 +85,14 @@ CREATE TABLE `panel_activation` ( `creation` int(11) unsigned NOT NULL default '0', `activationcode` varchar(50) default NULL, PRIMARY KEY (id) -) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci; +) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci; DROP TABLE IF EXISTS `panel_admins`; CREATE TABLE `panel_admins` ( `adminid` int(11) unsigned NOT NULL auto_increment, - `loginname` varchar(50) NOT NULL default '', - `password` varchar(255) NOT NULL default '', + `loginname` varchar(50) NOT NULL, + `password` varchar(255) NOT NULL, `name` varchar(255) NOT NULL default '', `email` varchar(255) NOT NULL default '', `def_language` varchar(100) NOT NULL default '', @@ -142,7 +143,7 @@ CREATE TABLE `panel_admins` ( DROP TABLE IF EXISTS `panel_customers`; CREATE TABLE `panel_customers` ( `customerid` int(11) unsigned NOT NULL auto_increment, - `loginname` varchar(50) NOT NULL default '', + `loginname` varchar(50) NOT NULL, `password` varchar(255) NOT NULL default '', `adminid` int(11) unsigned NOT NULL default '0', `name` varchar(255) NOT NULL default '', @@ -223,7 +224,8 @@ CREATE TABLE `panel_databases` ( DROP TABLE IF EXISTS `panel_domains`; CREATE TABLE `panel_domains` ( `id` int(11) unsigned NOT NULL auto_increment, - `domain` varchar(255) NOT NULL default '', + `domain` varchar(255) NOT NULL, + `domain_ace` varchar(255) NOT NULL default '', `adminid` int(11) unsigned NOT NULL default '0', `customerid` int(11) unsigned NOT NULL default '0', `aliasdomain` int(11) unsigned NULL, @@ -268,12 +270,13 @@ CREATE TABLE `panel_domains` ( `writeaccesslog` tinyint(1) DEFAULT '1', `writeerrorlog` tinyint(1) DEFAULT '1', `override_tls` tinyint(1) DEFAULT '0', - `ssl_protocols` text, - `ssl_cipher_list` text, - `tlsv13_cipher_list` text, + `ssl_protocols` varchar(255) NOT NULL DEFAULT '', + `ssl_cipher_list` varchar(500) NOT NULL DEFAULT '', + `tlsv13_cipher_list` varchar(500) NOT NULL DEFAULT '', `ssl_enabled` tinyint(1) DEFAULT '1', `ssl_honorcipherorder` tinyint(1) DEFAULT '0', `ssl_sessiontickets` tinyint(1) DEFAULT '1', + `description` varchar(255) NOT NULL DEFAULT '', PRIMARY KEY (`id`), KEY `customerid` (`customerid`), KEY `parentdomain` (`parentdomainid`), @@ -285,7 +288,7 @@ CREATE TABLE `panel_domains` ( DROP TABLE IF EXISTS `panel_ipsandports`; CREATE TABLE `panel_ipsandports` ( `id` int(11) unsigned NOT NULL auto_increment, - `ip` varchar(39) NOT NULL default '', + `ip` varchar(39) NOT NULL, `port` int(5) NOT NULL default '80', `listen_statement` tinyint(1) NOT NULL default '0', `namevirtualhost_statement` tinyint(1) NOT NULL default '0', @@ -386,6 +389,7 @@ INSERT INTO `panel_settings` (`settinggroup`, `varname`, `value`) VALUES ('dkim', 'dkim_domains', 'domains'), ('dkim', 'dkim_dkimkeys', 'dkim-keys.conf'), ('dkim', 'dkimrestart_command', '/etc/init.d/dkim-filter restart'), + ('dkim', 'privkeysuffix', '.priv'), ('admin', 'show_news_feed', '0'), ('admin', 'show_version_login', '0'), ('admin', 'show_version_footer', '0'), @@ -491,7 +495,6 @@ opcache.load_comments opcache.revalidate_path opcache.save_comments opcache.use_cwd -opcache.validate_timestamps opcache.fast_shutdown'), ('phpfpm', 'ini_admin_values', 'cgi.redirect_status_env date.timezone @@ -515,7 +518,8 @@ opcache.restrict_api opcache.revalidate_freq opcache.max_accelerated_files opcache.memory_consumption -opcache.interned_strings_buffer'), +opcache.interned_strings_buffer +opcache.validate_timestamps'), ('nginx', 'fastcgiparams', '/etc/nginx/fastcgi_params'), ('system', 'lastaccountnumber', '0'), ('system', 'lastguid', '9999'), @@ -528,7 +532,7 @@ opcache.interned_strings_buffer'), ('system', 'vmail_gid', '2000'), ('system', 'vmail_homedir', '/var/customers/mail/'), ('system', 'vmail_maildirname', 'Maildir'), - ('system', 'bind_enable', '1'), + ('system', 'bind_enable', '0'), ('system', 'bindconf_directory', '/etc/bind/'), ('system', 'bindreload_command', '/etc/init.d/bind9 reload'), ('system', 'hostname', 'SERVERNAME'), @@ -553,6 +557,7 @@ opcache.interned_strings_buffer'), ('system', 'ssl_cert_file', '/etc/apache2/apache2.pem'), ('system', 'use_ssl', '0'), ('system', 'default_vhostconf', ''), + ('system', 'default_sslvhostconf', ''), ('system', 'mail_quota_enabled', '0'), ('system', 'mail_quota', '100'), ('system', 'webalizer_enabled', '1'), @@ -606,6 +611,7 @@ opcache.interned_strings_buffer'), ('system', 'documentroot_use_default_value', '0'), ('system', 'passwordcryptfunc', '3'), ('system', 'axfrservers', ''), + ('system', 'powerdns_mode', 'Native'), ('system', 'customer_ssl_path', '/etc/ssl/froxlor-custom/'), ('system', 'allow_error_report_admin', '1'), ('system', 'allow_error_report_customer', '0'), @@ -623,7 +629,7 @@ opcache.interned_strings_buffer'), ('system', 'apacheitksupport', '0'), ('system', 'leprivatekey', 'unset'), ('system', 'lepublickey', 'unset'), - ('system', 'letsencryptca', 'production'), + ('system', 'letsencryptca', 'letsencrypt'), ('system', 'letsencryptcountrycode', 'DE'), ('system', 'letsencryptstate', 'Hessen'), ('system', 'letsencryptchallengepath', '/var/www/froxlor'), @@ -653,8 +659,8 @@ opcache.interned_strings_buffer'), ('system', 'leregistered', '0'), ('system', 'leaccount', ''), ('system', 'nssextrausers', '0'), - ('system', 'disable_le_selfcheck', '0'), - ('system', 'ssl_protocols', 'TLSv1,TLSv1.2'), + ('system', 'le_domain_dnscheck', '1'), + ('system', 'ssl_protocols', 'TLSv1.2'), ('system', 'tlsv13_cipher_list', ''), ('system', 'honorcipherorder', '0'), ('system', 'sessiontickets', '1'), @@ -669,6 +675,14 @@ opcache.interned_strings_buffer'), ('system', 'froxloraliases', ''), ('system', 'apply_specialsettings_default', '1'), ('system', 'apply_phpconfigs_default', '1'), + ('system', 'hide_incompatible_settings', '0'), + ('system', 'include_default_vhostconf', '0'), + ('system', 'soaemail', ''), + ('system', 'domaindefaultalias', '0'), + ('system', 'createstdsubdom_default', '1'), + ('system', 'froxlorusergroup', ''), + ('system', 'froxlorusergroup_gid', ''), + ('system', 'acmeshpath', '/root/.acme.sh/acme.sh'), ('api', 'enabled', '0'), ('2fa', 'enabled', '1'), ('panel', 'decimal_places', '4'), @@ -681,7 +695,6 @@ opcache.interned_strings_buffer'), ('panel', 'paging', '20'), ('panel', 'natsorting', '1'), ('panel', 'sendalternativemail', '0'), - ('panel', 'no_robots', '1'), ('panel', 'allow_domain_change_admin', '0'), ('panel', 'allow_domain_change_customer', '0'), ('panel', 'frontend', 'froxlor'), @@ -703,8 +716,15 @@ opcache.interned_strings_buffer'), ('panel', 'password_special_char', '!?<>§$%+#=@'), ('panel', 'customer_hide_options', ''), ('panel', 'is_configured', '0'), - ('panel', 'version', '0.10.13'), - ('panel', 'db_version', '201912313'); + ('panel', 'imprint_url', ''), + ('panel', 'terms_url', ''), + ('panel', 'privacy_url', ''), + ('panel', 'logo_image_header', ''), + ('panel', 'logo_image_login', ''), + ('panel', 'logo_overridetheme', '0'), + ('panel', 'logo_overridecustom', '0'), + ('panel', 'version', '0.10.33'), + ('panel', 'db_version', '202112310'); DROP TABLE IF EXISTS `panel_tasks`; @@ -785,23 +805,6 @@ CREATE TABLE `panel_diskspace` ( -DROP TABLE IF EXISTS `panel_diskspace_admins`; -CREATE TABLE `panel_diskspace_admins` ( - `id` int(11) unsigned NOT NULL auto_increment, - `adminid` int(11) unsigned NOT NULL default '0', - `year` int(4) unsigned zerofill NOT NULL default '0000', - `month` int(2) unsigned zerofill NOT NULL default '00', - `day` int(2) unsigned zerofill NOT NULL default '00', - `stamp` int(11) unsigned NOT NULL default '0', - `webspace` bigint(30) unsigned NOT NULL default '0', - `mail` bigint(30) unsigned NOT NULL default '0', - `mysql` bigint(30) unsigned NOT NULL default '0', - PRIMARY KEY (`id`), - KEY `adminid` (`adminid`) -) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci; - - - DROP TABLE IF EXISTS `panel_languages`; CREATE TABLE `panel_languages` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, @@ -820,7 +823,8 @@ INSERT INTO `panel_languages` (`id`, `language`, `iso`, `file`) VALUES (4, 'Português', 'pt', 'lng/portugues.lng.php'), (5, 'Italiano', 'it', 'lng/italian.lng.php'), (6, 'Nederlands', 'nl', 'lng/dutch.lng.php'), - (7, 'Svenska', 'sv', 'lng/swedish.lng.php'); + (7, 'Svenska', 'sv', 'lng/swedish.lng.php'), + (8, 'Česká republika', 'cs', 'lng/czech.lng.php'); DROP TABLE IF EXISTS `panel_syslog`; @@ -938,7 +942,7 @@ CREATE TABLE IF NOT EXISTS `ftp_quotalimits` ( -INSERT INTO `ftp_quotalimits` (`name`, `quota_type`, `per_session`, `limit_type`, `bytes_in_avail`, `bytes_out_avail`, `bytes_xfer_avail`, `files_in_avail`, `files_out_avail`, `files_xfer_avail`) VALUES +INSERT INTO `ftp_quotalimits` (`name`, `quota_type`, `per_session`, `limit_type`, `bytes_in_avail`, `bytes_out_avail`, `bytes_xfer_avail`, `files_in_avail`, `files_out_avail`, `files_xfer_avail`) VALUES ('froxlor', 'user', 'false', 'hard', 0, 0, 0, 0, 0, 0); @@ -996,7 +1000,8 @@ CREATE TABLE IF NOT EXISTS `domain_ssl_settings` ( `ssl_csr_file` mediumtext, `ssl_fullchain_file` mediumtext, `expirationdate` datetime DEFAULT NULL, - PRIMARY KEY (`id`) + PRIMARY KEY (`id`), + UNIQUE KEY (`domainid`) ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci; diff --git a/install/lib/class.FroxlorInstall.php b/install/lib/class.FroxlorInstall.php index ddc3166a..30855bfa 100644 --- a/install/lib/class.FroxlorInstall.php +++ b/install/lib/class.FroxlorInstall.php @@ -28,7 +28,7 @@ * @author Froxlor team (2010-) * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt * @package Install - * + * */ class FroxlorInstall { @@ -123,7 +123,7 @@ class FroxlorInstall if ((isset($_POST['installstep']) && $_POST['installstep'] == '1') || (isset($_GET['check']) && $_GET['check'] == '1')) { $pagetitle = $this->_lng['install']['title']; if ($this->_checkPostData()) { - // ceck data and create userdata etc.etc.etc. + // check data and create userdata etc.etc.etc. $result = $this->_doInstall(); } elseif (isset($_GET['check']) && $_GET['check'] == '1') { // gather data @@ -159,13 +159,17 @@ class FroxlorInstall $this->_guessServerName(); $this->_guessServerIP(); $this->_guessWebserver(); + $this->_guessDistribution(); $this->_getPostField('mysql_host', '127.0.0.1'); $this->_getPostField('mysql_database', 'froxlor'); + $this->_getPostField('mysql_forcecreate', '0'); $this->_getPostField('mysql_unpriv_user', 'froxlor'); $this->_getPostField('mysql_unpriv_pass'); $this->_getPostField('mysql_root_user', 'root'); $this->_getPostField('mysql_root_pass'); + $this->_getPostField('mysql_ssl_ca_file'); + $this->_getPostField('mysql_ssl_verify_server_certificate', 0); $this->_getPostField('admin_user', 'admin'); $this->_getPostField('admin_pass1'); $this->_getPostField('admin_pass2'); @@ -211,6 +215,12 @@ class FroxlorInstall $options = array( 'PDO::MYSQL_ATTR_INIT_COMMAND' => 'SET names utf8' ); + + if (!empty($this->_data['mysql_ssl_ca_file'])) { + $options[\PDO::MYSQL_ATTR_SSL_CA] = $this->_data['mysql_ssl_ca_file']; + $options[\PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT] = (bool) $this->_data['mysql_ssl_verify_server_certificate']; + } + $dsn = "mysql:host=" . $this->_data['mysql_host'] . ";"; $fatal_fail = false; try { @@ -245,15 +255,23 @@ class FroxlorInstall $content .= $this->_status_message('green', "OK"); // check for existing db and create backup if so $content .= $this->_backupExistingDatabase($db_root); - // create unprivileged user and the database itself - $content .= $this->_createDatabaseAndUser($db_root); - // importing data to new database - $content .= $this->_importDatabaseData(); + if (!$this->_abort) { + // create unprivileged user and the database itself + $content .= $this->_createDatabaseAndUser($db_root); + // importing data to new database + $content .= $this->_importDatabaseData(); + } if (! $this->_abort) { // create DB object for new database $options = array( 'PDO::MYSQL_ATTR_INIT_COMMAND' => 'SET names utf8' ); + + if (!empty($this->_data['mysql_ssl_ca_file'])) { + $options[\PDO::MYSQL_ATTR_SSL_CA] = $this->_data['mysql_ssl_ca_file']; + $options[\PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT] = (bool) $this->_data['mysql_ssl_verify_server_certificate']; + } + $dsn = "mysql:host=" . $this->_data['mysql_host'] . ";dbname=" . $this->_data['mysql_database'] . ";"; $another_fail = false; try { @@ -323,35 +341,70 @@ class FroxlorInstall $userdata .= "\$sql['user']='" . addcslashes($this->_data['mysql_unpriv_user'], "'\\") . "';\n"; $userdata .= "\$sql['password']='" . addcslashes($this->_data['mysql_unpriv_pass'], "'\\") . "';\n"; $userdata .= "\$sql['db']='" . addcslashes($this->_data['mysql_database'], "'\\") . "';\n"; + $userdata .= "\$sql['ssl']['caFile']='" . addcslashes($this->_data['mysql_ssl_ca_file'], "'\\") . "';\n"; + $userdata .= "\$sql['ssl']['verifyServerCertificate']='" . addcslashes($this->_data['mysql_ssl_verify_server_certificate'], "'\\") . "';\n"; $userdata .= "\$sql_root[0]['caption']='Default';\n"; $userdata .= "\$sql_root[0]['host']='" . addcslashes($this->_data['mysql_host'], "'\\") . "';\n"; $userdata .= "\$sql_root[0]['user']='" . addcslashes($this->_data['mysql_root_user'], "'\\") . "';\n"; $userdata .= "\$sql_root[0]['password']='" . addcslashes($this->_data['mysql_root_pass'], "'\\") . "';\n"; + $userdata .= "\$sql_root[0]['ssl']['caFile']='" . addcslashes($this->_data['mysql_ssl_ca_file'], "'\\") . "';\n"; + $userdata .= "\$sql_root[0]['ssl']['verifyServerCertificate']='" . addcslashes($this->_data['mysql_ssl_verify_server_certificate'], "'\\") . "';\n"; $userdata .= "// enable debugging to browser in case of SQL errors\n"; $userdata .= "\$sql['debug'] = false;\n"; $userdata .= "?>"; // test if we can store the userdata.inc.php in ../lib + $umask = @umask(077); $userdata_file = dirname(dirname(dirname(__FILE__))) . '/lib/userdata.inc.php'; - if ($fp = @fopen($userdata_file, 'w')) { - $result = @fputs($fp, $userdata, strlen($userdata)); + if (@touch($userdata_file) && @is_writable($userdata_file)) { + $fp = @fopen($userdata_file, 'w'); + @fputs($fp, $userdata, strlen($userdata)); @fclose($fp); $content .= $this->_status_message('green', 'OK'); - chmod($userdata_file, 0440); - } elseif ($fp = @fopen('/tmp/userdata.inc.php', 'w')) { - $result = @fputs($fp, $userdata, strlen($userdata)); - @fclose($fp); - $content .= $this->_status_message('orange', $this->_lng['install']['creating_configfile_temp']); - chmod('/tmp/userdata.inc.php', 0440); } else { - $content .= $this->_status_message('red', $this->_lng['install']['creating_configfile_failed']); - $escpduserdata = nl2br(htmlspecialchars($userdata)); - eval("\$content .= \"" . $this->_getTemplate("textarea") . "\";"); + @unlink($userdata_file); + // try creating it in a temporary file + $temp_file = @tempnam(sys_get_temp_dir(), 'fx'); + if ($temp_file) { + $fp = @fopen($temp_file, 'w'); + @fputs($fp, $userdata, strlen($userdata)); + @fclose($fp); + $content .= $this->_status_message('orange', sprintf($this->_lng['install']['creating_configfile_temp'], $temp_file)); + } else { + $content .= $this->_status_message('red', $this->_lng['install']['creating_configfile_failed']); + $escpduserdata = nl2br(htmlspecialchars($userdata)); + eval("\$content .= \"" . $this->_getTemplate("textarea") . "\";"); + } } + @umask($umask); return $content; } + /** + * generate safe unique token + * + * @param int $length + * @return string + */ + private function genUniqueToken(int $length = 16) + { + if(!isset($length) || intval($length) <= 8 ){ + $length = 16; + } + if (function_exists('random_bytes')) { + return bin2hex(random_bytes($length)); + } + if (function_exists('mcrypt_create_iv')) { + return bin2hex(mcrypt_create_iv($length, MCRYPT_DEV_URANDOM)); + } + if (function_exists('openssl_random_pseudo_bytes')) { + return bin2hex(openssl_random_pseudo_bytes($length)); + } + // if everything else fails, use unsafe fallback + return md5(uniqid(microtime(), 1)); + } + /** * create corresponding entries in froxlor database * @@ -395,8 +448,8 @@ class FroxlorInstall $content .= $this->_status_message('begin', $this->_lng['install']['adding_admin_user']); $ins_data = array( 'loginname' => $this->_data['admin_user'], - /* use SHA256 default crypt */ - 'password' => crypt($this->_data['admin_pass1'], '$5$' . md5(uniqid(microtime(), 1)) . md5(uniqid(microtime(), 1))), + /* use SHA256 default crypt */ + 'password' => crypt($this->_data['admin_pass1'], '$5$' . $this->genUniqueToken() . $this->genUniqueToken()), 'email' => 'admin@' . $this->_data['servername'], 'deflang' => $this->_languages[$this->_activelng] ); @@ -497,12 +550,30 @@ class FroxlorInstall $this->_updateSetting($upd_stmt, 'error', 'system', 'errorlog_level'); } + $distros = glob(\Froxlor\FileDir::makeCorrectDir(\Froxlor\Froxlor::getInstallDir() . '/lib/configfiles/') . '*.xml'); + foreach ($distros as $_distribution) { + if ($this->_data['distribution'] == str_replace(".xml", "", strtolower(basename($_distribution)))) { + $dist = new \Froxlor\Config\ConfigParser($_distribution); + $defaults = $dist->getDefaults(); + foreach ($defaults->property as $property) { + $this->_updateSetting($upd_stmt, $property->value, $property->settinggroup, $property->varname); + } + } + } + $this->_updateSetting($upd_stmt, $this->_data['activate_newsfeed'], 'admin', 'show_news_feed'); $this->_updateSetting($upd_stmt, dirname(dirname(dirname(__FILE__))), 'system', 'letsencryptchallengepath'); // insert the lastcronrun to be the installation date $this->_updateSetting($upd_stmt, time(), 'system', 'lastcronrun'); + // check currently used php version and set values of fpm/fcgid accordingly + if (defined('PHP_MAJOR_VERSION') && defined('PHP_MINOR_VERSION')) { + $reload = "service php" . PHP_MAJOR_VERSION . "." . PHP_MINOR_VERSION . "-fpm restart"; + $config_dir = "/etc/php/" . PHP_MAJOR_VERSION . "." . PHP_MINOR_VERSION . "/fpm/pool.d/"; + $db->query("UPDATE `" . TABLE_PANEL_FPMDAEMONS . "` SET `reload_cmd` = '" . $reload . "', `config_dir` = '" . $config_dir . "' WHERE `id` ='1';"); + } + // set specific times for some crons (traffic only at night, etc.) $ts = mktime(0, 0, 0, date('m', time()), date('d', time()), date('Y', time())); $db->query("UPDATE `" . TABLE_PANEL_CRONRUNS . "` SET `lastrun` = '" . $ts . "' WHERE `cronfile` ='cron_traffic';"); @@ -529,6 +600,12 @@ class FroxlorInstall $options = array( 'PDO::MYSQL_ATTR_INIT_COMMAND' => 'SET names utf8' ); + + if (!empty($this->_data['mysql_ssl_ca_file'])) { + $options[\PDO::MYSQL_ATTR_SSL_CA] = $this->_data['mysql_ssl_ca_file']; + $options[\PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT] = (bool) $this->_data['mysql_ssl_verify_server_certificate']; + } + $dsn = "mysql:host=" . $this->_data['mysql_host'] . ";dbname=" . $this->_data['mysql_database'] . ";"; $fatal_fail = false; try { @@ -563,7 +640,7 @@ class FroxlorInstall for ($i = 0; $i < sizeof($sql_query); $i ++) { if (trim($sql_query[$i]) != '') { try { - $result = $db->query($sql_query[$i]); + $db->query($sql_query[$i]); } catch (\PDOException $e) { $content .= $this->_status_message('red', $e->getMessage()); $fatal_fail = true; @@ -661,7 +738,7 @@ class FroxlorInstall if (version_compare($db_root->getAttribute(\PDO::ATTR_SERVER_VERSION), '8.0.11', '>=')) { // create user $stmt = $db_root->prepare(" - CREATE USER '" . $username . "'@'" . $access_host . "' IDENTIFIED BY :password + CREATE USER '" . $username . "'@'" . $access_host . "' IDENTIFIED WITH mysql_native_password BY :password "); $stmt->execute(array( "password" => $password @@ -707,39 +784,59 @@ class FroxlorInstall )); $rows = $db_root->query("SELECT FOUND_ROWS()")->fetchColumn(); + $content .= $this->_status_message('begin', $this->_lng['install']['check_db_exists']); + // check result if ($result_stmt !== false && $rows > 0) { $tables_exist = true; } if ($tables_exist) { - // tell whats going on - $content .= $this->_status_message('begin', $this->_lng['install']['backup_old_db']); + if ((int)$this->_data['mysql_forcecreate'] > 0) { + // set status + $content .= $this->_status_message('orange', 'exists (' . $this->_data['mysql_database'] . ')'); + // tell what's going on + $content .= $this->_status_message('begin', $this->_lng['install']['backup_old_db']); - // create temporary backup-filename - $filename = "/tmp/froxlor_backup_" . date('YmdHi') . ".sql"; + // create temporary backup-filename + $filename = "/tmp/froxlor_backup_" . date('YmdHi') . ".sql"; - // look for mysqldump - $do_backup = false; - if (file_exists("/usr/bin/mysqldump")) { - $do_backup = true; - $mysql_dump = '/usr/bin/mysqldump'; - } elseif (file_exists("/usr/local/bin/mysqldump")) { - $do_backup = true; - $mysql_dump = '/usr/local/bin/mysqldump'; - } + // look for mysqldump + $do_backup = false; + if (file_exists("/usr/bin/mysqldump")) { + $do_backup = true; + $mysql_dump = '/usr/bin/mysqldump'; + } elseif (file_exists("/usr/local/bin/mysqldump")) { + $do_backup = true; + $mysql_dump = '/usr/local/bin/mysqldump'; + } - if ($do_backup) { - $command = $mysql_dump . " " . $this->_data['mysql_database'] . " -u " . $this->_data['mysql_root_user'] . " --password='" . $this->_data['mysql_root_pass'] . "' --result-file=" . $filename; - $output = exec($command); - if (stristr($output, "error")) { - $content .= $this->_status_message('red', $this->_lng['install']['backup_failed']); + // create temporary .cnf file + $cnffilename = "/tmp/froxlor_dump.cnf"; + $dumpcnf = "[mysqldump]" . PHP_EOL . "password=\"" . $this->_data['mysql_root_pass'] . "\"" . PHP_EOL; + file_put_contents($cnffilename, $dumpcnf); + + if ($do_backup) { + $command = $mysql_dump . " --defaults-extra-file=" . $cnffilename . " " . escapeshellarg($this->_data['mysql_database']) . " -u " . escapeshellarg($this->_data['mysql_root_user']) . " --result-file=" . $filename; + $output = []; + exec($command, $output); + @unlink($cnffilename); + if (stristr(implode(" ", $output), "error") || ! file_exists($filename)) { + $content .= $this->_status_message('red', $this->_lng['install']['backup_failed']); + $this->_abort = true; + } else { + $content .= $this->_status_message('green', 'OK (' . $filename . ')'); + } } else { - $content .= $this->_status_message('green', 'OK (' . $filename . ')'); + $content .= $this->_status_message('red', $this->_lng['install']['backup_binary_missing']); + $this->_abort = true; } } else { - $content .= $this->_status_message('red', $this->_lng['install']['backup_binary_missing']); + $content .= $this->_status_message('red', $this->_lng['install']['db_exists']); + $this->_abort = true; } + } else { + $content .= $content .= $this->_status_message('green', 'OK'); } return $content; @@ -758,7 +855,7 @@ class FroxlorInstall } // language selection $language_options = ''; - foreach ($this->_languages as $language_name => $language_file) { + foreach ($this->_languages as $language_file => $language_name) { $language_options .= \Froxlor\UI\HTML::makeoption($language_name, $language_file, $this->_activelng, true, true); } // get language-form-template @@ -775,6 +872,8 @@ class FroxlorInstall $formdata .= $this->_getSectionItemString('mysql_host', true); // database $formdata .= $this->_getSectionItemString('mysql_database', true); + // database overwrite if exists? + $formdata .= $this->_getSectionItemYesNo('mysql_forcecreate', false); // unpriv-user has to be different from root if ($this->_data['mysql_unpriv_user'] == $this->_data['mysql_root_user']) { $style = 'blue'; @@ -804,6 +903,9 @@ class FroxlorInstall } $formdata .= $this->_getSectionItemString('mysql_root_pass', true, $style, 'password'); + $formdata .= $this->_getSectionItemString('mysql_ssl_ca_file', false, $style); + $formdata .= $this->_getSectionItemYesNo('mysql_ssl_verify_server_certificate', false, $style); + /** * admin data */ @@ -833,6 +935,37 @@ class FroxlorInstall */ $section = $this->_lng['install']['serversettings']; eval("\$formdata .= \"" . $this->_getTemplate("datasection") . "\";"); + // distribution + if (! empty($_POST['installstep']) && $this->_data['distribution'] == '') { + $diststyle = 'color:red;'; + } else { + $diststyle = ''; + } + + // show list of available distro's + $distributions_select_data = []; + $distros = glob(\Froxlor\FileDir::makeCorrectDir(\Froxlor\Froxlor::getInstallDir() . '/lib/configfiles/') . '*.xml'); + foreach ($distros as $_distribution) { + $dist = new \Froxlor\Config\ConfigParser($_distribution); + $dist_display = $dist->distributionName . " " . $dist->distributionCodename . " (" . $dist->distributionVersion . ")"; + if (!array_key_exists($dist_display, $distributions_select_data)) { + $distributions_select_data[$dist_display] = ''; + } + $distributions_select_data[$dist_display] .= str_replace(".xml", "", strtolower(basename($_distribution))); + } + + // sort by distribution name + ksort($distributions_select_data); + + $distributions_select = ''; + foreach ($distributions_select_data as $dist_display => $dist_index) { + // create select-box-option + $distributions_select .= \Froxlor\UI\HTML::makeoption($dist_display, $dist_index, $this->_data['distribution'] ?? ''); + // $this->_data['distribution'] + } + + $formdata .= $this->_getSectionItemSelectbox('distribution', $distributions_select, $diststyle); + // servername if (! empty($_POST['installstep']) && $this->_data['servername'] == '') { $style = 'color:red;'; @@ -854,12 +987,12 @@ class FroxlorInstall $websrvstyle = ''; } // apache - $formdata .= $this->_getSectionItemCheckbox('apache2', ($this->_data['webserver'] == 'apache2'), $websrvstyle); - $formdata .= $this->_getSectionItemCheckbox('apache24', ($this->_data['webserver'] == 'apache24'), $websrvstyle); + $formdata .= $this->_getSectionItemCheckbox('webserver', 'apache2', ($this->_data['webserver'] == 'apache2'), $websrvstyle); + $formdata .= $this->_getSectionItemCheckbox('webserver', 'apache24', ($this->_data['webserver'] == 'apache24'), $websrvstyle); // lighttpd - $formdata .= $this->_getSectionItemCheckbox('lighttpd', ($this->_data['webserver'] == 'lighttpd'), $websrvstyle); + $formdata .= $this->_getSectionItemCheckbox('webserver', 'lighttpd', ($this->_data['webserver'] == 'lighttpd'), $websrvstyle); // nginx - $formdata .= $this->_getSectionItemCheckbox('nginx', ($this->_data['webserver'] == 'nginx'), $websrvstyle); + $formdata .= $this->_getSectionItemCheckbox('webserver', 'nginx', ($this->_data['webserver'] == 'nginx'), $websrvstyle); // webserver-user if (! empty($_POST['installstep']) && $this->_data['httpuser'] == '') { $style = 'color:red;'; @@ -895,7 +1028,7 @@ class FroxlorInstall * optional css * @param string $type * optional type of input-box (default: text) - * + * * @return string */ private function _getSectionItemString($fieldname = null, $required = false, $style = "", $type = 'text') @@ -911,7 +1044,7 @@ class FroxlorInstall } /** - * generate form radio field for webserver-selection + * generate form radio field * * @param string $fieldname * @param boolean $checked @@ -919,8 +1052,9 @@ class FroxlorInstall * * @return string */ - private function _getSectionItemCheckbox($fieldname = null, $checked = false, $style = "") + private function _getSectionItemCheckbox($groupname = null, $fieldname = null, $checked = false, $style = "") { + $groupname = $this->_lng['install'][$groupname]; $fieldlabel = $this->_lng['install'][$fieldname]; if ($checked) { $checked = 'checked="checked"'; @@ -930,6 +1064,24 @@ class FroxlorInstall return $sectionitem; } + /** + * generate form selectbox + * + * @param string $fieldname + * @param boolean $options + * @param string $style + * + * @return string + */ + private function _getSectionItemSelectbox($fieldname = null, $options = null, $style = "") + { + $fieldlabel = $this->_lng['install'][$fieldname]; + + $sectionitem = ""; + eval("\$sectionitem .= \"" . $this->_getTemplate("dataitemselect") . "\";"); + return $sectionitem; + } + /** * generate form checkbox field * @@ -964,11 +1116,11 @@ class FroxlorInstall // check for correct php version $content .= $this->_status_message('begin', $this->_lng['requirements']['phpversion']); - if (version_compare("7.0.0", PHP_VERSION, ">=")) { + if (version_compare("7.1.0", PHP_VERSION, ">=")) { $content .= $this->_status_message('red', $this->_lng['requirements']['notfound'] . ' (' . PHP_VERSION . ')'); $_die = true; } else { - if (version_compare("7.1.0", PHP_VERSION, ">=")) { + if (version_compare("7.4.0", PHP_VERSION, ">=")) { $content .= $this->_status_message('orange', $this->_lng['requirements']['newerphpprefered'] . ' (' . PHP_VERSION . ')'); } else { $content .= $this->_status_message('green', PHP_VERSION); @@ -1167,7 +1319,7 @@ class FroxlorInstall * * @param string $template * name of the template including subdirectory - * + * * @return string */ private function _getTemplate($template = null) @@ -1234,10 +1386,12 @@ class FroxlorInstall // from form if (! empty($_POST['serverip'])) { $this->_data['serverip'] = $_POST['serverip']; + $this->_data['serverip'] = inet_ntop(inet_pton($this->_data['serverip'])); return; // from $_SERVER } elseif (! empty($_SERVER['SERVER_ADDR'])) { $this->_data['serverip'] = $_SERVER['SERVER_ADDR']; + $this->_data['serverip'] = inet_ntop(inet_pton($this->_data['serverip'])); return; } // empty @@ -1266,6 +1420,49 @@ class FroxlorInstall } } + /** + * get/guess linux distribution + */ + private function _guessDistribution() + { + // post + if (! empty($_POST['distribution'])) { + $this->_data['distribution'] = $_POST['distribution']; + } else { + // set default os. + $os_dist = array( + 'ID' => 'buster' + ); + $os_version = array( + '0' => '10' + ); + + // read os-release + if (file_exists('/etc/os-release')) { + $os_dist_content = file_get_contents('/etc/os-release'); + $os_dist_arr = explode("\n", $os_dist_content); + $os_dist = []; + foreach ($os_dist_arr as $os_dist_line) { + if (empty(trim($os_dist_line))) continue; + $tmp = explode("=", $os_dist_line); + $os_dist[$tmp[0]] = str_replace('"', "", trim($tmp[1])); + } + if (is_array($os_dist) && array_key_exists('ID', $os_dist) && array_key_exists('VERSION_ID', $os_dist)) { + $os_version = explode('.', $os_dist['VERSION_ID'])[0]; + } + } + + $distros = glob(\Froxlor\FileDir::makeCorrectDir(\Froxlor\Froxlor::getInstallDir() . '/lib/configfiles/') . '*.xml'); + foreach ($distros as $_distribution) { + $dist = new \Froxlor\Config\ConfigParser($_distribution); + $ver = explode('.', $dist->distributionVersion)[0]; + if (strtolower($os_dist['ID']) == strtolower($dist->distributionName) && $os_version == $ver) { + $this->_data['distribution'] = str_replace(".xml", "", strtolower(basename($_distribution))); + } + } + } + } + /** * check if POST field is set and get value for the * internal data array, if not set use either '' or $default if != null diff --git a/install/lib/updateFunctions.php b/install/lib/updateFunctions.php index e3aea709..2b35ee4d 100644 --- a/install/lib/updateFunctions.php +++ b/install/lib/updateFunctions.php @@ -30,6 +30,7 @@ */ function showUpdateStep($task = null, $needs_status = true) { + set_time_limit(30); if (! $needs_status) echo ""; @@ -41,7 +42,6 @@ function showUpdateStep($task = null, $needs_status = true) } \Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, $task); - \Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, $task); } /** @@ -82,7 +82,6 @@ function lastStepStatus($status = -1, $message = '') if ($status == - 1 || $status == 2) { \Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, 'Attention - last update task failed!!!'); - \Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, 'Attention - last update task failed!!!'); } elseif ($status == 0 || $status == 1) { \Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, 'Success'); } diff --git a/install/lng/english.lng.php b/install/lng/english.lng.php index b7dd5ef8..081de41b 100644 --- a/install/lng/english.lng.php +++ b/install/lng/english.lng.php @@ -22,8 +22,8 @@ $lng['requirements']['not_true'] = 'no'; $lng['requirements']['notfound'] = 'not found'; $lng['requirements']['notinstalled'] = 'not installed'; $lng['requirements']['activated'] = 'enabled'; -$lng['requirements']['phpversion'] = 'PHP version >= 7.0'; -$lng['requirements']['newerphpprefered'] = 'Good, but php-7.1 is prefered.'; +$lng['requirements']['phpversion'] = 'PHP version >= 7.1'; +$lng['requirements']['newerphpprefered'] = 'Good, but php-7.4 is preferred.'; $lng['requirements']['phppdo'] = 'PHP PDO extension and PDO-MySQL driver...'; $lng['requirements']['phpsession'] = 'PHP session-extension...'; $lng['requirements']['phpctype'] = 'PHP ctype-extension...'; @@ -39,7 +39,7 @@ $lng['requirements']['phpjson'] = 'PHP json-extension...'; $lng['requirements']['bcmathdescription'] = 'Traffic-calculation related functions will not work correctly!'; $lng['requirements']['zipdescription'] = 'The auto-update feature requires the zip extension.'; $lng['requirements']['openbasedir'] = 'open_basedir...'; -$lng['requirements']['openbasedirenabled'] = 'Froxlor will not work properly with open_basedir enabled. Please disable open_basedir for Froxlor in the coresponding php.ini'; +$lng['requirements']['openbasedirenabled'] = 'Froxlor will not work properly with open_basedir enabled. Please disable open_basedir for Froxlor in the corresponding php.ini'; $lng['requirements']['mysqldump'] = 'MySQL dump tool'; $lng['requirements']['mysqldumpmissing'] = 'Automatic backup of possible existing database is not possible. Please install mysql-client tools'; $lng['requirements']['diedbecauseofrequirements'] = 'Cannot install Froxlor without these requirements! Try to fix them and retry.'; @@ -53,16 +53,20 @@ $lng['install']['welcometext'] = 'Thank you for choosing Froxlor. Please fill ou $lng['install']['database'] = 'Database connection'; $lng['install']['mysql_host'] = 'MySQL-Hostname'; $lng['install']['mysql_database'] = 'Database name'; +$lng['install']['mysql_forcecreate'] = 'Backup and overwrite database if exists?'; $lng['install']['mysql_unpriv_user'] = 'Username for the unprivileged MySQL-account'; $lng['install']['mysql_unpriv_pass'] = 'Password for the unprivileged MySQL-account'; $lng['install']['mysql_root_user'] = 'Username for the MySQL-root-account'; $lng['install']['mysql_root_pass'] = 'Password for the MySQL-root-account'; +$lng['install']['mysql_ssl_ca_file'] = 'MySQL server certificate file path'; +$lng['install']['mysql_ssl_verify_server_certificate'] = 'Verify MySQL TLS certificate'; $lng['install']['admin_account'] = 'Administrator Account'; $lng['install']['admin_user'] = 'Administrator Username'; $lng['install']['admin_pass1'] = 'Administrator Password'; $lng['install']['admin_pass2'] = 'Administrator-Password (confirm)'; $lng['install']['activate_newsfeed'] = 'Enable the official newsfeed
(https://inside.froxlor.org/news/)'; $lng['install']['serversettings'] = 'Server settings'; +$lng['install']['distribution'] = 'Distribution'; $lng['install']['servername'] = 'Server name (FQDN, no ip-address)'; $lng['install']['serverip'] = 'Server IP'; $lng['install']['webserver'] = 'Webserver'; @@ -78,6 +82,8 @@ $lng['install']['testing_mysql_fail'] = 'There seems to be a problem with the da $lng['install']['backup_old_db'] = 'Creating backup of old database...'; $lng['install']['backup_binary_missing'] = 'Could not find mysqldump'; $lng['install']['backup_failed'] = 'Could not backup database'; +$lng['install']['check_db_exists'] = 'Checking database...'; +$lng['install']['db_exists'] = 'Unable to create database. A database with the same name exists and should not be overwritten'; $lng['install']['prepare_db'] = 'Preparing database...'; $lng['install']['create_mysqluser_and_db'] = 'Creating database and username...'; $lng['install']['testing_new_db'] = 'Testing if database and user have been created correctly...'; @@ -86,7 +92,7 @@ $lng['install']['changing_data'] = 'Adjusting settings...'; $lng['install']['creating_entries'] = 'Inserting new values...'; $lng['install']['adding_admin_user'] = 'Creating admin-account...'; $lng['install']['creating_configfile'] = 'Creating configfile...'; -$lng['install']['creating_configfile_temp'] = 'File was saved in /tmp/userdata.inc.php, please move to ' . dirname(dirname(__DIR__)) . '/lib/.'; +$lng['install']['creating_configfile_temp'] = 'File was saved in %s, please move to ' . dirname(dirname(__DIR__)) . '/lib/userdata.inc.php'; $lng['install']['creating_configfile_failed'] = 'Could not create ' . dirname(dirname(__DIR__)) . '/lib/userdata.inc.php, please create it manually with the following content:'; $lng['install']['froxlor_succ_installed'] = 'Froxlor was installed successfully.'; diff --git a/install/lng/french.lng.php b/install/lng/french.lng.php index fdb733ce..36a013a4 100644 --- a/install/lng/french.lng.php +++ b/install/lng/french.lng.php @@ -22,7 +22,7 @@ $lng['requirements']['not_true'] = 'non'; $lng['requirements']['notfound'] = 'introuvable'; $lng['requirements']['notinstalled'] = 'non installé'; $lng['requirements']['activated'] = 'activé'; -$lng['requirements']['phpversion'] = 'PHP version >= 7.0'; +$lng['requirements']['phpversion'] = 'PHP version >= 7.1'; $lng['requirements']['phppdo'] = 'extension PHP PDO et pilote PDO-MySQL ...'; $lng['requirements']['phpxml'] = 'extension PHP XML...'; $lng['requirements']['phpfilter'] = 'extension PHP filter ...'; @@ -53,6 +53,7 @@ $lng['install']['admin_user'] = 'Nom d\'utilisateur administrateur'; $lng['install']['admin_pass1'] = 'Mot de passe administrateur'; $lng['install']['admin_pass2'] = 'Mot de passe administrateur (confirmez)'; $lng['install']['serversettings'] = 'Réglages serveur'; +$lng['install']['distribution'] = 'Distribution'; $lng['install']['servername'] = 'Nom du serveur (FQDN, pas d\'adresse IP)'; $lng['install']['serverip'] = 'Adresse IP du serveur'; $lng['install']['webserver'] = 'Serveur Web'; @@ -76,7 +77,7 @@ $lng['install']['changing_data'] = 'Ajustement des paramètres...'; $lng['install']['creating_entries'] = 'Insertion des nouvelles valeurs...'; $lng['install']['adding_admin_user'] = 'Création du compte administrateur...'; $lng['install']['creating_configfile'] = 'Création du fichier de configuration...'; -$lng['install']['creating_configfile_temp'] = 'Le fichier a été enregistré dans /tmp/userdata.inc.php, merci de le déplacer dans ' . dirname(dirname(__DIR__)) . '/lib/.'; +$lng['install']['creating_configfile_temp'] = 'Le fichier a été enregistré dans %s, merci de le déplacer dans ' . dirname(dirname(__DIR__)) . '/lib/userdata.inc.php'; $lng['install']['creating_configfile_failed'] = 'Impossible de créer ' . dirname(dirname(__DIR__)) . '/lib/userdata.inc.php, merci de le créer manuellement avec le contenu suivant:'; $lng['install']['froxlor_succ_installed'] = 'Froxlor a été installé avec succès.'; diff --git a/install/lng/german.lng.php b/install/lng/german.lng.php index 1f95decc..86c97d3c 100644 --- a/install/lng/german.lng.php +++ b/install/lng/german.lng.php @@ -22,8 +22,8 @@ $lng['requirements']['not_true'] = 'nein'; $lng['requirements']['notfound'] = 'nicht gefunden'; $lng['requirements']['notinstalled'] = 'nicht installiert'; $lng['requirements']['activated'] = 'ist aktiviert.'; -$lng['requirements']['phpversion'] = 'PHP Version >= 7.0'; -$lng['requirements']['newerphpprefered'] = 'Passt, aber php-7.1 wird bevorzugt.'; +$lng['requirements']['phpversion'] = 'PHP Version >= 7.1'; +$lng['requirements']['newerphpprefered'] = 'Passt, aber php-7.4 wird bevorzugt.'; $lng['requirements']['phppdo'] = 'PHP PDO Erweiterung und PDO-MySQL Treiber...'; $lng['requirements']['phpsession'] = 'PHP session-Erweiterung...'; $lng['requirements']['phpctype'] = 'PHP ctype-Erweiterung...'; @@ -53,16 +53,20 @@ $lng['install']['welcometext'] = 'Vielen Dank dass Sie sich für Froxlor entschi $lng['install']['database'] = 'Datenbankverbindung'; $lng['install']['mysql_host'] = 'MySQL-Hostname'; $lng['install']['mysql_database'] = 'Datenbank Name'; +$lng['install']['mysql_forcecreate'] = 'Datenbank sichern und überschreiben wenn vorhanden?'; $lng['install']['mysql_unpriv_user'] = 'Benutzername für den unprivilegierten MySQL-Account'; $lng['install']['mysql_unpriv_pass'] = 'Passwort für den unprivilegierten MySQL-Account'; $lng['install']['mysql_root_user'] = 'Benutzername für den MySQL-Root-Account'; $lng['install']['mysql_root_pass'] = 'Passwort für den MySQL-Root-Account'; +$lng['install']['mysql_ssl_ca_file'] = 'MySQL-Server Zertifikatspfad'; +$lng['install']['mysql_ssl_verify_server_certificate'] = 'Validieren des MySQL-Server Zertifikats'; $lng['install']['admin_account'] = 'Admin-Zugang'; $lng['install']['admin_user'] = 'Administrator-Benutzername'; $lng['install']['admin_pass1'] = 'Administrator-Passwort'; $lng['install']['admin_pass2'] = 'Administrator-Passwort (Bestätigung)'; $lng['install']['activate_newsfeed'] = 'Aktiviere das offizielle Newsfeed
(https://inside.froxlor.org/news/)'; $lng['install']['serversettings'] = 'Servereinstellungen'; +$lng['install']['distribution'] = 'Distribution'; $lng['install']['servername'] = 'Servername (FQDN, keine IP-Adresse)'; $lng['install']['serverip'] = 'Server-IP'; $lng['install']['webserver'] = 'Webserver'; @@ -78,6 +82,8 @@ $lng['install']['testing_mysql_fail'] = 'Bei der Verwendung der Datenbank gibt e $lng['install']['backup_old_db'] = 'Sicherung vorheriger Datenbank...'; $lng['install']['backup_binary_missing'] = 'Konnte mysqldump nicht finden'; $lng['install']['backup_failed'] = 'Sicherung fehlgeschlagen'; +$lng['install']['check_db_exists'] = 'Databenbank wird geprüft...'; +$lng['install']['db_exists'] = 'Datenbank kann nicht erstellt werden. Eine Datenbank mit dem selben Namen existiert bereits und soll nicht überschrieben werden.'; $lng['install']['prepare_db'] = 'Datenbank wird vorbereitet...'; $lng['install']['create_mysqluser_and_db'] = 'Erstelle Datenbank und Benutzer...'; $lng['install']['testing_new_db'] = 'Teste, ob Datenbank und Benutzer korrekt angelegt wurden...'; @@ -86,7 +92,7 @@ $lng['install']['changing_data'] = 'Einstellungen anpassen...'; $lng['install']['creating_entries'] = 'Trage neue Werte ein...'; $lng['install']['adding_admin_user'] = 'Erstelle Admin-Benutzer...'; $lng['install']['creating_configfile'] = 'Erstelle Konfigurationsdatei...'; -$lng['install']['creating_configfile_temp'] = 'Datei wurde in /tmp/userdata.inc.php gespeichert, bitte nach ' . dirname(dirname(__DIR__)) . '/lib/ verschieben.'; +$lng['install']['creating_configfile_temp'] = 'Datei wurde in %s gespeichert, bitte nach ' . dirname(dirname(__DIR__)) . '/lib/userdata.inc.php verschieben.'; $lng['install']['creating_configfile_failed'] = 'Konnte ' . dirname(dirname(__DIR__)) . '/lib/userdata.inc.php nicht erstellen, bitte manuell mit folgendem Inhalt anlegen:'; $lng['install']['froxlor_succ_installed'] = 'Froxlor wurde erfolgreich installiert.'; diff --git a/install/scripts/php-sessionclean.php b/install/scripts/php-sessionclean.php new file mode 100755 index 00000000..41f633db --- /dev/null +++ b/install/scripts/php-sessionclean.php @@ -0,0 +1,31 @@ +#!/usr/bin/php + (2018-) + * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt + * @package Cron + * + */ + +// Check if we're in the CLI +if (@php_sapi_name() !== 'cli') { + die('This script will only work in the shell.'); +} + +require dirname(dirname(__DIR__)) . '/vendor/autoload.php'; + +// give control to command line handler +try { + \Froxlor\Cli\PhpSessioncleanCmd::processParameters($argc, $argv); +} catch (Exception $e) { + \Froxlor\Cli\PhpSessioncleanCmd::printerr($e->getMessage()); +} diff --git a/install/templates/dataitemchk.tpl b/install/templates/dataitemchk.tpl index 30279bfa..46c90d1c 100644 --- a/install/templates/dataitemchk.tpl +++ b/install/templates/dataitemchk.tpl @@ -1,4 +1,4 @@

- - {$fieldlabel} + + {$fieldlabel}

diff --git a/install/templates/dataitemselect.tpl b/install/templates/dataitemselect.tpl new file mode 100644 index 00000000..91701bc6 --- /dev/null +++ b/install/templates/dataitemselect.tpl @@ -0,0 +1,6 @@ +

+ + +

diff --git a/install/updates/froxlor/0.10/update_0.10.inc.php b/install/updates/froxlor/0.10/update_0.10.inc.php index 3da2dea7..7889077e 100644 --- a/install/updates/froxlor/0.10/update_0.10.inc.php +++ b/install/updates/froxlor/0.10/update_0.10.inc.php @@ -1,6 +1,7 @@ (2010-) * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt * @package Install - * + * */ if (! defined('_CRON_UPDATE')) { if (! defined('AREA') || (defined('AREA') && AREA != 'admin') || ! isset($userinfo['loginname']) || (isset($userinfo['loginname']) && $userinfo['loginname'] == '')) { @@ -546,7 +547,7 @@ if (\Froxlor\Froxlor::isFroxlorVersion('0.10.10')) { if (\Froxlor\Froxlor::isDatabaseVersion('201912311')) { showUpdateStep("Migrate logfiles_format setting"); $current_format = Settings::Set('system.logfiles_format'); - if (!empty($current_format)) { + if (! empty($current_format)) { Settings::Set('system.logfiles_format', '"' . Settings::Get('system.logfiles_format') . '"'); lastStepStatus(0); } else { @@ -571,3 +572,401 @@ if (\Froxlor\Froxlor::isFroxlorVersion('0.10.12')) { showUpdateStep("Updating from 0.10.12 to 0.10.13", false); \Froxlor\Froxlor::updateToVersion('0.10.13'); } + +if (\Froxlor\Froxlor::isDatabaseVersion('201912313')) { + showUpdateStep("Adding new field to domains table"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `domain_ace` varchar(255) NOT NULL default '' AFTER `domain`;"); + lastStepStatus(0); + + showUpdateStep("Updating domain entries"); + $upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_DOMAINS . "` SET `domain_ace` = :ace WHERE `id` = :domainid"); + $sel_stmt = Database::prepare("SELECT id, domain FROM `" . TABLE_PANEL_DOMAINS . "` ORDER BY id ASC"); + Database::pexecute($sel_stmt); + $idna_convert = new \Froxlor\Idna\IdnaWrapper(); + while ($domain = $sel_stmt->fetch(\PDO::FETCH_ASSOC)) { + Database::pexecute($upd_stmt, [ + 'ace' => $idna_convert->decode($domain['domain']), + 'domainid' => $domain['id'] + ]); + } + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('202002290'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.10.13')) { + showUpdateStep("Updating from 0.10.13 to 0.10.14", false); + \Froxlor\Froxlor::updateToVersion('0.10.14'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.10.14')) { + showUpdateStep("Updating from 0.10.14 to 0.10.15", false); + \Froxlor\Froxlor::updateToVersion('0.10.15'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('202002290')) { + showUpdateStep("Adding new setting to validate DNS when using Let's Encrypt"); + Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `settinggroup` = 'system' AND `varname` = 'disable_le_selfcheck'"); + $le_domain_dnscheck = isset($_POST['system_le_domain_dnscheck']) ? (int) $_POST['system_le_domain_dnscheck'] : '1'; + Settings::AddNew("system.le_domain_dnscheck", $le_domain_dnscheck); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('202004140'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.10.15')) { + showUpdateStep("Updating from 0.10.15 to 0.10.16", false); + \Froxlor\Froxlor::updateToVersion('0.10.16'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('202004140')) { + + showUpdateStep("Adding unique key on domainid field in domain ssl table"); + // check for duplicate entries prior to set a unique key to avoid errors on update + Database::query(" + DELETE a.* FROM domain_ssl_settings AS a + LEFT JOIN domain_ssl_settings AS b ON + ((b.`domainid`=a.`domainid` AND UNIX_TIMESTAMP(b.`expirationdate`) > UNIX_TIMESTAMP(a.`expirationdate`)) + OR (UNIX_TIMESTAMP(b.`expirationdate`) = UNIX_TIMESTAMP(a.`expirationdate`) AND b.`id`>a.`id`)) + WHERE b.`id` IS NOT NULL + "); + Database::query("ALTER TABLE `domain_ssl_settings` ADD UNIQUE(`domainid`)"); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('202005150'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.10.16')) { + showUpdateStep("Updating from 0.10.16 to 0.10.17", false); + \Froxlor\Froxlor::updateToVersion('0.10.17'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.10.17')) { + showUpdateStep("Updating from 0.10.17 to 0.10.18", false); + \Froxlor\Froxlor::updateToVersion('0.10.18'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.10.18')) { + showUpdateStep("Updating from 0.10.18 to 0.10.19", false); + \Froxlor\Froxlor::updateToVersion('0.10.19'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('202005150')) { + + showUpdateStep("Add new performance indexes", true); + Database::query("ALTER TABLE panel_customers ADD INDEX guid (guid);"); + Database::query("ALTER TABLE panel_tasks ADD INDEX type (type);"); + Database::query("ALTER TABLE mail_users ADD INDEX username (username);"); + Database::query("ALTER TABLE mail_users ADD INDEX imap (imap);"); + Database::query("ALTER TABLE mail_users ADD INDEX pop3 (pop3);"); + Database::query("ALTER TABLE ftp_groups ADD INDEX gid (gid);"); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('202007240'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.10.19')) { + showUpdateStep("Updating from 0.10.19 to 0.10.20", false); + \Froxlor\Froxlor::updateToVersion('0.10.20'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('202007240')) { + + showUpdateStep("Removing old unused table", true); + Database::query("DROP TABLE IF EXISTS `panel_diskspace_admins`;"); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('202009070'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.10.20')) { + showUpdateStep("Updating from 0.10.20 to 0.10.21", false); + \Froxlor\Froxlor::updateToVersion('0.10.21'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.10.21')) { + + showUpdateStep("Adding settings for ssl-vhost default content if not updated from db-version 201910110", true); + Settings::AddNew("system.default_sslvhostconf", ''); + lastStepStatus(0); + + showUpdateStep("Updating from 0.10.21 to 0.10.22", false); + \Froxlor\Froxlor::updateToVersion('0.10.22'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.10.22')) { + showUpdateStep("Updating from 0.10.22 to 0.10.23", false); + \Froxlor\Froxlor::updateToVersion('0.10.23'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.10.23')) { + showUpdateStep("Updating from 0.10.23 to 0.10.23.1", false); + \Froxlor\Froxlor::updateToVersion('0.10.23.1'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('202009070')) { + + showUpdateStep("Adding setting to hide incompatible settings", true); + Settings::AddNew("system.hide_incompatible_settings", '0'); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('202012300'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('202012300')) { + + showUpdateStep("Adding setting for DKIM private key extension/suffix", true); + Settings::AddNew("dkim.privkeysuffix", '.priv'); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('202101200'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.10.23.1')) { + showUpdateStep("Updating from 0.10.23.1 to 0.10.24", false); + \Froxlor\Froxlor::updateToVersion('0.10.24'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('202101200')) { + + showUpdateStep("Adding setting for mail address used in SOA records", true); + Settings::AddNew("system.soaemail", ''); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('202102200'); +} + +/* + * skip due to potential "1118 Row size too large" error + * +if (\Froxlor\Froxlor::isDatabaseVersion('202102200')) { + + showUpdateStep("Add new description fields to mail and domain table", true); + Database::query("ALTER TABLE panel_domains ADD `description` varchar(255) NOT NULL DEFAULT '' AFTER `ssl_sessiontickets`;"); + Database::query("ALTER TABLE mail_virtual ADD `description` varchar(255) NOT NULL DEFAULT '' AFTER `iscatchall`"); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('202103030'); +} +*/ + +if (\Froxlor\Froxlor::isFroxlorVersion('0.10.24')) { + showUpdateStep("Updating from 0.10.24 to 0.10.25", false); + \Froxlor\Froxlor::updateToVersion('0.10.25'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('202102200') || \Froxlor\Froxlor::isDatabaseVersion('202103030')) { + + showUpdateStep("Refactoring columns from large tables", true); + Database::query("ALTER TABLE panel_domains CHANGE `ssl_protocols` `ssl_protocols` varchar(255) NOT NULL DEFAULT '';"); + Database::query("ALTER TABLE panel_domains CHANGE `ssl_cipher_list` `ssl_cipher_list` varchar(500) NOT NULL DEFAULT '';"); + Database::query("ALTER TABLE panel_domains CHANGE `tlsv13_cipher_list` `tlsv13_cipher_list` varchar(500) NOT NULL DEFAULT '';"); + lastStepStatus(0); + + showUpdateStep("Add new description fields to mail and domain table", true); + $result = Database::query("DESCRIBE `panel_domains`"); + $columnfound = 0; + while ($row = $result->fetch(PDO::FETCH_ASSOC)) { + if ($row['Field'] == 'description') { + $columnfound = 1; + } + } + if (! $columnfound) { + Database::query("ALTER TABLE panel_domains ADD `description` varchar(255) NOT NULL DEFAULT '' AFTER `ssl_sessiontickets`;"); + } + $result = Database::query("DESCRIBE `mail_virtual`"); + $columnfound = 0; + while ($row = $result->fetch(PDO::FETCH_ASSOC)) { + if ($row['Field'] == 'description') { + $columnfound = 1; + } + } + if (! $columnfound) { + Database::query("ALTER TABLE mail_virtual ADD `description` varchar(255) NOT NULL DEFAULT '' AFTER `iscatchall`"); + } + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('202103110'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('202103110')) { + + showUpdateStep("Adding settings for imprint, terms of use and privacy policy URLs", true); + Settings::AddNew("panel.imprint_url", ''); + Settings::AddNew("panel.terms_url", ''); + Settings::AddNew("panel.privacy_url", ''); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('202103240'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.10.25')) { + showUpdateStep("Updating from 0.10.25 to 0.10.26", false); + \Froxlor\Froxlor::updateToVersion('0.10.26'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('202103240')) { + + showUpdateStep("Adding setting for default serveralias value for new domains", true); + Settings::AddNew("system.domaindefaultalias", '0'); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('202106160'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('202106160')) { + + showUpdateStep("Adjusting Let's Encrypt endpoint configuration to support ZeroSSL", true); + if (Settings::Get('system.letsencryptca') == 'testing') { + Settings::Set("system.letsencryptca", 'letsencrypt_test'); + } else { + Settings::Set("system.letsencryptca", 'letsencrypt'); + } + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('202106270'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('202106270')) { + showUpdateStep("Adding custom logo image settings", true); + Settings::AddNew("panel.logo_image_header", ''); + Settings::AddNew("panel.logo_image_login", ''); + lastStepStatus(0); + + // Migrating old custom logo over, if exists + $custom_logo_file_old = \Froxlor\Froxlor::getInstallDir() . '/templates/Sparkle/assets/img/logo_custom.png'; + if (file_exists($custom_logo_file_old)) { + showUpdateStep("Migrating existing custom logo to new settings", true); + + $path = \Froxlor\Froxlor::getInstallDir().'/img/'; + if (!is_dir($path) && !mkdir($path, 0775)) { + throw new \Exception("img directory does not exist and cannot be created"); + } + if (!is_writable($path)) { + if (!chmod($path, 0775)) { + throw new \Exception("Cannot write to img directory"); + } + } + + // Save as new custom logo header + $save_to = 'logo_header.png'; + copy($custom_logo_file_old, $path.$save_to); + Settings::Set("panel.logo_image_header", "img/{$save_to}?v=".time()); + + // Save as new custom logo login + $save_to = 'logo_login.png'; + copy($custom_logo_file_old, $path.$save_to); + Settings::Set("panel.logo_image_login", "img/{$save_to}?v=".time()); + + lastStepStatus(0); + } + + \Froxlor\Froxlor::updateToDbVersion('202107070'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.10.26')) { + showUpdateStep("Updating from 0.10.26 to 0.10.27", false); + \Froxlor\Froxlor::updateToVersion('0.10.27'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('202107070')) { + showUpdateStep("Adding settings to overwrite theme- or custom theme-logo with the new logo settings", true); + Settings::AddNew("panel.logo_overridetheme", '0'); + Settings::AddNew("panel.logo_overridecustom", '0'); + lastStepStatus(0); + \Froxlor\Froxlor::updateToDbVersion('202107200'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('202107200')) { + showUpdateStep("Adding settings to define default value of 'create std-subdomain' when creating a customer", true); + Settings::AddNew("system.createstdsubdom_default", '1'); + lastStepStatus(0); + \Froxlor\Froxlor::updateToDbVersion('202107210'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('202107210')) { + showUpdateStep("Normalizing ipv6 for correct comparison", true); + $result_stmt = Database::prepare(" + SELECT `id`, `ip` FROM `" . TABLE_PANEL_IPSANDPORTS . "`" + ); + Database::pexecute($result_stmt); + $upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_IPSANDPORTS . "` SET `ip` = :ip WHERE `id` = :id"); + while ($iprow = $result_stmt->fetch(\PDO::FETCH_ASSOC)) { + if (Validate::is_ipv6($iprow['ip'])) { + $ip = inet_ntop(inet_pton($iprow['ip'])); + Database::pexecute($upd_stmt, [ + 'ip' => $ip, + 'id' => $iprow['id'] + ]); + } + } + lastStepStatus(0); + \Froxlor\Froxlor::updateToDbVersion('202107260'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('202107260')) { + showUpdateStep("Removing setting for search-engine allow yes/no", true); + Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `settinggroup` = 'panel' AND `varname` = 'no_robots'"); + lastStepStatus(0); + showUpdateStep("Adding setting to have all froxlor customers in a local group", true); + Settings::AddNew("system.froxlorusergroup", ''); + Settings::AddNew("system.froxlorusergroup_gid", ''); + lastStepStatus(0); + \Froxlor\Froxlor::updateToDbVersion('202107300'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('202107300')) { + showUpdateStep("Adds the possibility to select the PowerDNS Operation Mode", true); + Settings::AddNew("system.powerdns_mode", 'Native'); + lastStepStatus(0); + \Froxlor\Froxlor::updateToDbVersion('202108180'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.10.27')) { + showUpdateStep("Updating from 0.10.27 to 0.10.28", false); + \Froxlor\Froxlor::updateToVersion('0.10.28'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('202108180')) { + showUpdateStep("Adding czech language file", true); + Database::query("INSERT INTO `" . TABLE_PANEL_LANGUAGE . "` SET `language` = 'Česká republika', `iso` = 'cs', `file` = 'lng/czech.lng.php'"); + lastStepStatus(0); + \Froxlor\Froxlor::updateToDbVersion('202109040'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.10.28')) { + showUpdateStep("Updating from 0.10.28 to 0.10.29", false); + \Froxlor\Froxlor::updateToVersion('0.10.29'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.10.29')) { + showUpdateStep("Updating from 0.10.29 to 0.10.29.1", false); + \Froxlor\Froxlor::updateToVersion('0.10.29.1'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.10.29.1')) { + showUpdateStep("Updating from 0.10.29.1 to 0.10.30", false); + \Froxlor\Froxlor::updateToVersion('0.10.30'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.10.30')) { + showUpdateStep("Updating from 0.10.30 to 0.10.31", false); + \Froxlor\Froxlor::updateToVersion('0.10.31'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('202109040')) { + showUpdateStep("Add setting for acme.sh install location", true); + Settings::AddNew("system.acmeshpath", '/root/.acme.sh/acme.sh'); + lastStepStatus(0); + \Froxlor\Froxlor::updateToDbVersion('202112310'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.10.31')) { + showUpdateStep("Updating from 0.10.31 to 0.10.32", false); + \Froxlor\Froxlor::updateToVersion('0.10.32'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.10.32')) { + showUpdateStep("Updating from 0.10.32 to 0.10.33", false); + \Froxlor\Froxlor::updateToVersion('0.10.33'); +} diff --git a/install/updates/froxlor/0.9/update_0.9.inc.php b/install/updates/froxlor/0.9/update_0.9.inc.php index 4a1ed614..156541f3 100644 --- a/install/updates/froxlor/0.9/update_0.9.inc.php +++ b/install/updates/froxlor/0.9/update_0.9.inc.php @@ -2505,7 +2505,7 @@ if (\Froxlor\Froxlor::isFroxlorVersion('0.9.30')) { showUpdateStep("Updating from 0.9.30 to 0.9.31-dev1", true); lastStepStatus(0); - showUpdateStep("Removing unsused tables"); + showUpdateStep("Removing unused tables"); Database::query("DROP TABLE IF EXISTS `ipsandports_docrootsettings`;"); Database::query("DROP TABLE IF EXISTS `domain_docrootsettings`;"); lastStepStatus(0); @@ -2856,7 +2856,7 @@ if (\Froxlor\Froxlor::isFroxlorVersion('0.9.32-rc1')) { Settings::AddNew("system.croncmdline", $croncmdline); // add task to generate cron.d-file \Froxlor\System\Cronjob::inserttask('99'); - // silenty add the auto-update setting - we do not want everybody to know and use this + // silently add the auto-update setting - we do not want everybody to know and use this // as it is a very dangerous setting Settings::AddNew("system.cron_allowautoupdate", 0); lastStepStatus(0); @@ -3872,7 +3872,7 @@ opcache.interned_strings_buffer'); if (\Froxlor\Froxlor::isDatabaseVersion('201801110')) { - showUpdateStep("Adding php-fpm php PATH setting for envrironment"); + showUpdateStep("Adding php-fpm php PATH setting for environment"); Settings::AddNew("phpfpm.envpath", '/usr/local/bin:/usr/bin:/bin'); lastStepStatus(0); diff --git a/install/updates/preconfig.php b/install/updates/preconfig.php index c2fd9dcf..66c29416 100644 --- a/install/updates/preconfig.php +++ b/install/updates/preconfig.php @@ -19,7 +19,7 @@ * Function getPreConfig * * outputs various content before the update process - * can be continued (askes for agreement whatever is being asked) + * can be continued (asks for agreement whatever is being asked) * * @param string $current_version * @param int $current_db_version @@ -34,6 +34,9 @@ function getPreConfig($current_version, $current_db_version) include_once \Froxlor\FileDir::makeCorrectFile(dirname(__FILE__) . '/preconfig/0.9/preconfig_0.9.inc.php'); parseAndOutputPreconfig($has_preconfig, $return, $current_version, $current_db_version); + include_once \Froxlor\FileDir::makeCorrectFile(dirname(__FILE__) . '/preconfig/0.10/preconfig_0.10.inc.php'); + parseAndOutputPreconfig2($has_preconfig, $return, $current_version, $current_db_version); + $return .= '

' . \Froxlor\UI\HTML::makecheckbox('update_changesagreed', 'I have read the update notifications above and I am aware of the changes made to my system.', '1', true, '0', true); $return .= ''; $return .= ''; diff --git a/install/updates/preconfig/0.10/preconfig_0.10.inc.php b/install/updates/preconfig/0.10/preconfig_0.10.inc.php new file mode 100644 index 00000000..91c9e140 --- /dev/null +++ b/install/updates/preconfig/0.10/preconfig_0.10.inc.php @@ -0,0 +1,42 @@ + (2010-) + * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt + * @package Updater + * + */ + +/** + * checks if the new-version has some updating to do + * + * @param boolean $has_preconfig + * pointer to check if any preconfig has to be output + * @param string $return + * pointer to output string + * @param string $current_version + * current froxlor version + * + * @return null + */ +function parseAndOutputPreconfig2(&$has_preconfig, &$return, $current_version, $current_db_version) +{ + global $lng; + + if (versionInUpdate($current_db_version, '202004140')) { + $has_preconfig = true; + $description = 'Froxlor can now optionally validate the dns entries of domains that request Lets Encrypt certificates to reduce dns-related problems (e.g. freshly registered domain or updated a-record).
'; + $question = 'Validate DNS of domains when using Lets Encrypt '; + $question .= \Froxlor\UI\HTML::makeyesno('system_le_domain_dnscheck', '1', '0', '1'); + + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); + } +} diff --git a/install/updates/preconfig/0.9/preconfig_0.9.inc.php b/install/updates/preconfig/0.9/preconfig_0.9.inc.php index 41af997f..848f032d 100644 --- a/install/updates/preconfig/0.9/preconfig_0.9.inc.php +++ b/install/updates/preconfig/0.9/preconfig_0.9.inc.php @@ -414,7 +414,7 @@ function parseAndOutputPreconfig(&$has_preconfig, &$return, $current_version, $c if (Settings::Get('system.webserver') == 'apache2') { $has_preconfig = true; - $description = 'Froxlor now supports the new Apache 2.4. Please be aware that you need to load additional apache-modules in ordner to use it.
'; + $description = 'Froxlor now supports the new Apache 2.4. Please be aware that you need to load additional apache-modules in order to use it.
'; $description .= '
LoadModule authz_core_module modules/mod_authz_core.so
 					LoadModule authz_host_module modules/mod_authz_host.so

'; $question = 'Do you want to enable the Apache-2.4 modification?: '; @@ -600,8 +600,8 @@ function parseAndOutputPreconfig(&$has_preconfig, &$return, $current_version, $c if (versionInUpdate($current_version, '0.9.32-rc2')) { $has_preconfig = true; $description = 'To customize the command which executes the cronjob (php - basically) change the path below according to your system.

'; - $question = 'Please specify the command to execute cronscripts (default: "/usr/bin/nice -n 5 /usr/bin/php5 -q")
'; - $question .= '
'; + $question = 'Please specify the command to execute cronscripts (default: "/usr/bin/nice -n 5 /usr/bin/php -q")
'; + $question .= '
'; eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } diff --git a/js/html5shiv.min.js b/js/html5shiv.min.js index d4c731ad..355afd10 100644 --- a/js/html5shiv.min.js +++ b/js/html5shiv.min.js @@ -1,4 +1,4 @@ /** -* @preserve HTML5 Shiv 3.7.2 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed +* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed */ -!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.2",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b)}(this,document); \ No newline at end of file +!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/js/jquery.min.js b/js/jquery.min.js index 4d9b3a25..d467083b 100644 --- a/js/jquery.min.js +++ b/js/jquery.min.js @@ -1,2 +1,2 @@ -/*! jQuery v3.3.1 | (c) JS Foundation and other contributors | jquery.org/license */ -!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(e,t){"use strict";var n=[],r=e.document,i=Object.getPrototypeOf,o=n.slice,a=n.concat,s=n.push,u=n.indexOf,l={},c=l.toString,f=l.hasOwnProperty,p=f.toString,d=p.call(Object),h={},g=function e(t){return"function"==typeof t&&"number"!=typeof t.nodeType},y=function e(t){return null!=t&&t===t.window},v={type:!0,src:!0,noModule:!0};function m(e,t,n){var i,o=(t=t||r).createElement("script");if(o.text=e,n)for(i in v)n[i]&&(o[i]=n[i]);t.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[c.call(e)]||"object":typeof e}var b="3.3.1",w=function(e,t){return new w.fn.init(e,t)},T=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;w.fn=w.prototype={jquery:"3.3.1",constructor:w,length:0,toArray:function(){return o.call(this)},get:function(e){return null==e?o.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=w.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return w.each(this,e)},map:function(e){return this.pushStack(w.map(this,function(t,n){return e.call(t,n,t)}))},slice:function(){return this.pushStack(o.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n0&&t-1 in e)}var E=function(e){var t,n,r,i,o,a,s,u,l,c,f,p,d,h,g,y,v,m,x,b="sizzle"+1*new Date,w=e.document,T=0,C=0,E=ae(),k=ae(),S=ae(),D=function(e,t){return e===t&&(f=!0),0},N={}.hasOwnProperty,A=[],j=A.pop,q=A.push,L=A.push,H=A.slice,O=function(e,t){for(var n=0,r=e.length;n+~]|"+M+")"+M+"*"),z=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),X=new RegExp(W),U=new RegExp("^"+R+"$"),V={ID:new RegExp("^#("+R+")"),CLASS:new RegExp("^\\.("+R+")"),TAG:new RegExp("^("+R+"|[*])"),ATTR:new RegExp("^"+I),PSEUDO:new RegExp("^"+W),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+P+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},G=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Q=/^[^{]+\{\s*\[native \w/,J=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,K=/[+~]/,Z=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ee=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},te=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ne=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},re=function(){p()},ie=me(function(e){return!0===e.disabled&&("form"in e||"label"in e)},{dir:"parentNode",next:"legend"});try{L.apply(A=H.call(w.childNodes),w.childNodes),A[w.childNodes.length].nodeType}catch(e){L={apply:A.length?function(e,t){q.apply(e,H.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function oe(e,t,r,i){var o,s,l,c,f,h,v,m=t&&t.ownerDocument,T=t?t.nodeType:9;if(r=r||[],"string"!=typeof e||!e||1!==T&&9!==T&&11!==T)return r;if(!i&&((t?t.ownerDocument||t:w)!==d&&p(t),t=t||d,g)){if(11!==T&&(f=J.exec(e)))if(o=f[1]){if(9===T){if(!(l=t.getElementById(o)))return r;if(l.id===o)return r.push(l),r}else if(m&&(l=m.getElementById(o))&&x(t,l)&&l.id===o)return r.push(l),r}else{if(f[2])return L.apply(r,t.getElementsByTagName(e)),r;if((o=f[3])&&n.getElementsByClassName&&t.getElementsByClassName)return L.apply(r,t.getElementsByClassName(o)),r}if(n.qsa&&!S[e+" "]&&(!y||!y.test(e))){if(1!==T)m=t,v=e;else if("object"!==t.nodeName.toLowerCase()){(c=t.getAttribute("id"))?c=c.replace(te,ne):t.setAttribute("id",c=b),s=(h=a(e)).length;while(s--)h[s]="#"+c+" "+ve(h[s]);v=h.join(","),m=K.test(e)&&ge(t.parentNode)||t}if(v)try{return L.apply(r,m.querySelectorAll(v)),r}catch(e){}finally{c===b&&t.removeAttribute("id")}}}return u(e.replace(B,"$1"),t,r,i)}function ae(){var e=[];function t(n,i){return e.push(n+" ")>r.cacheLength&&delete t[e.shift()],t[n+" "]=i}return t}function se(e){return e[b]=!0,e}function ue(e){var t=d.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function le(e,t){var n=e.split("|"),i=n.length;while(i--)r.attrHandle[n[i]]=t}function ce(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function fe(e){return function(t){return"input"===t.nodeName.toLowerCase()&&t.type===e}}function pe(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function de(e){return function(t){return"form"in t?t.parentNode&&!1===t.disabled?"label"in t?"label"in t.parentNode?t.parentNode.disabled===e:t.disabled===e:t.isDisabled===e||t.isDisabled!==!e&&ie(t)===e:t.disabled===e:"label"in t&&t.disabled===e}}function he(e){return se(function(t){return t=+t,se(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}function ge(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}n=oe.support={},o=oe.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&"HTML"!==t.nodeName},p=oe.setDocument=function(e){var t,i,a=e?e.ownerDocument||e:w;return a!==d&&9===a.nodeType&&a.documentElement?(d=a,h=d.documentElement,g=!o(d),w!==d&&(i=d.defaultView)&&i.top!==i&&(i.addEventListener?i.addEventListener("unload",re,!1):i.attachEvent&&i.attachEvent("onunload",re)),n.attributes=ue(function(e){return e.className="i",!e.getAttribute("className")}),n.getElementsByTagName=ue(function(e){return e.appendChild(d.createComment("")),!e.getElementsByTagName("*").length}),n.getElementsByClassName=Q.test(d.getElementsByClassName),n.getById=ue(function(e){return h.appendChild(e).id=b,!d.getElementsByName||!d.getElementsByName(b).length}),n.getById?(r.filter.ID=function(e){var t=e.replace(Z,ee);return function(e){return e.getAttribute("id")===t}},r.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&g){var n=t.getElementById(e);return n?[n]:[]}}):(r.filter.ID=function(e){var t=e.replace(Z,ee);return function(e){var n="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return n&&n.value===t}},r.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&g){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),r.find.TAG=n.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):n.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},r.find.CLASS=n.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&g)return t.getElementsByClassName(e)},v=[],y=[],(n.qsa=Q.test(d.querySelectorAll))&&(ue(function(e){h.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&y.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||y.push("\\["+M+"*(?:value|"+P+")"),e.querySelectorAll("[id~="+b+"-]").length||y.push("~="),e.querySelectorAll(":checked").length||y.push(":checked"),e.querySelectorAll("a#"+b+"+*").length||y.push(".#.+[+~]")}),ue(function(e){e.innerHTML="";var t=d.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&y.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&y.push(":enabled",":disabled"),h.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&y.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),y.push(",.*:")})),(n.matchesSelector=Q.test(m=h.matches||h.webkitMatchesSelector||h.mozMatchesSelector||h.oMatchesSelector||h.msMatchesSelector))&&ue(function(e){n.disconnectedMatch=m.call(e,"*"),m.call(e,"[s!='']:x"),v.push("!=",W)}),y=y.length&&new RegExp(y.join("|")),v=v.length&&new RegExp(v.join("|")),t=Q.test(h.compareDocumentPosition),x=t||Q.test(h.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return f=!0,0;var r=!e.compareDocumentPosition-!t.compareDocumentPosition;return r||(1&(r=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!n.sortDetached&&t.compareDocumentPosition(e)===r?e===d||e.ownerDocument===w&&x(w,e)?-1:t===d||t.ownerDocument===w&&x(w,t)?1:c?O(c,e)-O(c,t):0:4&r?-1:1)}:function(e,t){if(e===t)return f=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===d?-1:t===d?1:i?-1:o?1:c?O(c,e)-O(c,t):0;if(i===o)return ce(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?ce(a[r],s[r]):a[r]===w?-1:s[r]===w?1:0},d):d},oe.matches=function(e,t){return oe(e,null,null,t)},oe.matchesSelector=function(e,t){if((e.ownerDocument||e)!==d&&p(e),t=t.replace(z,"='$1']"),n.matchesSelector&&g&&!S[t+" "]&&(!v||!v.test(t))&&(!y||!y.test(t)))try{var r=m.call(e,t);if(r||n.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(e){}return oe(t,d,null,[e]).length>0},oe.contains=function(e,t){return(e.ownerDocument||e)!==d&&p(e),x(e,t)},oe.attr=function(e,t){(e.ownerDocument||e)!==d&&p(e);var i=r.attrHandle[t.toLowerCase()],o=i&&N.call(r.attrHandle,t.toLowerCase())?i(e,t,!g):void 0;return void 0!==o?o:n.attributes||!g?e.getAttribute(t):(o=e.getAttributeNode(t))&&o.specified?o.value:null},oe.escape=function(e){return(e+"").replace(te,ne)},oe.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},oe.uniqueSort=function(e){var t,r=[],i=0,o=0;if(f=!n.detectDuplicates,c=!n.sortStable&&e.slice(0),e.sort(D),f){while(t=e[o++])t===e[o]&&(i=r.push(o));while(i--)e.splice(r[i],1)}return c=null,e},i=oe.getText=function(e){var t,n="",r=0,o=e.nodeType;if(o){if(1===o||9===o||11===o){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=i(e)}else if(3===o||4===o)return e.nodeValue}else while(t=e[r++])n+=i(t);return n},(r=oe.selectors={cacheLength:50,createPseudo:se,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(Z,ee),e[3]=(e[3]||e[4]||e[5]||"").replace(Z,ee),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||oe.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&oe.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return V.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=a(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(Z,ee).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=E[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&E(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=oe.attr(r,e);return null==i?"!="===t:!t||(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i.replace($," ")+" ").indexOf(n)>-1:"|="===t&&(i===n||i.slice(0,n.length+1)===n+"-"))}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,f,p,d,h,g=o!==a?"nextSibling":"previousSibling",y=t.parentNode,v=s&&t.nodeName.toLowerCase(),m=!u&&!s,x=!1;if(y){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===v:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?y.firstChild:y.lastChild],a&&m){x=(d=(l=(c=(f=(p=y)[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]||[])[0]===T&&l[1])&&l[2],p=d&&y.childNodes[d];while(p=++d&&p&&p[g]||(x=d=0)||h.pop())if(1===p.nodeType&&++x&&p===t){c[e]=[T,d,x];break}}else if(m&&(x=d=(l=(c=(f=(p=t)[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]||[])[0]===T&&l[1]),!1===x)while(p=++d&&p&&p[g]||(x=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===v:1===p.nodeType)&&++x&&(m&&((c=(f=p[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]=[T,x]),p===t))break;return(x-=i)===r||x%r==0&&x/r>=0}}},PSEUDO:function(e,t){var n,i=r.pseudos[e]||r.setFilters[e.toLowerCase()]||oe.error("unsupported pseudo: "+e);return i[b]?i(t):i.length>1?(n=[e,e,"",t],r.setFilters.hasOwnProperty(e.toLowerCase())?se(function(e,n){var r,o=i(e,t),a=o.length;while(a--)e[r=O(e,o[a])]=!(n[r]=o[a])}):function(e){return i(e,0,n)}):i}},pseudos:{not:se(function(e){var t=[],n=[],r=s(e.replace(B,"$1"));return r[b]?se(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),t[0]=null,!n.pop()}}),has:se(function(e){return function(t){return oe(e,t).length>0}}),contains:se(function(e){return e=e.replace(Z,ee),function(t){return(t.textContent||t.innerText||i(t)).indexOf(e)>-1}}),lang:se(function(e){return U.test(e||"")||oe.error("unsupported lang: "+e),e=e.replace(Z,ee).toLowerCase(),function(t){var n;do{if(n=g?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return(n=n.toLowerCase())===e||0===n.indexOf(e+"-")}while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===h},focus:function(e){return e===d.activeElement&&(!d.hasFocus||d.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:de(!1),disabled:de(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!r.pseudos.empty(e)},header:function(e){return Y.test(e.nodeName)},input:function(e){return G.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:he(function(){return[0]}),last:he(function(e,t){return[t-1]}),eq:he(function(e,t,n){return[n<0?n+t:n]}),even:he(function(e,t){for(var n=0;n=0;)e.push(r);return e}),gt:he(function(e,t,n){for(var r=n<0?n+t:n;++r1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function be(e,t,n){for(var r=0,i=t.length;r-1&&(o[l]=!(a[l]=f))}}else v=we(v===a?v.splice(h,v.length):v),i?i(null,a,v,u):L.apply(a,v)})}function Ce(e){for(var t,n,i,o=e.length,a=r.relative[e[0].type],s=a||r.relative[" "],u=a?1:0,c=me(function(e){return e===t},s,!0),f=me(function(e){return O(t,e)>-1},s,!0),p=[function(e,n,r){var i=!a&&(r||n!==l)||((t=n).nodeType?c(e,n,r):f(e,n,r));return t=null,i}];u1&&xe(p),u>1&&ve(e.slice(0,u-1).concat({value:" "===e[u-2].type?"*":""})).replace(B,"$1"),n,u0,i=e.length>0,o=function(o,a,s,u,c){var f,h,y,v=0,m="0",x=o&&[],b=[],w=l,C=o||i&&r.find.TAG("*",c),E=T+=null==w?1:Math.random()||.1,k=C.length;for(c&&(l=a===d||a||c);m!==k&&null!=(f=C[m]);m++){if(i&&f){h=0,a||f.ownerDocument===d||(p(f),s=!g);while(y=e[h++])if(y(f,a||d,s)){u.push(f);break}c&&(T=E)}n&&((f=!y&&f)&&v--,o&&x.push(f))}if(v+=m,n&&m!==v){h=0;while(y=t[h++])y(x,b,a,s);if(o){if(v>0)while(m--)x[m]||b[m]||(b[m]=j.call(u));b=we(b)}L.apply(u,b),c&&!o&&b.length>0&&v+t.length>1&&oe.uniqueSort(u)}return c&&(T=E,l=w),x};return n?se(o):o}return s=oe.compile=function(e,t){var n,r=[],i=[],o=S[e+" "];if(!o){t||(t=a(e)),n=t.length;while(n--)(o=Ce(t[n]))[b]?r.push(o):i.push(o);(o=S(e,Ee(i,r))).selector=e}return o},u=oe.select=function(e,t,n,i){var o,u,l,c,f,p="function"==typeof e&&e,d=!i&&a(e=p.selector||e);if(n=n||[],1===d.length){if((u=d[0]=d[0].slice(0)).length>2&&"ID"===(l=u[0]).type&&9===t.nodeType&&g&&r.relative[u[1].type]){if(!(t=(r.find.ID(l.matches[0].replace(Z,ee),t)||[])[0]))return n;p&&(t=t.parentNode),e=e.slice(u.shift().value.length)}o=V.needsContext.test(e)?0:u.length;while(o--){if(l=u[o],r.relative[c=l.type])break;if((f=r.find[c])&&(i=f(l.matches[0].replace(Z,ee),K.test(u[0].type)&&ge(t.parentNode)||t))){if(u.splice(o,1),!(e=i.length&&ve(u)))return L.apply(n,i),n;break}}}return(p||s(e,d))(i,t,!g,n,!t||K.test(e)&&ge(t.parentNode)||t),n},n.sortStable=b.split("").sort(D).join("")===b,n.detectDuplicates=!!f,p(),n.sortDetached=ue(function(e){return 1&e.compareDocumentPosition(d.createElement("fieldset"))}),ue(function(e){return e.innerHTML="","#"===e.firstChild.getAttribute("href")})||le("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),n.attributes&&ue(function(e){return e.innerHTML="",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||le("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),ue(function(e){return null==e.getAttribute("disabled")})||le(P,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),oe}(e);w.find=E,w.expr=E.selectors,w.expr[":"]=w.expr.pseudos,w.uniqueSort=w.unique=E.uniqueSort,w.text=E.getText,w.isXMLDoc=E.isXML,w.contains=E.contains,w.escapeSelector=E.escape;var k=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&w(e).is(n))break;r.push(e)}return r},S=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},D=w.expr.match.needsContext;function N(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var A=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,t,n){return g(t)?w.grep(e,function(e,r){return!!t.call(e,r,e)!==n}):t.nodeType?w.grep(e,function(e){return e===t!==n}):"string"!=typeof t?w.grep(e,function(e){return u.call(t,e)>-1!==n}):w.filter(t,e,n)}w.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?w.find.matchesSelector(r,e)?[r]:[]:w.find.matches(e,w.grep(t,function(e){return 1===e.nodeType}))},w.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(w(e).filter(function(){for(t=0;t1?w.uniqueSort(n):n},filter:function(e){return this.pushStack(j(this,e||[],!1))},not:function(e){return this.pushStack(j(this,e||[],!0))},is:function(e){return!!j(this,"string"==typeof e&&D.test(e)?w(e):e||[],!1).length}});var q,L=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(w.fn.init=function(e,t,n){var i,o;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(i="<"===e[0]&&">"===e[e.length-1]&&e.length>=3?[null,e,null]:L.exec(e))||!i[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(i[1]){if(t=t instanceof w?t[0]:t,w.merge(this,w.parseHTML(i[1],t&&t.nodeType?t.ownerDocument||t:r,!0)),A.test(i[1])&&w.isPlainObject(t))for(i in t)g(this[i])?this[i](t[i]):this.attr(i,t[i]);return this}return(o=r.getElementById(i[2]))&&(this[0]=o,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):g(e)?void 0!==n.ready?n.ready(e):e(w):w.makeArray(e,this)}).prototype=w.fn,q=w(r);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};w.fn.extend({has:function(e){var t=w(e,this),n=t.length;return this.filter(function(){for(var e=0;e-1:1===n.nodeType&&w.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(o.length>1?w.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?u.call(w(e),this[0]):u.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(w.uniqueSort(w.merge(this.get(),w(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}});function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}w.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return k(e,"parentNode")},parentsUntil:function(e,t,n){return k(e,"parentNode",n)},next:function(e){return P(e,"nextSibling")},prev:function(e){return P(e,"previousSibling")},nextAll:function(e){return k(e,"nextSibling")},prevAll:function(e){return k(e,"previousSibling")},nextUntil:function(e,t,n){return k(e,"nextSibling",n)},prevUntil:function(e,t,n){return k(e,"previousSibling",n)},siblings:function(e){return S((e.parentNode||{}).firstChild,e)},children:function(e){return S(e.firstChild)},contents:function(e){return N(e,"iframe")?e.contentDocument:(N(e,"template")&&(e=e.content||e),w.merge([],e.childNodes))}},function(e,t){w.fn[e]=function(n,r){var i=w.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=w.filter(r,i)),this.length>1&&(O[e]||w.uniqueSort(i),H.test(e)&&i.reverse()),this.pushStack(i)}});var M=/[^\x20\t\r\n\f]+/g;function R(e){var t={};return w.each(e.match(M)||[],function(e,n){t[n]=!0}),t}w.Callbacks=function(e){e="string"==typeof e?R(e):w.extend({},e);var t,n,r,i,o=[],a=[],s=-1,u=function(){for(i=i||e.once,r=t=!0;a.length;s=-1){n=a.shift();while(++s-1)o.splice(n,1),n<=s&&s--}),this},has:function(e){return e?w.inArray(e,o)>-1:o.length>0},empty:function(){return o&&(o=[]),this},disable:function(){return i=a=[],o=n="",this},disabled:function(){return!o},lock:function(){return i=a=[],n||t||(o=n=""),this},locked:function(){return!!i},fireWith:function(e,n){return i||(n=[e,(n=n||[]).slice?n.slice():n],a.push(n),t||u()),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!r}};return l};function I(e){return e}function W(e){throw e}function $(e,t,n,r){var i;try{e&&g(i=e.promise)?i.call(e).done(t).fail(n):e&&g(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}w.extend({Deferred:function(t){var n=[["notify","progress",w.Callbacks("memory"),w.Callbacks("memory"),2],["resolve","done",w.Callbacks("once memory"),w.Callbacks("once memory"),0,"resolved"],["reject","fail",w.Callbacks("once memory"),w.Callbacks("once memory"),1,"rejected"]],r="pending",i={state:function(){return r},always:function(){return o.done(arguments).fail(arguments),this},"catch":function(e){return i.then(null,e)},pipe:function(){var e=arguments;return w.Deferred(function(t){w.each(n,function(n,r){var i=g(e[r[4]])&&e[r[4]];o[r[1]](function(){var e=i&&i.apply(this,arguments);e&&g(e.promise)?e.promise().progress(t.notify).done(t.resolve).fail(t.reject):t[r[0]+"With"](this,i?[e]:arguments)})}),e=null}).promise()},then:function(t,r,i){var o=0;function a(t,n,r,i){return function(){var s=this,u=arguments,l=function(){var e,l;if(!(t=o&&(r!==W&&(s=void 0,u=[e]),n.rejectWith(s,u))}};t?c():(w.Deferred.getStackHook&&(c.stackTrace=w.Deferred.getStackHook()),e.setTimeout(c))}}return w.Deferred(function(e){n[0][3].add(a(0,e,g(i)?i:I,e.notifyWith)),n[1][3].add(a(0,e,g(t)?t:I)),n[2][3].add(a(0,e,g(r)?r:W))}).promise()},promise:function(e){return null!=e?w.extend(e,i):i}},o={};return w.each(n,function(e,t){var a=t[2],s=t[5];i[t[1]]=a.add,s&&a.add(function(){r=s},n[3-e][2].disable,n[3-e][3].disable,n[0][2].lock,n[0][3].lock),a.add(t[3].fire),o[t[0]]=function(){return o[t[0]+"With"](this===o?void 0:this,arguments),this},o[t[0]+"With"]=a.fireWith}),i.promise(o),t&&t.call(o,o),o},when:function(e){var t=arguments.length,n=t,r=Array(n),i=o.call(arguments),a=w.Deferred(),s=function(e){return function(n){r[e]=this,i[e]=arguments.length>1?o.call(arguments):n,--t||a.resolveWith(r,i)}};if(t<=1&&($(e,a.done(s(n)).resolve,a.reject,!t),"pending"===a.state()||g(i[n]&&i[n].then)))return a.then();while(n--)$(i[n],s(n),a.reject);return a.promise()}});var B=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;w.Deferred.exceptionHook=function(t,n){e.console&&e.console.warn&&t&&B.test(t.name)&&e.console.warn("jQuery.Deferred exception: "+t.message,t.stack,n)},w.readyException=function(t){e.setTimeout(function(){throw t})};var F=w.Deferred();w.fn.ready=function(e){return F.then(e)["catch"](function(e){w.readyException(e)}),this},w.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--w.readyWait:w.isReady)||(w.isReady=!0,!0!==e&&--w.readyWait>0||F.resolveWith(r,[w]))}}),w.ready.then=F.then;function _(){r.removeEventListener("DOMContentLoaded",_),e.removeEventListener("load",_),w.ready()}"complete"===r.readyState||"loading"!==r.readyState&&!r.documentElement.doScroll?e.setTimeout(w.ready):(r.addEventListener("DOMContentLoaded",_),e.addEventListener("load",_));var z=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===x(n)){i=!0;for(s in n)z(e,t,s,n[s],!0,o,a)}else if(void 0!==r&&(i=!0,g(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(w(e),n)})),t))for(;s1,null,!0)},removeData:function(e){return this.each(function(){K.remove(this,e)})}}),w.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=J.get(e,t),n&&(!r||Array.isArray(n)?r=J.access(e,t,w.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=w.queue(e,t),r=n.length,i=n.shift(),o=w._queueHooks(e,t),a=function(){w.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return J.get(e,n)||J.access(e,n,{empty:w.Callbacks("once memory").add(function(){J.remove(e,[t+"queue",n])})})}}),w.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),arguments.length\x20\t\r\n\f]+)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ge.optgroup=ge.option,ge.tbody=ge.tfoot=ge.colgroup=ge.caption=ge.thead,ge.th=ge.td;function ye(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&N(e,t)?w.merge([e],n):n}function ve(e,t){for(var n=0,r=e.length;n-1)i&&i.push(o);else if(l=w.contains(o.ownerDocument,o),a=ye(f.appendChild(o),"script"),l&&ve(a),n){c=0;while(o=a[c++])he.test(o.type||"")&&n.push(o)}return f}!function(){var e=r.createDocumentFragment().appendChild(r.createElement("div")),t=r.createElement("input");t.setAttribute("type","radio"),t.setAttribute("checked","checked"),t.setAttribute("name","t"),e.appendChild(t),h.checkClone=e.cloneNode(!0).cloneNode(!0).lastChild.checked,e.innerHTML="",h.noCloneChecked=!!e.cloneNode(!0).lastChild.defaultValue}();var be=r.documentElement,we=/^key/,Te=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ce=/^([^.]*)(?:\.(.+)|)/;function Ee(){return!0}function ke(){return!1}function Se(){try{return r.activeElement}catch(e){}}function De(e,t,n,r,i,o){var a,s;if("object"==typeof t){"string"!=typeof n&&(r=r||n,n=void 0);for(s in t)De(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=ke;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return w().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=w.guid++)),e.each(function(){w.event.add(this,t,i,r,n)})}w.event={global:{},add:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,y=J.get(e);if(y){n.handler&&(n=(o=n).handler,i=o.selector),i&&w.find.matchesSelector(be,i),n.guid||(n.guid=w.guid++),(u=y.events)||(u=y.events={}),(a=y.handle)||(a=y.handle=function(t){return"undefined"!=typeof w&&w.event.triggered!==t.type?w.event.dispatch.apply(e,arguments):void 0}),l=(t=(t||"").match(M)||[""]).length;while(l--)d=g=(s=Ce.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=w.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=w.event.special[d]||{},c=w.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&w.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(e,r,h,a)||e.addEventListener&&e.addEventListener(d,a)),f.add&&(f.add.call(e,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),w.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,y=J.hasData(e)&&J.get(e);if(y&&(u=y.events)){l=(t=(t||"").match(M)||[""]).length;while(l--)if(s=Ce.exec(t[l])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){f=w.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,y.handle)||w.removeEvent(e,d,y.handle),delete u[d])}else for(d in u)w.event.remove(e,d+t[l],n,r,!0);w.isEmptyObject(u)&&J.remove(e,"handle events")}},dispatch:function(e){var t=w.event.fix(e),n,r,i,o,a,s,u=new Array(arguments.length),l=(J.get(this,"events")||{})[t.type]||[],c=w.event.special[t.type]||{};for(u[0]=t,n=1;n=1))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n-1:w.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u\x20\t\r\n\f]*)[^>]*)\/>/gi,Ae=/\s*$/g;function Le(e,t){return N(e,"table")&&N(11!==t.nodeType?t:t.firstChild,"tr")?w(e).children("tbody")[0]||e:e}function He(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Oe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Pe(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(J.hasData(e)&&(o=J.access(e),a=J.set(t,o),l=o.events)){delete a.handle,a.events={};for(i in l)for(n=0,r=l[i].length;n1&&"string"==typeof y&&!h.checkClone&&je.test(y))return e.each(function(i){var o=e.eq(i);v&&(t[0]=y.call(this,i,o.html())),Re(o,t,n,r)});if(p&&(i=xe(t,e[0].ownerDocument,!1,e,r),o=i.firstChild,1===i.childNodes.length&&(i=o),o||r)){for(u=(s=w.map(ye(i,"script"),He)).length;f")},clone:function(e,t,n){var r,i,o,a,s=e.cloneNode(!0),u=w.contains(e.ownerDocument,e);if(!(h.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||w.isXMLDoc(e)))for(a=ye(s),r=0,i=(o=ye(e)).length;r0&&ve(a,!u&&ye(e,"script")),s},cleanData:function(e){for(var t,n,r,i=w.event.special,o=0;void 0!==(n=e[o]);o++)if(Y(n)){if(t=n[J.expando]){if(t.events)for(r in t.events)i[r]?w.event.remove(n,r):w.removeEvent(n,r,t.handle);n[J.expando]=void 0}n[K.expando]&&(n[K.expando]=void 0)}}}),w.fn.extend({detach:function(e){return Ie(this,e,!0)},remove:function(e){return Ie(this,e)},text:function(e){return z(this,function(e){return void 0===e?w.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return Re(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||Le(this,e).appendChild(e)})},prepend:function(){return Re(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Le(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return Re(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return Re(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(w.cleanData(ye(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return w.clone(this,e,t)})},html:function(e){return z(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!Ae.test(e)&&!ge[(de.exec(e)||["",""])[1].toLowerCase()]){e=w.htmlPrefilter(e);try{for(;n=0&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))),u}function et(e,t,n){var r=$e(e),i=Fe(e,t,r),o="border-box"===w.css(e,"boxSizing",!1,r),a=o;if(We.test(i)){if(!n)return i;i="auto"}return a=a&&(h.boxSizingReliable()||i===e.style[t]),("auto"===i||!parseFloat(i)&&"inline"===w.css(e,"display",!1,r))&&(i=e["offset"+t[0].toUpperCase()+t.slice(1)],a=!0),(i=parseFloat(i)||0)+Ze(e,t,n||(o?"border":"content"),a,r,i)+"px"}w.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Fe(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=G(t),u=Xe.test(t),l=e.style;if(u||(t=Je(s)),a=w.cssHooks[t]||w.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];"string"==(o=typeof n)&&(i=ie.exec(n))&&i[1]&&(n=ue(e,t,i),o="number"),null!=n&&n===n&&("number"===o&&(n+=i&&i[3]||(w.cssNumber[s]?"":"px")),h.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=G(t);return Xe.test(t)||(t=Je(s)),(a=w.cssHooks[t]||w.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=Fe(e,t,r)),"normal"===i&&t in Ve&&(i=Ve[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),w.each(["height","width"],function(e,t){w.cssHooks[t]={get:function(e,n,r){if(n)return!ze.test(w.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?et(e,t,r):se(e,Ue,function(){return et(e,t,r)})},set:function(e,n,r){var i,o=$e(e),a="border-box"===w.css(e,"boxSizing",!1,o),s=r&&Ze(e,t,r,a,o);return a&&h.scrollboxSize()===o.position&&(s-=Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-parseFloat(o[t])-Ze(e,t,"border",!1,o)-.5)),s&&(i=ie.exec(n))&&"px"!==(i[3]||"px")&&(e.style[t]=n,n=w.css(e,t)),Ke(e,n,s)}}}),w.cssHooks.marginLeft=_e(h.reliableMarginLeft,function(e,t){if(t)return(parseFloat(Fe(e,"marginLeft"))||e.getBoundingClientRect().left-se(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),w.each({margin:"",padding:"",border:"Width"},function(e,t){w.cssHooks[e+t]={expand:function(n){for(var r=0,i={},o="string"==typeof n?n.split(" "):[n];r<4;r++)i[e+oe[r]+t]=o[r]||o[r-2]||o[0];return i}},"margin"!==e&&(w.cssHooks[e+t].set=Ke)}),w.fn.extend({css:function(e,t){return z(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=$e(e),i=t.length;a1)}});function tt(e,t,n,r,i){return new tt.prototype.init(e,t,n,r,i)}w.Tween=tt,tt.prototype={constructor:tt,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||w.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(w.cssNumber[n]?"":"px")},cur:function(){var e=tt.propHooks[this.prop];return e&&e.get?e.get(this):tt.propHooks._default.get(this)},run:function(e){var t,n=tt.propHooks[this.prop];return this.options.duration?this.pos=t=w.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):tt.propHooks._default.set(this),this}},tt.prototype.init.prototype=tt.prototype,tt.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=w.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){w.fx.step[e.prop]?w.fx.step[e.prop](e):1!==e.elem.nodeType||null==e.elem.style[w.cssProps[e.prop]]&&!w.cssHooks[e.prop]?e.elem[e.prop]=e.now:w.style(e.elem,e.prop,e.now+e.unit)}}},tt.propHooks.scrollTop=tt.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},w.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},w.fx=tt.prototype.init,w.fx.step={};var nt,rt,it=/^(?:toggle|show|hide)$/,ot=/queueHooks$/;function at(){rt&&(!1===r.hidden&&e.requestAnimationFrame?e.requestAnimationFrame(at):e.setTimeout(at,w.fx.interval),w.fx.tick())}function st(){return e.setTimeout(function(){nt=void 0}),nt=Date.now()}function ut(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=oe[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function lt(e,t,n){for(var r,i=(pt.tweeners[t]||[]).concat(pt.tweeners["*"]),o=0,a=i.length;o1)},removeAttr:function(e){return this.each(function(){w.removeAttr(this,e)})}}),w.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?w.prop(e,t,n):(1===o&&w.isXMLDoc(e)||(i=w.attrHooks[t.toLowerCase()]||(w.expr.match.bool.test(t)?dt:void 0)),void 0!==n?null===n?void w.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=w.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!h.radioValue&&"radio"===t&&N(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(M);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),dt={set:function(e,t,n){return!1===t?w.removeAttr(e,n):e.setAttribute(n,n),n}},w.each(w.expr.match.bool.source.match(/\w+/g),function(e,t){var n=ht[t]||w.find.attr;ht[t]=function(e,t,r){var i,o,a=t.toLowerCase();return r||(o=ht[a],ht[a]=i,i=null!=n(e,t,r)?a:null,ht[a]=o),i}});var gt=/^(?:input|select|textarea|button)$/i,yt=/^(?:a|area)$/i;w.fn.extend({prop:function(e,t){return z(this,w.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[w.propFix[e]||e]})}}),w.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&w.isXMLDoc(e)||(t=w.propFix[t]||t,i=w.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=w.find.attr(e,"tabindex");return t?parseInt(t,10):gt.test(e.nodeName)||yt.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),h.optSelected||(w.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),w.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){w.propFix[this.toLowerCase()]=this});function vt(e){return(e.match(M)||[]).join(" ")}function mt(e){return e.getAttribute&&e.getAttribute("class")||""}function xt(e){return Array.isArray(e)?e:"string"==typeof e?e.match(M)||[]:[]}w.fn.extend({addClass:function(e){var t,n,r,i,o,a,s,u=0;if(g(e))return this.each(function(t){w(this).addClass(e.call(this,t,mt(this)))});if((t=xt(e)).length)while(n=this[u++])if(i=mt(n),r=1===n.nodeType&&" "+vt(i)+" "){a=0;while(o=t[a++])r.indexOf(" "+o+" ")<0&&(r+=o+" ");i!==(s=vt(r))&&n.setAttribute("class",s)}return this},removeClass:function(e){var t,n,r,i,o,a,s,u=0;if(g(e))return this.each(function(t){w(this).removeClass(e.call(this,t,mt(this)))});if(!arguments.length)return this.attr("class","");if((t=xt(e)).length)while(n=this[u++])if(i=mt(n),r=1===n.nodeType&&" "+vt(i)+" "){a=0;while(o=t[a++])while(r.indexOf(" "+o+" ")>-1)r=r.replace(" "+o+" "," ");i!==(s=vt(r))&&n.setAttribute("class",s)}return this},toggleClass:function(e,t){var n=typeof e,r="string"===n||Array.isArray(e);return"boolean"==typeof t&&r?t?this.addClass(e):this.removeClass(e):g(e)?this.each(function(n){w(this).toggleClass(e.call(this,n,mt(this),t),t)}):this.each(function(){var t,i,o,a;if(r){i=0,o=w(this),a=xt(e);while(t=a[i++])o.hasClass(t)?o.removeClass(t):o.addClass(t)}else void 0!==e&&"boolean"!==n||((t=mt(this))&&J.set(this,"__className__",t),this.setAttribute&&this.setAttribute("class",t||!1===e?"":J.get(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;t=" "+e+" ";while(n=this[r++])if(1===n.nodeType&&(" "+vt(mt(n))+" ").indexOf(t)>-1)return!0;return!1}});var bt=/\r/g;w.fn.extend({val:function(e){var t,n,r,i=this[0];{if(arguments.length)return r=g(e),this.each(function(n){var i;1===this.nodeType&&(null==(i=r?e.call(this,n,w(this).val()):e)?i="":"number"==typeof i?i+="":Array.isArray(i)&&(i=w.map(i,function(e){return null==e?"":e+""})),(t=w.valHooks[this.type]||w.valHooks[this.nodeName.toLowerCase()])&&"set"in t&&void 0!==t.set(this,i,"value")||(this.value=i))});if(i)return(t=w.valHooks[i.type]||w.valHooks[i.nodeName.toLowerCase()])&&"get"in t&&void 0!==(n=t.get(i,"value"))?n:"string"==typeof(n=i.value)?n.replace(bt,""):null==n?"":n}}}),w.extend({valHooks:{option:{get:function(e){var t=w.find.attr(e,"value");return null!=t?t:vt(w.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r-1)&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),w.each(["radio","checkbox"],function(){w.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=w.inArray(w(e).val(),t)>-1}},h.checkOn||(w.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),h.focusin="onfocusin"in e;var wt=/^(?:focusinfocus|focusoutblur)$/,Tt=function(e){e.stopPropagation()};w.extend(w.event,{trigger:function(t,n,i,o){var a,s,u,l,c,p,d,h,v=[i||r],m=f.call(t,"type")?t.type:t,x=f.call(t,"namespace")?t.namespace.split("."):[];if(s=h=u=i=i||r,3!==i.nodeType&&8!==i.nodeType&&!wt.test(m+w.event.triggered)&&(m.indexOf(".")>-1&&(m=(x=m.split(".")).shift(),x.sort()),c=m.indexOf(":")<0&&"on"+m,t=t[w.expando]?t:new w.Event(m,"object"==typeof t&&t),t.isTrigger=o?2:3,t.namespace=x.join("."),t.rnamespace=t.namespace?new RegExp("(^|\\.)"+x.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=void 0,t.target||(t.target=i),n=null==n?[t]:w.makeArray(n,[t]),d=w.event.special[m]||{},o||!d.trigger||!1!==d.trigger.apply(i,n))){if(!o&&!d.noBubble&&!y(i)){for(l=d.delegateType||m,wt.test(l+m)||(s=s.parentNode);s;s=s.parentNode)v.push(s),u=s;u===(i.ownerDocument||r)&&v.push(u.defaultView||u.parentWindow||e)}a=0;while((s=v[a++])&&!t.isPropagationStopped())h=s,t.type=a>1?l:d.bindType||m,(p=(J.get(s,"events")||{})[t.type]&&J.get(s,"handle"))&&p.apply(s,n),(p=c&&s[c])&&p.apply&&Y(s)&&(t.result=p.apply(s,n),!1===t.result&&t.preventDefault());return t.type=m,o||t.isDefaultPrevented()||d._default&&!1!==d._default.apply(v.pop(),n)||!Y(i)||c&&g(i[m])&&!y(i)&&((u=i[c])&&(i[c]=null),w.event.triggered=m,t.isPropagationStopped()&&h.addEventListener(m,Tt),i[m](),t.isPropagationStopped()&&h.removeEventListener(m,Tt),w.event.triggered=void 0,u&&(i[c]=u)),t.result}},simulate:function(e,t,n){var r=w.extend(new w.Event,n,{type:e,isSimulated:!0});w.event.trigger(r,null,t)}}),w.fn.extend({trigger:function(e,t){return this.each(function(){w.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return w.event.trigger(e,t,n,!0)}}),h.focusin||w.each({focus:"focusin",blur:"focusout"},function(e,t){var n=function(e){w.event.simulate(t,e.target,w.event.fix(e))};w.event.special[t]={setup:function(){var r=this.ownerDocument||this,i=J.access(r,t);i||r.addEventListener(e,n,!0),J.access(r,t,(i||0)+1)},teardown:function(){var r=this.ownerDocument||this,i=J.access(r,t)-1;i?J.access(r,t,i):(r.removeEventListener(e,n,!0),J.remove(r,t))}}});var Ct=e.location,Et=Date.now(),kt=/\?/;w.parseXML=function(t){var n;if(!t||"string"!=typeof t)return null;try{n=(new e.DOMParser).parseFromString(t,"text/xml")}catch(e){n=void 0}return n&&!n.getElementsByTagName("parsererror").length||w.error("Invalid XML: "+t),n};var St=/\[\]$/,Dt=/\r?\n/g,Nt=/^(?:submit|button|image|reset|file)$/i,At=/^(?:input|select|textarea|keygen)/i;function jt(e,t,n,r){var i;if(Array.isArray(t))w.each(t,function(t,i){n||St.test(e)?r(e,i):jt(e+"["+("object"==typeof i&&null!=i?t:"")+"]",i,n,r)});else if(n||"object"!==x(t))r(e,t);else for(i in t)jt(e+"["+i+"]",t[i],n,r)}w.param=function(e,t){var n,r=[],i=function(e,t){var n=g(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(Array.isArray(e)||e.jquery&&!w.isPlainObject(e))w.each(e,function(){i(this.name,this.value)});else for(n in e)jt(n,e[n],t,i);return r.join("&")},w.fn.extend({serialize:function(){return w.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=w.prop(this,"elements");return e?w.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!w(this).is(":disabled")&&At.test(this.nodeName)&&!Nt.test(e)&&(this.checked||!pe.test(e))}).map(function(e,t){var n=w(this).val();return null==n?null:Array.isArray(n)?w.map(n,function(e){return{name:t.name,value:e.replace(Dt,"\r\n")}}):{name:t.name,value:n.replace(Dt,"\r\n")}}).get()}});var qt=/%20/g,Lt=/#.*$/,Ht=/([?&])_=[^&]*/,Ot=/^(.*?):[ \t]*([^\r\n]*)$/gm,Pt=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Mt=/^(?:GET|HEAD)$/,Rt=/^\/\//,It={},Wt={},$t="*/".concat("*"),Bt=r.createElement("a");Bt.href=Ct.href;function Ft(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(M)||[];if(g(n))while(r=o[i++])"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function _t(e,t,n,r){var i={},o=e===Wt;function a(s){var u;return i[s]=!0,w.each(e[s]||[],function(e,s){var l=s(t,n,r);return"string"!=typeof l||o||i[l]?o?!(u=l):void 0:(t.dataTypes.unshift(l),a(l),!1)}),u}return a(t.dataTypes[0])||!i["*"]&&a("*")}function zt(e,t){var n,r,i=w.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&w.extend(!0,e,r),e}function Xt(e,t,n){var r,i,o,a,s=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}function Ut(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(!(a=l[u+" "+o]||l["* "+o]))for(i in l)if((s=i.split(" "))[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}w.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Ct.href,type:"GET",isLocal:Pt.test(Ct.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":$t,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":w.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?zt(zt(e,w.ajaxSettings),t):zt(w.ajaxSettings,e)},ajaxPrefilter:Ft(It),ajaxTransport:Ft(Wt),ajax:function(t,n){"object"==typeof t&&(n=t,t=void 0),n=n||{};var i,o,a,s,u,l,c,f,p,d,h=w.ajaxSetup({},n),g=h.context||h,y=h.context&&(g.nodeType||g.jquery)?w(g):w.event,v=w.Deferred(),m=w.Callbacks("once memory"),x=h.statusCode||{},b={},T={},C="canceled",E={readyState:0,getResponseHeader:function(e){var t;if(c){if(!s){s={};while(t=Ot.exec(a))s[t[1].toLowerCase()]=t[2]}t=s[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return c?a:null},setRequestHeader:function(e,t){return null==c&&(e=T[e.toLowerCase()]=T[e.toLowerCase()]||e,b[e]=t),this},overrideMimeType:function(e){return null==c&&(h.mimeType=e),this},statusCode:function(e){var t;if(e)if(c)E.always(e[E.status]);else for(t in e)x[t]=[x[t],e[t]];return this},abort:function(e){var t=e||C;return i&&i.abort(t),k(0,t),this}};if(v.promise(E),h.url=((t||h.url||Ct.href)+"").replace(Rt,Ct.protocol+"//"),h.type=n.method||n.type||h.method||h.type,h.dataTypes=(h.dataType||"*").toLowerCase().match(M)||[""],null==h.crossDomain){l=r.createElement("a");try{l.href=h.url,l.href=l.href,h.crossDomain=Bt.protocol+"//"+Bt.host!=l.protocol+"//"+l.host}catch(e){h.crossDomain=!0}}if(h.data&&h.processData&&"string"!=typeof h.data&&(h.data=w.param(h.data,h.traditional)),_t(It,h,n,E),c)return E;(f=w.event&&h.global)&&0==w.active++&&w.event.trigger("ajaxStart"),h.type=h.type.toUpperCase(),h.hasContent=!Mt.test(h.type),o=h.url.replace(Lt,""),h.hasContent?h.data&&h.processData&&0===(h.contentType||"").indexOf("application/x-www-form-urlencoded")&&(h.data=h.data.replace(qt,"+")):(d=h.url.slice(o.length),h.data&&(h.processData||"string"==typeof h.data)&&(o+=(kt.test(o)?"&":"?")+h.data,delete h.data),!1===h.cache&&(o=o.replace(Ht,"$1"),d=(kt.test(o)?"&":"?")+"_="+Et+++d),h.url=o+d),h.ifModified&&(w.lastModified[o]&&E.setRequestHeader("If-Modified-Since",w.lastModified[o]),w.etag[o]&&E.setRequestHeader("If-None-Match",w.etag[o])),(h.data&&h.hasContent&&!1!==h.contentType||n.contentType)&&E.setRequestHeader("Content-Type",h.contentType),E.setRequestHeader("Accept",h.dataTypes[0]&&h.accepts[h.dataTypes[0]]?h.accepts[h.dataTypes[0]]+("*"!==h.dataTypes[0]?", "+$t+"; q=0.01":""):h.accepts["*"]);for(p in h.headers)E.setRequestHeader(p,h.headers[p]);if(h.beforeSend&&(!1===h.beforeSend.call(g,E,h)||c))return E.abort();if(C="abort",m.add(h.complete),E.done(h.success),E.fail(h.error),i=_t(Wt,h,n,E)){if(E.readyState=1,f&&y.trigger("ajaxSend",[E,h]),c)return E;h.async&&h.timeout>0&&(u=e.setTimeout(function(){E.abort("timeout")},h.timeout));try{c=!1,i.send(b,k)}catch(e){if(c)throw e;k(-1,e)}}else k(-1,"No Transport");function k(t,n,r,s){var l,p,d,b,T,C=n;c||(c=!0,u&&e.clearTimeout(u),i=void 0,a=s||"",E.readyState=t>0?4:0,l=t>=200&&t<300||304===t,r&&(b=Xt(h,E,r)),b=Ut(h,b,E,l),l?(h.ifModified&&((T=E.getResponseHeader("Last-Modified"))&&(w.lastModified[o]=T),(T=E.getResponseHeader("etag"))&&(w.etag[o]=T)),204===t||"HEAD"===h.type?C="nocontent":304===t?C="notmodified":(C=b.state,p=b.data,l=!(d=b.error))):(d=C,!t&&C||(C="error",t<0&&(t=0))),E.status=t,E.statusText=(n||C)+"",l?v.resolveWith(g,[p,C,E]):v.rejectWith(g,[E,C,d]),E.statusCode(x),x=void 0,f&&y.trigger(l?"ajaxSuccess":"ajaxError",[E,h,l?p:d]),m.fireWith(g,[E,C]),f&&(y.trigger("ajaxComplete",[E,h]),--w.active||w.event.trigger("ajaxStop")))}return E},getJSON:function(e,t,n){return w.get(e,t,n,"json")},getScript:function(e,t){return w.get(e,void 0,t,"script")}}),w.each(["get","post"],function(e,t){w[t]=function(e,n,r,i){return g(n)&&(i=i||r,r=n,n=void 0),w.ajax(w.extend({url:e,type:t,dataType:i,data:n,success:r},w.isPlainObject(e)&&e))}}),w._evalUrl=function(e){return w.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},w.fn.extend({wrapAll:function(e){var t;return this[0]&&(g(e)&&(e=e.call(this[0])),t=w(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(e){return g(e)?this.each(function(t){w(this).wrapInner(e.call(this,t))}):this.each(function(){var t=w(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=g(e);return this.each(function(n){w(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(e){return this.parent(e).not("body").each(function(){w(this).replaceWith(this.childNodes)}),this}}),w.expr.pseudos.hidden=function(e){return!w.expr.pseudos.visible(e)},w.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},w.ajaxSettings.xhr=function(){try{return new e.XMLHttpRequest}catch(e){}};var Vt={0:200,1223:204},Gt=w.ajaxSettings.xhr();h.cors=!!Gt&&"withCredentials"in Gt,h.ajax=Gt=!!Gt,w.ajaxTransport(function(t){var n,r;if(h.cors||Gt&&!t.crossDomain)return{send:function(i,o){var a,s=t.xhr();if(s.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(a in t.xhrFields)s[a]=t.xhrFields[a];t.mimeType&&s.overrideMimeType&&s.overrideMimeType(t.mimeType),t.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");for(a in i)s.setRequestHeader(a,i[a]);n=function(e){return function(){n&&(n=r=s.onload=s.onerror=s.onabort=s.ontimeout=s.onreadystatechange=null,"abort"===e?s.abort():"error"===e?"number"!=typeof s.status?o(0,"error"):o(s.status,s.statusText):o(Vt[s.status]||s.status,s.statusText,"text"!==(s.responseType||"text")||"string"!=typeof s.responseText?{binary:s.response}:{text:s.responseText},s.getAllResponseHeaders()))}},s.onload=n(),r=s.onerror=s.ontimeout=n("error"),void 0!==s.onabort?s.onabort=r:s.onreadystatechange=function(){4===s.readyState&&e.setTimeout(function(){n&&r()})},n=n("abort");try{s.send(t.hasContent&&t.data||null)}catch(e){if(n)throw e}},abort:function(){n&&n()}}}),w.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),w.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return w.globalEval(e),e}}}),w.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),w.ajaxTransport("script",function(e){if(e.crossDomain){var t,n;return{send:function(i,o){t=w("
diff --git a/templates/Sparkle/admin/ipsandports/ipsandports_edit.tpl b/templates/Sparkle/admin/ipsandports/ipsandports_edit.tpl index 4d12e2ac..4f61b938 100644 --- a/templates/Sparkle/admin/ipsandports/ipsandports_edit.tpl +++ b/templates/Sparkle/admin/ipsandports/ipsandports_edit.tpl @@ -6,6 +6,7 @@ $header {$title} +
diff --git a/templates/Sparkle/admin/message/message.tpl b/templates/Sparkle/admin/message/message.tpl index eaacf581..f047150a 100644 --- a/templates/Sparkle/admin/message/message.tpl +++ b/templates/Sparkle/admin/message/message.tpl @@ -23,8 +23,8 @@ $header - - + + diff --git a/templates/Sparkle/admin/settings/settings_form_begin.tpl b/templates/Sparkle/admin/settings/settings_form_begin.tpl index 87a16c57..792b8af1 100644 --- a/templates/Sparkle/admin/settings/settings_form_begin.tpl +++ b/templates/Sparkle/admin/settings/settings_form_begin.tpl @@ -1,5 +1,5 @@ $header - + diff --git a/templates/Sparkle/admin/templates/templates_add_2.tpl b/templates/Sparkle/admin/templates/templates_add_2.tpl index 6f197624..7077f924 100644 --- a/templates/Sparkle/admin/templates/templates_add_2.tpl +++ b/templates/Sparkle/admin/templates/templates_add_2.tpl @@ -40,23 +40,27 @@ $header + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - @@ -88,10 +92,6 @@ $header - - - - @@ -138,10 +138,6 @@ $header - - - - @@ -164,10 +160,6 @@ $header - - - - diff --git a/templates/Sparkle/admin/templates/templates_edit.tpl b/templates/Sparkle/admin/templates/templates_edit.tpl index d9a12501..875ef050 100644 --- a/templates/Sparkle/admin/templates/templates_edit.tpl +++ b/templates/Sparkle/admin/templates/templates_edit.tpl @@ -42,23 +42,27 @@ $header + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - @@ -90,10 +94,6 @@ $header - - - - @@ -140,10 +140,6 @@ $header - - - - @@ -166,10 +162,6 @@ $header - - - - @@ -190,4 +182,3 @@ $header $footer - diff --git a/templates/Sparkle/assets/css/custom.example.css b/templates/Sparkle/assets/css/custom.example.css new file mode 100644 index 00000000..66f3fef1 --- /dev/null +++ b/templates/Sparkle/assets/css/custom.example.css @@ -0,0 +1 @@ +/* To include your custom CSS for this theme, please rename this file to "custom.css" and place your CSS in it */ \ No newline at end of file diff --git a/templates/Sparkle/assets/css/main.css b/templates/Sparkle/assets/css/main.css index eb696992..8d6f7726 100644 --- a/templates/Sparkle/assets/css/main.css +++ b/templates/Sparkle/assets/css/main.css @@ -77,7 +77,11 @@ strong { } header img { - padding: 10px 0 10px 10px; + padding: 10px; +} +.login header img { + margin: 0 auto; + display: block; } img.small { @@ -1737,4 +1741,17 @@ td.size-50 { font-weight: 700; padding: 5px 10px; color: #ffe !important; -} \ No newline at end of file +} + +.footer-link:after { + content: " |"; +} +.footer-link:last-child:after { + content: ""; +} + +.field-image-preview { + max-width: 300px; + max-height: 500px; + margin-bottom: 10px; +} diff --git a/templates/Sparkle/assets/js/circular.js b/templates/Sparkle/assets/js/circular.js index 085743bf..f755c7e6 100644 --- a/templates/Sparkle/assets/js/circular.js +++ b/templates/Sparkle/assets/js/circular.js @@ -56,7 +56,7 @@ $(document).ready(function() { // Draw percentages if (!isNaN(assigned) && available == "∞") { - // Unlimited ressource and assigned + // Unlimited resource and assigned if (assigned > used) { // Draw assigned as full circle circularCircle(canvas, 38, 0, 270, 4, assiColor); @@ -77,7 +77,7 @@ $(document).ready(function() { } circularText(canvas, 60, 42, 26, "∞"); } else if (!isNaN(assigned)) { - // Limited ressources but assigned + // Limited resources but assigned available = parseFloat(available); assignedP = Math.round(100 / available * assigned); @@ -92,7 +92,7 @@ $(document).ready(function() { circularCircle(canvas, 40, 0, 270, 8, unliColor); circularText(canvas, 60, 42, 26, "∞"); } else { - // Limited ressources + // Limited resources available = parseFloat(available); usedP = 100 / available * used; if (usedP < 1 && usedP > 0) { diff --git a/templates/Sparkle/assets/js/ipsandports.js b/templates/Sparkle/assets/js/ipsandports.js new file mode 100644 index 00000000..87091afa --- /dev/null +++ b/templates/Sparkle/assets/js/ipsandports.js @@ -0,0 +1,46 @@ +$(document).ready(function() { + + var getUrlParameter = function getUrlParameter(sParam) { + var sPageURL = decodeURIComponent(window.location.search.substring(1)), + sURLVariables = sPageURL.split('&'), + sParameterName, + i; + + for (i = 0; i < sURLVariables.length; i++) { + sParameterName = sURLVariables[i].split('='); + + if (sParameterName[0] === sParam) { + return sParameterName[1] === undefined ? true : sParameterName[1]; + } + } + }; + + /** + * check for internal ip and output a notice if private-range ip is given + */ + $('#ip').change(function() { + var ipval = $(this).val(); + if (ipval.length > 0) { + var sid = getUrlParameter('s'); + $.ajax({ + url: "admin_ipsandports.php?s="+sid+"&page=overview&action=jqCheckIP", + type: "POST", + data: { + ip: ipval + }, + dataType: "json", + success: function(json) { + if (json != 0) { + $('#ip').parent().append(json); + } else { + $('#ipnote').remove(); + } + }, + error: function(a, b) { + console.log(a, b); + } + }); + } + }); + +}); diff --git a/templates/Sparkle/assets/js/traffic.js b/templates/Sparkle/assets/js/traffic.js index ffa6f1f7..5eb045c6 100644 --- a/templates/Sparkle/assets/js/traffic.js +++ b/templates/Sparkle/assets/js/traffic.js @@ -19,8 +19,8 @@ $(document).ready(function() { } else { ticks.push([i, $(row).children().first().html()]); } - ftp.push([i, parseFloat(ftpd / 1024)]); - http.push([i, parseFloat(httpd / 1024)]); + ftp.push([i, parseFloat(ftpd)]); + http.push([i, parseFloat(httpd)]); mail.push([i, parseFloat(maild)]); i++; }); @@ -107,24 +107,16 @@ $(document).ready(function() { "font-size": "11px" }).appendTo("body"); - $("#ftpchart, #httpchart").bind("plothover", function(event, pos, item) { + $("#ftpchart, #httpchart, #mailchart").bind("plothover", function(event, pos, item) { if (item) { - var y = item.datapoint[1].toFixed(2); + var y = item.datapoint[1]; + var unit = 'MiB'; + if (y > 1024) { + y /= 1024; + unit = 'GiB'; + } - $("#tooltip").html(item.series.label + ": " + y + " GiB").css({ - top: item.pageY + 5, - left: item.pageX - $("#tooltip").width() / 2 - }).fadeIn(200); - } else { - $("#tooltip").hide(); - } - }); - - $("#mailchart").bind("plothover", function(event, pos, item) { - if (item) { - var y = item.datapoint[1].toFixed(2); - - $("#tooltip").html(item.series.label + ": " + y + " MiB").css({ + $("#tooltip").html(item.series.label + ": " + y.toFixed(2) + " " + unit).css({ top: item.pageY + 5, left: item.pageX - $("#tooltip").width() / 2 }).fadeIn(200); diff --git a/templates/Sparkle/config.json b/templates/Sparkle/config.json index 1effdcb9..70e23c9c 100644 --- a/templates/Sparkle/config.json +++ b/templates/Sparkle/config.json @@ -2,7 +2,8 @@ "variants": { "default": { "css": [ - "main.css" + "main.css", + "custom.css" ], "js": [ "main.js", diff --git a/templates/Sparkle/customer/domains/domainlist.tpl b/templates/Sparkle/customer/domains/domainlist.tpl index 5325ee92..890f2104 100644 --- a/templates/Sparkle/customer/domains/domainlist.tpl +++ b/templates/Sparkle/customer/domains/domainlist.tpl @@ -3,7 +3,7 @@

  - {$lng['domains']['domainsettings']} ({$domains_count}) + {$lng['domains']['domainsettings']} ({$result['count']} / {$domains_count})

@@ -27,7 +27,7 @@
{SALUTATION}{$lng['admin']['templates']['SALUTATION']}
{FIRSTNAME}{$lng['admin']['templates']['FIRSTNAME']}
{NAME}{$lng['admin']['templates']['NAME']}
{COMPANY}{$lng['admin']['templates']['COMPANY']}
{CUSTOMER_NO}{$lng['admin']['templates']['CUSTOMER_NO']}
{SALUTATION}{$lng['admin']['templates']['SALUTATION']}
{FIRSTNAME}{$lng['admin']['templates']['FIRSTNAME']}
{NAME}{$lng['admin']['templates']['NAME']}
{COMPANY}{$lng['admin']['templates']['COMPANY']}
{USERNAME} {$lng['admin']['templates']['USERNAME']}
{SALUTATION}{$lng['admin']['templates']['SALUTATION']}
{USERNAME} {$lng['admin']['templates']['USERNAME']}
{SALUTATION}{$lng['admin']['templates']['SALUTATION']}
{DB_NAME} {$lng['admin']['templates']['DB_NAME']}
{SALUTATION}{$lng['admin']['templates']['SALUTATION']}
{USR_NAME} {$lng['admin']['templates']['USR_NAME']}
{SALUTATION}{$lng['admin']['templates']['SALUTATION']}
{FIRSTNAME}{$lng['admin']['templates']['FIRSTNAME']}
{NAME}{$lng['admin']['templates']['NAME']}
{COMPANY}{$lng['admin']['templates']['COMPANY']}
{CUSTOMER_NO}{$lng['admin']['templates']['CUSTOMER_NO']}
{SALUTATION}{$lng['admin']['templates']['SALUTATION']}
{FIRSTNAME}{$lng['admin']['templates']['FIRSTNAME']}
{NAME}{$lng['admin']['templates']['NAME']}
{COMPANY}{$lng['admin']['templates']['COMPANY']}
{USERNAME} {$lng['admin']['templates']['USERNAME']}
{SALUTATION}{$lng['admin']['templates']['SALUTATION']}
{USERNAME} {$lng['admin']['templates']['USERNAME']}
{SALUTATION}{$lng['admin']['templates']['SALUTATION']}
{DB_NAME} {$lng['admin']['templates']['DB_NAME']}
{SALUTATION}{$lng['admin']['templates']['SALUTATION']}
{USR_NAME} {$lng['admin']['templates']['USR_NAME']}
- + diff --git a/templates/Sparkle/customer/domains/domains_domain.tpl b/templates/Sparkle/customer/domains/domains_domain.tpl index 321b45b9..652ce34e 100644 --- a/templates/Sparkle/customer/domains/domains_domain.tpl +++ b/templates/Sparkle/customer/domains/domains_domain.tpl @@ -15,7 +15,7 @@ diff --git a/templates/Sparkle/customer/email/emails.tpl b/templates/Sparkle/customer/email/emails.tpl index 3ee17e54..da719798 100644 --- a/templates/Sparkle/customer/email/emails.tpl +++ b/templates/Sparkle/customer/email/emails.tpl @@ -3,7 +3,7 @@

  - {$lng['menue']['email']['emails']} ({$emailscount}) + {$lng['menue']['email']['emails']} ({$result['count']} / {$emailscount})

diff --git a/templates/Sparkle/customer/ftp/accounts.tpl b/templates/Sparkle/customer/ftp/accounts.tpl index ce431599..cf1f8b1a 100644 --- a/templates/Sparkle/customer/ftp/accounts.tpl +++ b/templates/Sparkle/customer/ftp/accounts.tpl @@ -3,7 +3,7 @@

  - {$lng['menue']['ftp']['accounts']} ({$ftps_count}) + {$lng['menue']['ftp']['accounts']} ({$result['count']} / {$ftps_count})

diff --git a/templates/Sparkle/customer/index/index.tpl b/templates/Sparkle/customer/index/index.tpl index 0f128703..f649e2ff 100644 --- a/templates/Sparkle/customer/index/index.tpl +++ b/templates/Sparkle/customer/index/index.tpl @@ -9,7 +9,7 @@ $header
- +
{$lng['customer']['total_diskspace']}
@@ -37,7 +37,7 @@ $header
- +
{$lng['customer']['diskspace']}
@@ -51,7 +51,7 @@ $header
- +
{$lng['customer']['traffic']}
@@ -87,7 +87,7 @@ $header {$userinfo['email_accounts']} {$lng['panel']['available']}
- {$userinfo['mailspace_used']} {$lng['customer']['mib']} + {$userinfo['mailspace_used']}
@@ -130,7 +130,7 @@ $header {$userinfo['mysqls']} {$lng['panel']['available']}
- {$userinfo['dbspace_used']} {$lng['customer']['mib']} + {$userinfo['dbspace_used']}
diff --git a/templates/Sparkle/customer/mysql/mysqls.tpl b/templates/Sparkle/customer/mysql/mysqls.tpl index f1085ca1..eed4c04f 100644 --- a/templates/Sparkle/customer/mysql/mysqls.tpl +++ b/templates/Sparkle/customer/mysql/mysqls.tpl @@ -3,7 +3,7 @@

  - {$lng['menue']['mysql']['databases']} ({$mysqls_count}) + {$lng['menue']['mysql']['databases']} ({$result['count']} / {$mysqls_count})

diff --git a/templates/Sparkle/footer.tpl b/templates/Sparkle/footer.tpl index 359c0bb9..590bc307 100644 --- a/templates/Sparkle/footer.tpl +++ b/templates/Sparkle/footer.tpl @@ -4,11 +4,14 @@
- Froxlor + Froxlor {$version}{$branding} © 2009-{$current_year} by the Froxlor Team
+ {$lng['imprint']} + {$lng['terms']} + {$lng['privacy']}

{$lng['panel']['translator']}: {$lng['translator']} diff --git a/templates/Sparkle/formfields/image.tpl b/templates/Sparkle/formfields/image.tpl new file mode 100644 index 00000000..1a880c44 --- /dev/null +++ b/templates/Sparkle/formfields/image.tpl @@ -0,0 +1,11 @@ +
+ + + diff --git a/templates/Sparkle/header.tpl b/templates/Sparkle/header.tpl index cfb3f205..f8271d25 100644 --- a/templates/Sparkle/header.tpl +++ b/templates/Sparkle/header.tpl @@ -3,10 +3,8 @@ - - @@ -65,7 +63,7 @@
  • {$lng['menue']['main']['apikeys']}
  • -
  • {$lng['menue']['main']['apihelp']}
  • +
  • {$lng['menue']['main']['apihelp']}
  • diff --git a/templates/Sparkle/login/fpwd.tpl b/templates/Sparkle/login/fpwd.tpl index 1764e47d..50eaa305 100644 --- a/templates/Sparkle/login/fpwd.tpl +++ b/templates/Sparkle/login/fpwd.tpl @@ -1,7 +1,7 @@ $header
    {$lng['domains']['domainname']} {$arrowcode['d.domain']}{$lng['domains']['domainname']} {$arrowcode['d.domain_ace']} {$lng['panel']['path']} {$lng['panel']['options']}
    {$row['documentroot']} - {$lng['domains']['aliasdomain']} {$row['aliasdomain']} + {$lng['domains']['aliasdomain']} {$row['aliasdomain']} @@ -28,7 +28,7 @@ {$lng['panel']['viewlogs']} - + {$lng['panel']['delete']}   @@ -46,10 +46,10 @@ {$lng['panel']['letsencrypt']} - + ({$lng['domains']['isassigneddomain']})  - + {$lng['domains']['hasaliasdomains']}
    {$label} + + Current Image
    + {$lng['panel']['image_field_delete']} +

    +
    + disabled="disabled" type="file" class="file" name="{$fieldname}" accept="image/jpeg, image/jpg, image/png, image/gif" /> +