diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 00000000..539d79c5 --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,57 @@ +# Contributing + +Before you start working on a PR, contact us via IRC in #froxlor on Freenode or +the forum at https://forum.froxlor.org to get a clue whether someone else isn't +already working on it or if we don not want/need this certain change. +Of course, bugfixes are always welcome. +However, at this stage of the 0.9.x branch, we are not looking for new +features or refactoring, especially not the kind which requires changes to a +lot of files. +Please focus on our API based version 0.10.x (current master). + + + + +## Checklist + +General rules for PRs are: +* Please save us all some trouble and unnecessary round-trips by _testing_ your +changes. + +* Re-write your commit history to provide a CLEAN history! + + * i.e. do not provide PRs which contain a commit that changes something, + the next changes it back, a third one changes it again, only a little + differently... + + +Thanks! + + + + +### Webserver changes +If you make changes to the functionality of webserver configuration, please +make sure your implementation covers all supported webservers. + + + + +### l10n + +If you add new language strings, please make sure you add the english fallback +strings in + +* `lng/english.lng.php` +* `install/lng/english.lng.php` (if applicable) + + + + +### New settings and database-layout changes +If you add new settings or layout changes, please make sure you add these to + +* `install/froxlor.sql` +* and handle the update (see `install/updates/froxlor/0.10/update_0.10.inc.php`) +* if you have any question on how update-process works, please contact us + diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..8cfead88 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms + +github: d00p +custom: ['https://paypal.me/Froxlor'] diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 00000000..ff27e343 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,64 @@ +# 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 +* or post a thread in our forum at https://forum.froxlor.org + +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 + + + + + +# Summary + +Please provide a concise summary of the problem you're experiencing... + + + + +# 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: ... + + + + +# Steps to reproduce + +1. +2. +3. + + + + +# Expected behavior + +1. +2. +3. + + + + +# Actual behavior + +1. +2. +3. + + + + +# Log files/log entries +syslog: +
+example
+
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..6b107ce3 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,38 @@ +# Description + +Please include a summary of the change and which issue is fixed if any. Please also include relevant motivation and context. List any dependencies that are required for this change. + +Fixes # (issue) + +## Type of change + +Please delete options that are not relevant. + +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) +- [ ] This change requires a documentation update + +# How Has This Been Tested? + +Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration + +- [ ] Test A +- [ ] Test B + +**Test Configuration**: + +* Distribution: +* Webserver: +* PHP: +* etc.etc.: + +# Checklist: + +- [ ] I have performed a self-review of my own code +- [ ] I have commented my code, particularly in hard-to-understand areas +- [ ] I have made corresponding changes to the documentation +- [ ] My changes generate no new warnings +- [ ] I have added tests that prove my fix is effective or that my feature works +- [ ] New and existing unit tests pass locally with my changes + diff --git a/.gitignore b/.gitignore index 0ef4964b..3d547882 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,9 @@ -templates/* -logs/* install/update.log +templates/* +lib/userdata.inc.php +lib/userdata.inc.php.bak +logs/* +!logs/index.html .buildpath .project .settings/ @@ -8,4 +11,10 @@ install/update.log *~ .well-known .idea -*.iml \ No newline at end of file +*.iml + +!templates/Froxlor/ +!templates/Sparkle/ +!templates/misc/ +templates/Froxlor/assets/img/logo_custom.png +vendor/ diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..eed5b7c8 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,64 @@ +language: php +dist: bionic +services: + - docker +php: + - 7.3 + +branches: + only: + - master + - namespaces + +matrix: + include: + - php: 7.3 + env: "DOCKER_MYSQL_TYPE=mysql DOCKER_MYSQL_VERSION=5.6" + - php: 7.3 + env: "DOCKER_MYSQL_TYPE=mysql DOCKER_MYSQL_VERSION=5.7" + - php: 7.3 + env: "DOCKER_MYSQL_TYPE=mysql DOCKER_MYSQL_VERSION=8.0 STARTCMD='mysqld --default-authentication-plugin=mysql_native_password'" + - php: 7.3 + env: "DOCKER_MYSQL_TYPE=mariadb DOCKER_MYSQL_VERSION=10.3" + - php: 7.3 + env: "DOCKER_MYSQL_TYPE=mariadb DOCKER_MYSQL_VERSION=10.4" + +addons: + apt: + update: true + +before_install: + - export MYSQL_DATABASE=froxlor010 + - docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=fr0xl0r.TravisCI -e MYSQL_DATABASE=$MYSQL_DATABASE -p 3306:3306 $DOCKER_MYSQL_TYPE:$DOCKER_MYSQL_VERSION $STARTCMD + - sudo apt-get install -y ant + - > + export tries=0; + export max_tries=20; + while [[ true ]]; do + tries=$((tries + 1)); + echo "waiting for database server to start up... [$tries]"; + sleep 5; + # Now see that today's table is there, which would indicate that the cron job ran. + mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI -s -e 'SHOW VARIABLES LIKE "%version%";' + look_exit=$?; + if [[ "$look_exit" = "0" ]]; then echo "Database server successfully started"; break; fi; + if [[ "$tries" -ge "$max_tries" ]]; then echo "Database server did not start in time"; exit 1; break; fi; + done; + +install: + - mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI -e "CREATE DATABASE IF NOT EXISTS froxlor010;" + - 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 + +script: + - ant phpunit-no-coverage + +notifications: + irc: "chat.freenode.net#froxlor" + webhooks: + urls: + - https://webhooks.gitter.im/e/bdf91d1c3f745e51f796 + on_success: always + on_failure: always + on_start: never diff --git a/2fa.php b/2fa.php new file mode 100644 index 00000000..9bd5f2cd --- /dev/null +++ b/2fa.php @@ -0,0 +1,90 @@ + (2018-) + * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt + * @package Panel + * @since 0.10.0 + * + */ + +// This file is being included in admin_index and customer_index +// and therefore does not need to require lib/init.php +if (AREA == 'admin') { + $upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_ADMINS . "` SET `type_2fa` = :t2fa, `data_2fa` = :d2fa WHERE adminid = :id"); + $uid = $userinfo['adminid']; +} elseif (AREA == 'customer') { + $upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET `type_2fa` = :t2fa, `data_2fa` = :d2fa WHERE customerid = :id"); + $uid = $userinfo['customerid']; +} +$success_message = ""; + +$tfa = new \Froxlor\FroxlorTwoFactorAuth('Froxlor ' . Settings::Get('system.hostname')); + +// do the delete and then just show a success-message +if ($action == 'delete') { + Database::pexecute($upd_stmt, array( + 't2fa' => 0, + 'd2fa' => "", + 'id' => $uid + )); + \Froxlor\UI\Response::standard_success($lng['2fa']['2fa_removed']); +} elseif ($action == 'add') { + $type = isset($_POST['type_2fa']) ? $_POST['type_2fa'] : '0'; + + if ($type == 0 || $type == 1) { + $data = ""; + } + if ($type == 2) { + // generate secret for TOTP + $data = $tfa->createSecret(); + } + Database::pexecute($upd_stmt, array( + 't2fa' => $type, + 'd2fa' => $data, + 'id' => $uid + )); + \Froxlor\UI\Response::standard_success(sprintf($lng['2fa']['2fa_added'], $filename, $s)); +} + +$log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed 2fa::overview"); + +if ($userinfo['type_2fa'] == '0') { + + // available types + $type_select_values = array( + 0 => '-', + 1 => 'E-Mail', + 2 => 'Authenticator' + ); + asort($type_select_values); + $type_select = ""; + foreach ($type_select_values as $_val => $_type) { + $type_select .= \Froxlor\UI\HTML::makeoption($_type, $_val); + } +} elseif ($userinfo['type_2fa'] == '1') { + // email 2fa enabled +} elseif ($userinfo['type_2fa'] == '2') { + // authenticator 2fa enabled + $ga_qrcode = $tfa->getQRCodeImageAsDataUri($userinfo['loginname'], $userinfo['data_2fa']); +} +eval("echo \"" . \Froxlor\UI\Template::getTemplate("2fa/overview", true) . "\";"); diff --git a/README.md b/README.md index 67c8c554..51b9d3d8 100644 --- a/README.md +++ b/README.md @@ -1,3 +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 The server administration software for your needs. @@ -11,13 +14,13 @@ Developed by experienced server administrators, this panel simplifies the effort 3. Point your browser to http://[ip-of-webserver]/froxlor 4. Follow the installer 5. Login as administrator -6. Adjust "Server > Settings" according to your needs -7. Choose your distribution under "Server > Configuration" +6. Adjust "System > Settings" according to your needs +7. Choose your distribution under "System > Configuration" 8. Follow the steps for your services 9. Have fun! ### Detailed installation -http://redmine.froxlor.org/projects/froxlor/wiki/Installationtarball +https://github.com/Froxlor/Froxlor/wiki/Install-froxlor-from-tarball ## Help @@ -30,12 +33,12 @@ irc://chat.freenode.net/froxlor ### Forum -The community is located on http://forum.froxlor.org +The community is located on https://forum.froxlor.org/ ### Wiki More documentation may be found in the froxlor - wiki: -http://redmine.froxlor.org/projects/froxlor/wiki +https://github.com/Froxlor/Froxlor/wiki ## License @@ -44,31 +47,28 @@ May be found in COPYING ## Downloads ### Tarball -http://files.froxlor.org/releases/froxlor-latest.tar.gz [MD5](http://files.froxlor.org/releases/froxlor-latest.tar.gz.md5) [SHA1](http://files.froxlor.org/releases/froxlor-latest.tar.gz.sha1) +https://files.froxlor.org/releases/froxlor-latest.tar.gz [MD5](https://files.froxlor.org/releases/froxlor-latest.tar.gz.md5) [SHA1](https://files.froxlor.org/releases/froxlor-latest.tar.gz.sha1) ### Debian repository -[HowTo](http://redmine.froxlor.org/projects/froxlor/wiki/Installationdebian) +[HowTo](https://github.com/Froxlor/Froxlor/wiki/Install-froxlor-on-debian) -/etc/apt/sources.list.d/froxlor.list -> deb http://debian.froxlor.org {wheezy|jessie} main +``` +apt-get -y install apt-transport-https lsb-release ca-certificates +wget -O - https://deb.froxlor.org/froxlor.gpg | apt-key add - +echo "deb https://deb.froxlor.org/debian $(lsb_release -sc) main" > /etc/apt/sources.list.d/froxlor.list +``` -### Gentoo repository +### Ubuntu repository -[HowTo](http://redmine.froxlor.org/projects/froxlor/wiki/Installationgentoo) +[HowTo](https://github.com/Froxlor/Froxlor/wiki/Install-froxlor-on-ubuntu) -http://files.froxlor.org/gentoo/repositories.xml +``` +apt-get -y install apt-transport-https lsb-release ca-certificates +wget -O - https://deb.froxlor.org/froxlor.gpg | apt-key add - +echo "deb https://deb.froxlor.org/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/froxlor.list +``` -## Let's Encrypt support - -This version of Froxlor contains a test implementation of support for [Let's Encrypt](https://letsencrypt.org). This is (as Let's Encrypt is in itself) -still a beta version and may break your system. The way it currently works is by creating a (sub-)domain with the default system - certificate, -after which the Let's Encrypt cronjob orders the certificate for this (sub-)domain and inserts the certificates in the database. With the next run -of the default cronjob, the certificates will be updated on the disk and the webserver reloaded. - -This has 2 known side-effects at the moment: -* The basic ip/port combinations don't work with the Froxlor - integration of Let's Encrypt, since it needs a certificate for the very first creation -* After creating a domain, it will have the default certificate for a short time (by default 5 minutes until the cronjob runs the next time) - -It may be possible to fix these issues, but they are not a priority at the moment +## Contributing +[see here](.github/CONTRIBUTING.md) diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000..2465b905 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,14 @@ +# Security Policy + +## Supported Versions + +Our main and active version is currently 0.10.x. It will receive maintenance and security updates periodically. The older version 0.9.x will not receive any kind of updates. Please update to [0.10.x](https://github.com/Froxlor/Froxlor/wiki/Updating-Froxlor) + +| Version | Supported | +| ------- | ------------------ | +| 0.10.x | :white_check_mark: | +| 0.9.x | :x: | + +## Reporting a Vulnerability + +If you think you have found a vulnerability in froxlor, please send an email to [team@froxlor.org](mailto:team@froxlor.org) with as many information as possible. Also, please give us appropriate time to fix the issue and build update-packages before publishing anything into the wild. diff --git a/actions/admin/settings/000.version.php b/actions/admin/settings/000.version.php deleted file mode 100644 index 12065743..00000000 --- a/actions/admin/settings/000.version.php +++ /dev/null @@ -1,72 +0,0 @@ - (2003-2009) - * @author Froxlor team (2010-) - * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt - * @package Settings - * - */ - -return array( - 'groups' => array( - 'version' => array( - 'fields' => array( - 'panel_version' => array( - 'settinggroup' => 'panel', - 'varname' => 'version', - 'type' => 'hidden', - 'default' => '', - ), - 'panel_frontend' => array( - 'settinggroup' => 'panel', - 'varname' => 'frontend', - 'type' => 'hidden', - 'default' => '', - ), - 'system_last_tasks_run' => array( - 'settinggroup' => 'system', - 'varname' => 'last_tasks_run', - 'type' => 'hidden', - 'default' => '', - 'save_method' => 'storeSettingField', - ), - 'system_last_traffic_run' => array( - 'settinggroup' => 'system', - 'varname' => 'last_traffic_run', - 'type' => 'hidden', - 'default' => '', - ), - 'system_lastcronrun' => array( - 'settinggroup' => 'system', - 'varname' => 'lastcronrun', - 'type' => 'hidden', - 'default' => '', - ), - 'system_lastguid' => array( - 'settinggroup' => 'system', - 'varname' => 'lastguid', - 'type' => 'hidden', - 'default' => 9999, - ), - 'system_lastaccountnumber' => array( - 'settinggroup' => 'system', - 'varname' => 'lastaccountnumber', - 'type' => 'hidden', - 'default' => 0, - ), - ), - ), - ), - ); - -?> diff --git a/actions/admin/settings/100.panel.php b/actions/admin/settings/100.panel.php index 63f771de..ffbb9f4f 100644 --- a/actions/admin/settings/100.panel.php +++ b/actions/admin/settings/100.panel.php @@ -16,40 +16,51 @@ * @package Language * */ - return array( 'groups' => array( 'panel' => array( 'title' => $lng['admin']['panelsettings'], 'fields' => array( 'panel_standardlanguage' => array( - 'label' => array('title' => $lng['login']['language'], 'description' => $lng['serversettings']['language']['description']), + 'label' => array( + 'title' => $lng['login']['language'], + 'description' => $lng['serversettings']['language']['description'] + ), 'settinggroup' => 'panel', 'varname' => 'standardlanguage', 'type' => 'option', 'default' => 'English', 'option_mode' => 'one', - 'option_options_method' => 'getLanguages', - 'save_method' => 'storeSettingField', + 'option_options_method' => array( + '\\Froxlor\\User', + 'getLanguages' ), + 'save_method' => 'storeSettingField' + ), 'panel_default_theme' => array( - 'label' => array('title' => $lng['panel']['theme'], 'description' => $lng['serversettings']['default_theme']), + 'label' => array( + 'title' => $lng['panel']['theme'], + 'description' => $lng['serversettings']['default_theme'] + ), 'settinggroup' => 'panel', 'varname' => 'default_theme', 'type' => 'option', - 'default' => 'Froxlor', + 'default' => 'Sparkle', 'option_mode' => 'one', - 'option_options_method' => 'getThemes', - 'save_method' => 'storeSettingDefaultTheme', + 'option_options_method' => array( + '\\Froxlor\\UI\\Template', + 'getThemes' ), + 'save_method' => 'storeSettingDefaultTheme' + ), 'panel_allow_theme_change_customer' => array( 'label' => $lng['serversettings']['panel_allow_theme_change_customer'], 'settinggroup' => 'panel', 'varname' => 'allow_theme_change_customer', 'type' => 'bool', 'default' => true, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'panel_allow_theme_change_admin' => array( 'label' => $lng['serversettings']['panel_allow_theme_change_admin'], 'settinggroup' => 'panel', @@ -57,23 +68,23 @@ return array( 'type' => 'bool', 'default' => true, 'save_method' => 'storeSettingField' - ), + ), 'panel_natsorting' => array( 'label' => $lng['serversettings']['natsorting'], 'settinggroup' => 'panel', 'varname' => 'natsorting', 'type' => 'bool', 'default' => false, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'panel_no_robots' => array( 'label' => $lng['serversettings']['no_robots'], 'settinggroup' => 'panel', 'varname' => 'no_robots', 'type' => 'bool', - 'default' => false, - 'save_method' => 'storeSettingField', - ), + 'default' => true, + 'save_method' => 'storeSettingField' + ), 'panel_paging' => array( 'label' => $lng['serversettings']['paging'], 'settinggroup' => 'panel', @@ -81,8 +92,8 @@ return array( 'type' => 'int', 'int_min' => 0, 'default' => 0, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'panel_pathedit' => array( 'label' => $lng['serversettings']['pathedit'], 'settinggroup' => 'panel', @@ -90,9 +101,12 @@ return array( 'type' => 'option', 'default' => 'Manual', 'option_mode' => 'one', - 'option_options' => array('Manual' => $lng['serversettings']['manual'], 'Dropdown' => $lng['serversettings']['dropdown']), - 'save_method' => 'storeSettingField', + 'option_options' => array( + 'Manual' => $lng['serversettings']['manual'], + 'Dropdown' => $lng['serversettings']['dropdown'] ), + 'save_method' => 'storeSettingField' + ), 'panel_adminmail' => array( 'label' => $lng['serversettings']['adminmail'], 'settinggroup' => 'panel', @@ -101,16 +115,16 @@ return array( 'string_type' => 'mail', 'string_emptyallowed' => false, 'default' => '', - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'panel_adminmail_defname' => array( 'label' => $lng['serversettings']['adminmail_defname'], 'settinggroup' => 'panel', 'varname' => 'adminmail_defname', 'type' => 'string', 'default' => 'Froxlor Administrator', - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'panel_adminmail_return' => array( 'label' => $lng['serversettings']['adminmail_return'], 'settinggroup' => 'panel', @@ -119,8 +133,8 @@ return array( 'string_type' => 'mail', 'string_emptyallowed' => true, 'default' => '', - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'panel_decimal_places' => array( 'label' => $lng['serversettings']['decimal_places'], 'settinggroup' => 'panel', @@ -129,8 +143,8 @@ return array( 'int_min' => 0, 'int_max' => 15, 'default' => 4, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'panel_phpmyadmin_url' => array( 'label' => $lng['serversettings']['phpmyadmin_url'], 'settinggroup' => 'panel', @@ -139,8 +153,8 @@ return array( 'string_type' => 'url', 'string_emptyallowed' => true, 'default' => '', - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'panel_webmail_url' => array( 'label' => $lng['serversettings']['webmail_url'], 'settinggroup' => 'panel', @@ -149,8 +163,8 @@ return array( 'string_type' => 'url', 'string_emptyallowed' => true, 'default' => '', - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'panel_webftp_url' => array( 'label' => $lng['serversettings']['webftp_url'], 'settinggroup' => 'panel', @@ -159,40 +173,40 @@ return array( 'string_type' => 'url', 'string_emptyallowed' => true, 'default' => '', - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'admin_show_version_login' => array( 'label' => $lng['admin']['show_version_login'], 'settinggroup' => 'admin', 'varname' => 'show_version_login', 'type' => 'bool', 'default' => false, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'admin_show_version_footer' => array( 'label' => $lng['admin']['show_version_footer'], 'settinggroup' => 'admin', 'varname' => 'show_version_footer', 'type' => 'bool', 'default' => false, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'admin_show_news_feed' => array( 'label' => $lng['admin']['show_news_feed'], 'settinggroup' => 'admin', 'varname' => 'show_news_feed', 'type' => 'bool', 'default' => false, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'customer_show_news_feed' => array( 'label' => $lng['admin']['customer_show_news_feed'], 'settinggroup' => 'customer', 'varname' => 'show_news_feed', 'type' => 'bool', 'default' => false, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'customer_news_feed_url' => array( 'label' => $lng['admin']['customer_news_feed_url'], 'settinggroup' => 'customer', @@ -201,35 +215,60 @@ return array( 'string_type' => 'url', 'string_emptyallowed' => true, 'default' => '', - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'panel_allow_domain_change_admin' => array( 'label' => $lng['serversettings']['panel_allow_domain_change_admin'], 'settinggroup' => 'panel', 'varname' => 'allow_domain_change_admin', 'type' => 'bool', 'default' => false, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'panel_allow_domain_change_customer' => array( 'label' => $lng['serversettings']['panel_allow_domain_change_customer'], 'settinggroup' => 'panel', 'varname' => 'allow_domain_change_customer', 'type' => 'bool', 'default' => false, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'panel_phpconfigs_hidestdsubdomain' => array( 'label' => $lng['serversettings']['panel_phpconfigs_hidestdsubdomain'], 'settinggroup' => 'panel', 'varname' => 'phpconfigs_hidestdsubdomain', 'type' => 'bool', 'default' => false, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' ), - ), - ), - ); + 'panel_customer_hide_options' => array( + 'label' => $lng['serversettings']['panel_customer_hide_options'], + 'settinggroup' => 'panel', + 'varname' => 'customer_hide_options', + 'type' => 'option', + 'default' => '', + 'option_mode' => 'multiple', + 'option_emptyallowed' => true, + 'option_options' => array( + 'email' => $lng['menue']['email']['email'], + 'mysql' => $lng['menue']['mysql']['mysql'], + 'domains' => $lng['menue']['domains']['domains'], + 'ftp' => $lng['menue']['ftp']['ftp'], + '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.backup' => $lng['menue']['extras']['extras'] . " / " . $lng['menue']['extras']['backup'], + 'traffic' => $lng['menue']['traffic']['traffic'], + 'traffic.http' => $lng['menue']['traffic']['traffic'] . " / HTTP", + 'traffic.ftp' => $lng['menue']['traffic']['traffic'] . " / FTP", + 'traffic.mail' => $lng['menue']['traffic']['traffic'] . " / Mail" + ), + 'save_method' => 'storeSettingField' + ) + ) + ) + ) +); ?> diff --git a/actions/admin/settings/110.accounts.php b/actions/admin/settings/110.accounts.php index eb2a24a6..71628dec 100644 --- a/actions/admin/settings/110.accounts.php +++ b/actions/admin/settings/110.accounts.php @@ -16,7 +16,6 @@ * @package Settings * */ - return array( 'groups' => array( 'accounts' => array( @@ -28,131 +27,144 @@ return array( 'varname' => 'sessiontimeout', 'type' => 'int', 'default' => 600, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'session_allow_multiple_login' => array( 'label' => $lng['serversettings']['session_allow_multiple_login'], 'settinggroup' => 'session', 'varname' => 'allow_multiple_login', 'type' => 'bool', 'default' => false, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'login_domain_login' => array( 'label' => $lng['serversettings']['login_domain_login'], 'settinggroup' => 'login', 'varname' => 'domain_login', 'type' => 'bool', 'default' => false, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'login_maxloginattempts' => array( 'label' => $lng['serversettings']['maxloginattempts'], 'settinggroup' => 'login', 'varname' => 'maxloginattempts', 'type' => 'int', 'default' => 3, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'login_deactivatetime' => array( 'label' => $lng['serversettings']['deactivatetime'], 'settinggroup' => 'login', 'varname' => 'deactivatetime', 'type' => 'int', 'default' => 900, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), + '2fa_enabled' => array( + 'label' => $lng['2fa']['2fa_enabled'], + 'settinggroup' => '2fa', + 'varname' => 'enabled', + 'type' => 'bool', + 'default' => true, + 'save_method' => 'storeSettingField' + ), 'panel_password_min_length' => array( 'label' => $lng['serversettings']['panel_password_min_length'], 'settinggroup' => 'panel', 'varname' => 'password_min_length', 'type' => 'int', 'default' => 0, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'panel_password_alpha_lower' => array( 'label' => $lng['serversettings']['panel_password_alpha_lower'], 'settinggroup' => 'panel', 'varname' => 'password_alpha_lower', 'type' => 'bool', 'default' => true, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'panel_password_alpha_upper' => array( 'label' => $lng['serversettings']['panel_password_alpha_upper'], 'settinggroup' => 'panel', 'varname' => 'password_alpha_upper', 'type' => 'bool', 'default' => true, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'panel_password_numeric' => array( 'label' => $lng['serversettings']['panel_password_numeric'], 'settinggroup' => 'panel', 'varname' => 'password_numeric', 'type' => 'bool', 'default' => false, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'panel_password_special_char_required' => array( 'label' => $lng['serversettings']['panel_password_special_char_required'], 'settinggroup' => 'panel', 'varname' => 'password_special_char_required', 'type' => 'bool', 'default' => false, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'panel_password_special_char' => array( 'label' => $lng['serversettings']['panel_password_special_char'], 'settinggroup' => 'panel', 'varname' => 'password_special_char', 'type' => 'string', 'default' => '!?<>§$%+#=@', - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'panel_password_regex' => array( 'label' => $lng['serversettings']['panel_password_regex'], 'settinggroup' => 'panel', 'varname' => 'password_regex', 'type' => 'string', 'default' => '', - /* 'plausibility_check_method' => 'checkValidRegEx', */ - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'customer_accountprefix' => array( 'label' => $lng['serversettings']['accountprefix'], 'settinggroup' => 'customer', 'varname' => 'accountprefix', 'type' => 'string', 'default' => '', - 'plausibility_check_method' => 'checkUsername', - 'save_method' => 'storeSettingField', + 'plausibility_check_method' => array( + '\\Froxlor\\Validate\\Check', + 'checkUsername' ), + 'save_method' => 'storeSettingField' + ), 'customer_mysqlprefix' => array( 'label' => $lng['serversettings']['mysqlprefix'], 'settinggroup' => 'customer', 'varname' => 'mysqlprefix', 'type' => 'string', 'default' => '', - 'plausibility_check_method' => 'checkUsername', - 'save_method' => 'storeSettingField', + 'plausibility_check_method' => array( + '\\Froxlor\\Validate\\Check', + 'checkUsername' ), + 'save_method' => 'storeSettingField' + ), 'customer_ftpprefix' => array( 'label' => $lng['serversettings']['ftpprefix'], 'settinggroup' => 'customer', 'varname' => 'ftpprefix', 'type' => 'string', 'default' => '', - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'customer_ftpatdomain' => array( 'label' => $lng['serversettings']['ftpdomain'], 'settinggroup' => 'customer', 'varname' => 'ftpatdomain', 'type' => 'bool', 'default' => false, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'panel_allow_preset' => array( 'label' => $lng['serversettings']['allow_password_reset'], 'settinggroup' => 'panel', @@ -161,14 +173,14 @@ return array( 'default' => false, 'save_method' => 'storeSettingField', 'dependency' => array( - 'fieldname' => 'panel_allow_preset_admin', - 'fielddata' => array( - 'settinggroup' => 'panel', - 'varname' => 'allow_preset_admin', - ), - 'onlyif' => 0 - ) - ), + 'fieldname' => 'panel_allow_preset_admin', + 'fielddata' => array( + 'settinggroup' => 'panel', + 'varname' => 'allow_preset_admin' + ), + 'onlyif' => 0 + ) + ), 'panel_allow_preset_admin' => array( 'label' => $lng['serversettings']['allow_password_reset_admin'], 'settinggroup' => 'panel', @@ -177,17 +189,25 @@ return array( 'default' => false, 'save_method' => 'storeSettingField', 'dependency' => array( - 'fieldname' => 'panel_allow_preset', - 'fielddata' => array( - 'settinggroup' => 'panel', - 'varname' => 'allow_preset', - ), - 'onlyif' => 1 - ) - ), + 'fieldname' => 'panel_allow_preset', + 'fielddata' => array( + 'settinggroup' => 'panel', + 'varname' => 'allow_preset' + ), + 'onlyif' => 1 + ) ), - ), - ), - ); + 'system_backupenabled' => array( + 'label' => $lng['serversettings']['backupenabled'], + 'settinggroup' => 'system', + 'varname' => 'backupenabled', + 'type' => 'bool', + 'default' => false, + 'cronmodule' => 'froxlor/backup', + 'save_method' => 'storeSettingField' + ) + ) + ) + ) +); -?> diff --git a/actions/admin/settings/120.system.php b/actions/admin/settings/120.system.php index 46faefcf..fb2f04b1 100644 --- a/actions/admin/settings/120.system.php +++ b/actions/admin/settings/120.system.php @@ -16,7 +16,6 @@ * @package Settings * */ - return array( 'groups' => array( 'system' => array( @@ -30,36 +29,58 @@ return array( 'string_type' => 'dir', 'default' => '/var/customers/webs/', 'save_method' => 'storeSettingField', - 'plausibility_check_method' => 'checkPathConflicts' - ), + 'plausibility_check_method' => array( + '\\Froxlor\\Validate\\Check', + 'checkPathConflicts' + ) + ), 'system_documentroot_use_default_value' => array( 'label' => $lng['serversettings']['documentroot_use_default_value'], 'settinggroup' => 'system', 'varname' => 'documentroot_use_default_value', 'type' => 'bool', 'default' => false, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'system_ipaddress' => array( 'label' => $lng['serversettings']['ipaddress'], 'settinggroup' => 'system', 'varname' => 'ipaddress', 'type' => 'option', 'option_mode' => 'one', - 'option_options_method' => 'getIpAddresses', - 'default' => '', - 'save_method' => 'storeSettingIpAddress', + 'option_options_method' => array( + '\\Froxlor\\Domain\\IpAddr', + 'getIpAddresses' ), + 'default' => '', + 'save_method' => 'storeSettingIpAddress' + ), 'system_defaultip' => array( 'label' => $lng['serversettings']['defaultip'], 'settinggroup' => 'system', 'varname' => 'defaultip', 'type' => 'option', 'option_mode' => 'multiple', - 'option_options_method' => 'getIpPortCombinations', - 'default' => '', - 'save_method' => 'storeSettingDefaultIp', + 'option_options_method' => array( + '\\Froxlor\\Domain\\IpAddr', + 'getIpPortCombinations' ), + 'default' => '', + 'save_method' => 'storeSettingDefaultIp' + ), + 'system_defaultsslip' => array( + 'label' => $lng['serversettings']['defaultsslip'], + 'settinggroup' => 'system', + 'varname' => 'defaultsslip', + 'type' => 'option', + 'option_mode' => 'multiple', + 'option_options_method' => array( + '\\Froxlor\\Domain\\IpAddr', + 'getSslIpPortCombinations' + ), + 'default' => '', + 'save_method' => 'storeSettingDefaultSslIp' + ), 'system_hostname' => array( 'label' => $lng['serversettings']['hostname'], 'settinggroup' => 'system', @@ -67,41 +88,55 @@ return array( 'type' => 'string', 'default' => '', 'save_method' => 'storeSettingHostname', - 'plausibility_check_method' => 'checkHostname', - ), - 'system_froxlordirectlyviahostname' => array( - 'label' => $lng['serversettings']['froxlordirectlyviahostname'], - 'settinggroup' => 'system', - 'varname' => 'froxlordirectlyviahostname', + 'plausibility_check_method' => array( + '\\Froxlor\\Validate\\Check', + 'checkHostname' + ) + ), + 'api_enabled' => array( + 'label' => $lng['serversettings']['enable_api'], + 'settinggroup' => 'api', + 'varname' => 'enabled', 'type' => 'bool', 'default' => false, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'system_validatedomain' => array( 'label' => $lng['serversettings']['validate_domain'], 'settinggroup' => 'system', 'varname' => 'validate_domain', 'type' => 'bool', 'default' => true, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'system_stdsubdomain' => array( 'label' => $lng['serversettings']['stdsubdomainhost'], 'settinggroup' => 'system', 'varname' => 'stdsubdomain', 'type' => 'string', 'default' => '', - 'save_method' => 'storeSettingHostname', - ), + 'save_method' => 'storeSettingHostname' + ), 'system_mysql_access_host' => array( 'label' => $lng['serversettings']['mysql_access_host'], 'settinggroup' => 'system', 'varname' => 'mysql_access_host', 'type' => 'string', 'default' => '127.0.0.1,localhost', - 'plausibility_check_method' => 'checkMysqlAccessHost', - 'save_method' => 'storeSettingMysqlAccessHost', + 'plausibility_check_method' => array( + '\\Froxlor\\Validate\\Check', + 'checkMysqlAccessHost' ), + 'save_method' => 'storeSettingMysqlAccessHost' + ), + 'system_nssextrausers' => array( + 'label' => $lng['serversettings']['nssextrausers'], + 'settinggroup' => 'system', + 'varname' => 'nssextrausers', + 'type' => 'bool', + 'default' => false, + 'save_method' => 'storeSettingField' + ), 'system_index_file_extension' => array( 'label' => $lng['serversettings']['index_file_extension'], 'settinggroup' => 'system', @@ -109,28 +144,28 @@ return array( 'type' => 'string', 'string_regexp' => '/^[a-zA-Z0-9]{1,6}$/', 'default' => 'html', - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'system_store_index_file_subs' => array( 'label' => $lng['serversettings']['system_store_index_file_subs'], 'settinggroup' => 'system', 'varname' => 'store_index_file_subs', 'type' => 'bool', 'default' => true, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'system_httpuser' => array( 'settinggroup' => 'system', 'varname' => 'httpuser', 'type' => 'hidden', - 'default' => 'www-data', - ), + 'default' => 'www-data' + ), 'system_httpgroup' => array( 'settinggroup' => 'system', 'varname' => 'httpgroup', 'type' => 'hidden', - 'default' => 'www-data', - ), + 'default' => 'www-data' + ), 'system_report_enable' => array( 'label' => $lng['serversettings']['report']['report'], 'settinggroup' => 'system', @@ -138,29 +173,112 @@ return array( 'type' => 'bool', 'default' => true, 'cronmodule' => 'froxlor/reports', - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'system_report_webmax' => array( 'label' => $lng['serversettings']['report']['webmax'], 'settinggroup' => 'system', 'varname' => 'report_webmax', 'type' => 'int', - 'int_min' => 1, + 'int_min' => 0, 'int_max' => 150, 'default' => 90, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'system_report_trafficmax' => array( 'label' => $lng['serversettings']['report']['trafficmax'], 'settinggroup' => 'system', 'varname' => 'report_trafficmax', 'type' => 'int', - 'int_min' => 1, + 'int_min' => 0, 'int_max' => 150, 'default' => 90, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' ), - ), - ), - ); + + 'system_mail_use_smtp' => array( + 'label' => $lng['serversettings']['mail_use_smtp'], + 'settinggroup' => 'system', + 'varname' => 'mail_use_smtp', + 'type' => 'bool', + 'default' => false, + 'save_method' => 'storeSettingField' + ), + 'system_mail_smtp_host' => array( + 'label' => $lng['serversettings']['mail_smtp_host'], + 'settinggroup' => 'system', + 'varname' => 'mail_smtp_host', + 'type' => 'string', + 'default' => 'localhost', + 'save_method' => 'storeSettingField' + ), + 'system_mail_smtp_port' => array( + 'label' => $lng['serversettings']['mail_smtp_port'], + 'settinggroup' => 'system', + 'varname' => 'mail_smtp_port', + 'type' => 'int', + 'int_min' => 1, + 'int_max' => 65535, + 'default' => 25, + 'save_method' => 'storeSettingField' + ), + 'system_mail_smtp_usetls' => array( + 'label' => $lng['serversettings']['mail_smtp_usetls'], + 'settinggroup' => 'system', + 'varname' => 'mail_smtp_usetls', + 'type' => 'bool', + 'default' => true, + 'save_method' => 'storeSettingField' + ), + 'system_mail_smtp_auth' => array( + 'label' => $lng['serversettings']['mail_smtp_auth'], + 'settinggroup' => 'system', + 'varname' => 'mail_smtp_auth', + 'type' => 'bool', + 'default' => true, + 'save_method' => 'storeSettingField' + ), + 'system_mail_smtp_user' => array( + 'label' => $lng['serversettings']['mail_smtp_user'], + 'settinggroup' => 'system', + 'varname' => 'mail_smtp_user', + 'type' => 'string', + 'default' => '', + 'save_method' => 'storeSettingField' + ), + 'system_mail_smtp_passwd' => array( + 'label' => $lng['serversettings']['mail_smtp_passwd'], + 'settinggroup' => 'system', + 'varname' => 'mail_smtp_passwd', + 'type' => 'hiddenString', + 'default' => '', + 'save_method' => 'storeSettingField' + ), + 'system_apply_specialsettings_default' => array( + 'label' => $lng['serversettings']['apply_specialsettings_default'], + 'settinggroup' => 'system', + 'varname' => 'apply_specialsettings_default', + 'type' => 'bool', + 'default' => true, + 'save_method' => 'storeSettingField' + ), + 'system_apply_phpconfigs_default' => array( + 'label' => $lng['serversettings']['apply_phpconfigs_default'], + 'settinggroup' => 'system', + 'varname' => 'apply_phpconfigs_default', + 'type' => 'bool', + 'default' => true, + '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/122.froxlorvhost.php b/actions/admin/settings/122.froxlorvhost.php new file mode 100644 index 00000000..41c9136c --- /dev/null +++ b/actions/admin/settings/122.froxlorvhost.php @@ -0,0 +1,271 @@ + (2016-) + * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt + * @package \Froxlor\Settings + * + */ +return array( + 'groups' => array( + 'froxlorvhost' => array( + 'title' => $lng['admin']['froxlorvhost'] . (call_user_func(array('\Froxlor\Settings\FroxlorVhostSettings', 'hasVhostContainerEnabled')) == false ? $lng['admin']['novhostcontainer'] : ''), + 'fields' => array( + /** + * Webserver-Vhost + */ + 'system_froxlordirectlyviahostname' => array( + 'label' => $lng['serversettings']['froxlordirectlyviahostname'], + 'settinggroup' => 'system', + 'varname' => 'froxlordirectlyviahostname', + 'type' => 'bool', + 'default' => false, + 'save_method' => 'storeSettingField' + ), + 'system_froxloraliases' => array( + 'label' => $lng['serversettings']['froxloraliases'], + 'settinggroup' => 'system', + 'varname' => 'froxloraliases', + 'type' => 'string', + 'string_regexp' => '/^(([a-z0-9\-\._]+, ?)*[a-z0-9\-\._]+)?$/i', + 'string_emptyallowed' => true, + 'default' => '', + 'save_method' => 'storeSettingField' + ), + /** + * SSL / Let's Encrypt + */ + 'system_le_froxlor_enabled' => array( + 'label' => $lng['serversettings']['le_froxlor_enabled'], + 'settinggroup' => 'system', + 'varname' => 'le_froxlor_enabled', + 'type' => 'bool', + 'default' => false, + 'save_method' => 'storeSettingClearCertificates', + 'visible' => \Froxlor\Settings::Get('system.leenabled') && call_user_func(array( + '\Froxlor\Settings\FroxlorVhostSettings', + 'hasVhostContainerEnabled' + ), true) + ), + 'system_le_froxlor_redirect' => array( + 'label' => $lng['serversettings']['le_froxlor_redirect'], + 'settinggroup' => 'system', + 'varname' => 'le_froxlor_redirect', + 'type' => 'bool', + 'default' => false, + 'save_method' => 'storeSettingField', + 'visible' => \Froxlor\Settings::Get('system.use_ssl') && call_user_func(array( + '\Froxlor\Settings\FroxlorVhostSettings', + 'hasVhostContainerEnabled' + ), true) + ), + 'system_hsts_maxage' => array( + 'label' => $lng['admin']['domain_hsts_maxage'], + 'settinggroup' => 'system', + 'varname' => 'hsts_maxage', + 'type' => 'int', + 'int_min' => 0, + 'int_max' => 94608000, // 3-years + 'default' => 0, + 'save_method' => 'storeSettingField', + 'visible' => \Froxlor\Settings::Get('system.use_ssl') && call_user_func(array( + '\Froxlor\Settings\FroxlorVhostSettings', + 'hasVhostContainerEnabled' + ), true) + ), + 'system_hsts_incsub' => array( + 'label' => $lng['admin']['domain_hsts_incsub'], + 'settinggroup' => 'system', + 'varname' => 'hsts_incsub', + 'type' => 'bool', + 'default' => false, + 'save_method' => 'storeSettingField', + 'visible' => \Froxlor\Settings::Get('system.use_ssl') && call_user_func(array( + '\Froxlor\Settings\FroxlorVhostSettings', + 'hasVhostContainerEnabled' + ), true) + ), + 'system_hsts_preload' => array( + 'label' => $lng['admin']['domain_hsts_preload'], + 'settinggroup' => 'system', + 'varname' => 'hsts_preload', + 'type' => 'bool', + 'default' => false, + 'save_method' => 'storeSettingField', + 'visible' => \Froxlor\Settings::Get('system.use_ssl') && call_user_func(array( + '\Froxlor\Settings\FroxlorVhostSettings', + 'hasVhostContainerEnabled' + ), true) + ), + 'system_honorcipherorder' => array( + 'label' => $lng['admin']['domain_honorcipherorder'], + 'settinggroup' => 'system', + 'varname' => 'honorcipherorder', + 'type' => 'bool', + 'default' => false, + 'save_method' => 'storeSettingField', + 'visible' => \Froxlor\Settings::Get('system.use_ssl') && call_user_func(array( + '\Froxlor\Settings\FroxlorVhostSettings', + 'hasVhostContainerEnabled' + ), true) + ), + 'system_sessiontickets' => array( + 'label' => $lng['admin']['domain_sessiontickets'], + 'settinggroup' => 'system', + 'varname' => 'sessiontickets', + 'type' => 'bool', + 'default' => true, + 'save_method' => 'storeSettingField', + 'visible' => \Froxlor\Settings::Get('system.use_ssl') && call_user_func(array( + '\Froxlor\Settings\FroxlorVhostSettings', + 'hasVhostContainerEnabled' + ), true) + ), + /** + * FCGID + */ + 'system_mod_fcgid_enabled_ownvhost' => array( + 'label' => $lng['serversettings']['mod_fcgid_ownvhost'], + 'settinggroup' => 'system', + 'varname' => 'mod_fcgid_ownvhost', + 'type' => 'bool', + 'default' => true, + 'save_method' => 'storeSettingField', + 'websrv_avail' => array( + 'apache2' + ), + 'visible' => \Froxlor\Settings::Get('system.mod_fcgid') && call_user_func(array( + '\Froxlor\Settings\FroxlorVhostSettings', + 'hasVhostContainerEnabled' + )) + ), + 'system_mod_fcgid_httpuser' => array( + 'label' => $lng['admin']['mod_fcgid_user'], + 'settinggroup' => 'system', + 'varname' => 'mod_fcgid_httpuser', + 'type' => 'string', + 'default' => 'froxlorlocal', + 'save_method' => 'storeSettingWebserverFcgidFpmUser', + 'websrv_avail' => array( + 'apache2' + ), + 'visible' => \Froxlor\Settings::Get('system.mod_fcgid') && call_user_func(array( + '\Froxlor\Settings\FroxlorVhostSettings', + 'hasVhostContainerEnabled' + )) + ), + 'system_mod_fcgid_httpgroup' => array( + 'label' => $lng['admin']['mod_fcgid_group'], + 'settinggroup' => 'system', + 'varname' => 'mod_fcgid_httpgroup', + 'type' => 'string', + 'default' => 'froxlorlocal', + 'save_method' => 'storeSettingField', + 'websrv_avail' => array( + 'apache2' + ), + 'visible' => \Froxlor\Settings::Get('system.mod_fcgid') && call_user_func(array( + '\Froxlor\Settings\FroxlorVhostSettings', + 'hasVhostContainerEnabled' + )) + ), + 'system_mod_fcgid_defaultini_ownvhost' => array( + 'label' => $lng['serversettings']['mod_fcgid']['defaultini_ownvhost'], + 'settinggroup' => 'system', + 'varname' => 'mod_fcgid_defaultini_ownvhost', + 'type' => 'option', + 'default' => '2', + 'option_mode' => 'one', + 'option_options_method' => array( + '\\Froxlor\\Http\\PhpConfig', + 'getPhpConfigs' + ), + 'save_method' => 'storeSettingField', + 'websrv_avail' => array( + 'apache2' + ), + 'visible' => \Froxlor\Settings::Get('system.mod_fcgid') && call_user_func(array( + '\Froxlor\Settings\FroxlorVhostSettings', + 'hasVhostContainerEnabled' + )) + ), + /** + * php-fpm + */ + 'system_phpfpm_enabled_ownvhost' => array( + 'label' => $lng['phpfpm']['ownvhost'], + 'settinggroup' => 'phpfpm', + 'varname' => 'enabled_ownvhost', + 'type' => 'bool', + 'default' => true, + 'save_method' => 'storeSettingField', + 'visible' => \Froxlor\Settings::Get('phpfpm.enabled') && call_user_func(array( + '\Froxlor\Settings\FroxlorVhostSettings', + 'hasVhostContainerEnabled' + )) + ), + 'system_phpfpm_httpuser' => array( + 'label' => $lng['phpfpm']['vhost_httpuser'], + 'settinggroup' => 'phpfpm', + 'varname' => 'vhost_httpuser', + 'type' => 'string', + 'default' => 'froxlorlocal', + 'save_method' => 'storeSettingWebserverFcgidFpmUser', + 'visible' => \Froxlor\Settings::Get('phpfpm.enabled') && call_user_func(array( + '\Froxlor\Settings\FroxlorVhostSettings', + 'hasVhostContainerEnabled' + )) + ), + 'system_phpfpm_httpgroup' => array( + 'label' => $lng['phpfpm']['vhost_httpgroup'], + 'settinggroup' => 'phpfpm', + 'varname' => 'vhost_httpgroup', + 'type' => 'string', + 'default' => 'froxlorlocal', + 'save_method' => 'storeSettingField', + 'visible' => \Froxlor\Settings::Get('phpfpm.enabled') && call_user_func(array( + '\Froxlor\Settings\FroxlorVhostSettings', + 'hasVhostContainerEnabled' + )) + ), + 'system_phpfpm_defaultini_ownvhost' => array( + 'label' => $lng['serversettings']['mod_fcgid']['defaultini_ownvhost'], + 'settinggroup' => 'phpfpm', + 'varname' => 'vhost_defaultini', + 'type' => 'option', + 'default' => '2', + 'option_mode' => 'one', + 'option_options_method' => array( + '\\Froxlor\\Http\\PhpConfig', + 'getPhpConfigs' + ), + 'save_method' => 'storeSettingField', + 'visible' => \Froxlor\Settings::Get('phpfpm.enabled') && call_user_func(array( + '\Froxlor\Settings\FroxlorVhostSettings', + 'hasVhostContainerEnabled' + )) + ), + /** + * DNS + */ + 'system_dns_createhostnameentry' => array( + 'label' => $lng['serversettings']['dns_createhostnameentry'], + 'settinggroup' => 'system', + 'varname' => 'dns_createhostnameentry', + 'type' => 'bool', + 'default' => false, + 'save_method' => 'storeSettingField', + 'visible' => \Froxlor\Settings::Get('system.bind_enable') + ) + ) + ) + ) +); diff --git a/actions/admin/settings/125.cronjob.php b/actions/admin/settings/125.cronjob.php index 9a7eb49d..66a72754 100644 --- a/actions/admin/settings/125.cronjob.php +++ b/actions/admin/settings/125.cronjob.php @@ -14,7 +14,6 @@ * @package Settings * */ - return array( 'groups' => array( 'crond' => array( @@ -27,40 +26,40 @@ return array( 'type' => 'string', 'string_type' => 'file', 'default' => '/etc/cron.d/froxlor', - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'system_croncmdline' => array( 'label' => $lng['serversettings']['system_croncmdline'], 'settinggroup' => 'system', 'varname' => 'croncmdline', 'type' => 'string', 'default' => '/usr/bin/nice -n 5 /usr/bin/php -q', - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'system_crondreload' => array( 'label' => $lng['serversettings']['system_crondreload'], 'settinggroup' => 'system', 'varname' => 'crondreload', 'type' => 'string', 'default' => '/etc/init.d/cron reload', - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'system_cron_allowautoupdate' => array( 'label' => $lng['serversettings']['system_cron_allowautoupdate'], 'settinggroup' => 'system', 'varname' => 'cron_allowautoupdate', 'type' => 'bool', 'default' => false, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'system_debug_cron' => array( 'label' => $lng['serversettings']['cron']['debug'], 'settinggroup' => 'system', 'varname' => 'debug_cron', 'type' => 'bool', 'default' => false, - 'save_method' => 'storeSettingField', - ) + 'save_method' => 'storeSettingField' + ) ) ) ) diff --git a/actions/admin/settings/130.webserver.php b/actions/admin/settings/130.webserver.php index d3bdc77d..05257264 100644 --- a/actions/admin/settings/130.webserver.php +++ b/actions/admin/settings/130.webserver.php @@ -13,10 +13,9 @@ * @author Florian Lippert (2003-2009) * @author Froxlor team (2010-) * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt - * @package Settings + * @package \Froxlor\Settings * */ - return array( 'groups' => array( 'webserver' => array( @@ -29,11 +28,18 @@ return array( 'type' => 'option', 'default' => 'apache2', 'option_mode' => 'one', - 'option_options' => array('apache2' => 'Apache 2', 'lighttpd' => 'ligHTTPd', 'nginx' => 'Nginx'), - 'save_method' => 'storeSettingField', - 'plausibility_check_method' => 'checkPhpInterfaceSetting', - 'overview_option' => true + 'option_options' => array( + 'apache2' => 'Apache 2', + 'lighttpd' => 'ligHTTPd', + 'nginx' => 'Nginx' ), + 'save_method' => 'storeSettingField', + 'plausibility_check_method' => array( + '\\Froxlor\\Validate\\Check', + 'checkPhpInterfaceSetting' + ), + 'overview_option' => true + ), 'system_apache_24' => array( 'label' => $lng['serversettings']['apache_24'], 'settinggroup' => 'system', @@ -41,34 +47,62 @@ return array( 'type' => 'bool', 'default' => false, 'save_method' => 'storeSettingField', - 'websrv_avail' => array('apache2') + 'websrv_avail' => array( + 'apache2' + ) + ), + 'system_apache_itksupport' => array( + 'label' => $lng['serversettings']['apache_itksupport'], + 'settinggroup' => 'system', + 'varname' => 'apacheitksupport', + 'type' => 'bool', + 'default' => false, + 'save_method' => 'storeSettingField', + 'visible' => (\Froxlor\Settings::Get('system.mod_fcgid') == 0 && \Froxlor\Settings::Get('phpfpm.enabled') == 0), + 'websrv_avail' => array( + 'apache2' + ) + ), + 'system_http2_support' => array( + 'label' => $lng['serversettings']['http2_support'], + 'settinggroup' => 'system', + 'varname' => 'http2_support', + 'type' => 'bool', + 'default' => false, + 'save_method' => 'storeSettingField', + 'websrv_avail' => array( + 'apache2', + 'nginx' ), - 'system_apache_itksupport' => array( - 'label' => $lng['serversettings']['apache_itksupport'], - 'settinggroup' => 'system', - 'varname' => 'apacheitksupport', - 'type' => 'bool', - 'default' => false, - 'save_method' => 'storeSettingField', - 'visible' => (Settings::Get('system.mod_fcgid') == 0 && Settings::Get('phpfpm.enabled') == 0), - 'websrv_avail' => array('apache2') - ), + 'visible' => \Froxlor\Settings::Get('system.use_ssl') + ), + 'system_dhparams_file' => array( + 'label' => $lng['serversettings']['dhparams_file'], + 'settinggroup' => 'system', + 'varname' => 'dhparams_file', + 'type' => 'string', + 'string_type' => 'file', + 'string_emptyallowed' => true, + 'default' => '', + 'save_method' => 'storeSettingField', + 'visible' => \Froxlor\Settings::Get('system.use_ssl') + ), 'system_httpuser' => array( 'label' => $lng['admin']['webserver_user'], 'settinggroup' => 'system', 'varname' => 'httpuser', 'type' => 'string', 'default' => 'www-data', - 'save_method' => 'storeSettingWebserverFcgidFpmUser', - ), + 'save_method' => 'storeSettingWebserverFcgidFpmUser' + ), 'system_httpgroup' => array( 'label' => $lng['admin']['webserver_group'], 'settinggroup' => 'system', 'varname' => 'httpgroup', 'type' => 'string', 'default' => 'www-data', - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'system_apacheconf_vhost' => array( 'label' => $lng['serversettings']['apacheconf_vhost'], 'settinggroup' => 'system', @@ -76,8 +110,8 @@ return array( 'type' => 'string', 'string_type' => 'filedir', 'default' => '/etc/apache2/sites-enabled/', - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'system_apacheconf_diroptions' => array( 'label' => $lng['serversettings']['apacheconf_diroptions'], 'settinggroup' => 'system', @@ -85,8 +119,8 @@ return array( 'type' => 'string', 'string_type' => 'filedir', 'default' => '/etc/apache2/sites-enabled/', - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'system_apacheconf_htpasswddir' => array( 'label' => $lng['serversettings']['apacheconf_htpasswddir'], 'settinggroup' => 'system', @@ -94,8 +128,8 @@ return array( 'type' => 'string', 'string_type' => 'confdir', 'default' => '/etc/apache2/htpasswd/', - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'system_logfiles_directory' => array( 'label' => $lng['serversettings']['logfiles_directory'], 'settinggroup' => 'system', @@ -103,8 +137,84 @@ return array( 'type' => 'string', 'string_type' => 'dir', 'default' => '/var/customers/logs/', + 'save_method' => 'storeSettingField' + ), + 'system_logfiles_script' => array( + 'label' => $lng['serversettings']['logfiles_script'], + 'settinggroup' => 'system', + 'varname' => 'logfiles_script', + 'type' => 'string', + 'string_type' => '', + 'default' => '', 'save_method' => 'storeSettingField', + 'websrv_avail' => array( + 'apache2' + ) + ), + 'system_logfiles_piped' => array( + 'label' => $lng['serversettings']['logfiles_piped'], + 'settinggroup' => 'system', + 'varname' => 'logfiles_piped', + 'type' => 'bool', + 'default' => false, + 'save_method' => 'storeSettingField', + 'websrv_avail' => array( + 'apache2' + ) + ), + 'system_logfiles_format' => array( + 'label' => $lng['serversettings']['logfiles_format'], + 'settinggroup' => 'system', + 'varname' => 'logfiles_format', + 'type' => 'string', + 'default' => '', + 'string_emptyallowed' => true, + 'save_method' => 'storeSettingField', + 'websrv_avail' => array( + 'apache2', + 'nginx' ), + 'visible' => \Froxlor\Settings::Get('system.awstats_enabled') == 1 + ), + 'system_logfiles_type' => array( + 'label' => $lng['serversettings']['logfiles_type'], + 'settinggroup' => 'system', + 'varname' => 'logfiles_type', + 'type' => 'option', + 'default' => '1', + 'option_mode' => 'one', + 'option_options' => array( + '1' => 'combined', + '2' => 'vhost_combined' + ), + 'save_method' => 'storeSettingField', + 'websrv_avail' => array( + 'apache2' + ) + ), + 'system_errorlog_level' => array( + 'label' => $lng['serversettings']['errorlog_level'], + 'settinggroup' => 'system', + 'varname' => 'errorlog_level', + 'type' => 'option', + 'default' => (\Froxlor\Settings::Get('system.webserver') == 'nginx' ? 'error' : 'warn'), + 'option_mode' => 'one', + 'option_options' => array( + 'emerg' => 'emerg', + 'alert' => 'alert', + 'crit' => 'crit', + 'error' => 'error', + 'warn' => 'warn', + 'notice' => 'notice', + 'info' => 'info', + 'debug' => 'debug' + ), + 'save_method' => 'storeSettingField', + 'websrv_avail' => array( + 'apache2', + 'nginx' + ) + ), 'system_customersslpath' => array( 'label' => $lng['serversettings']['customerssl_directory'], 'settinggroup' => 'system', @@ -112,8 +222,8 @@ return array( 'type' => 'string', 'string_type' => 'confdir', 'default' => '/etc/ssl/froxlor-custom/', - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'system_phpappendopenbasedir' => array( 'label' => $lng['serversettings']['phpappendopenbasedir'], 'settinggroup' => 'system', @@ -121,8 +231,8 @@ return array( 'type' => 'string', 'string_emptyallowed' => true, 'default' => '', - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'system_deactivateddocroot' => array( 'label' => $lng['serversettings']['deactivateddocroot'], 'settinggroup' => 'system', @@ -131,24 +241,53 @@ return array( 'string_type' => 'dir', 'string_emptyallowed' => true, 'default' => '', - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'system_default_vhostconf' => array( 'label' => $lng['serversettings']['default_vhostconf'], 'settinggroup' => 'system', 'varname' => 'default_vhostconf', 'type' => 'text', 'default' => '', + 'save_method' => 'storeSettingField' + ), + 'system_default_sslvhostconf' => array( + 'label' => $lng['serversettings']['default_sslvhostconf'], + 'settinggroup' => 'system', + 'varname' => 'default_sslvhostconf', + 'type' => 'text', + 'default' => '', 'save_method' => 'storeSettingField', - ), + 'visible' => \Froxlor\Settings::Get('system.use_ssl') == 1 + ), + 'system_include_default_vhostconf' => array( + 'label' => $lng['serversettings']['includedefault_sslvhostconf'], + 'settinggroup' => 'system', + 'varname' => 'include_default_vhostconf', + 'type' => 'bool', + 'default' => false, + 'save_method' => 'storeSettingField' + ), + 'system_apache_globaldiropt' => array( + 'label' => $lng['serversettings']['apache_globaldiropt'], + 'settinggroup' => 'system', + 'varname' => 'apacheglobaldiropt', + 'type' => 'text', + 'default' => '', + 'save_method' => 'storeSettingField', + 'visible' => (\Froxlor\Settings::Get('system.mod_fcgid') == 0 && \Froxlor\Settings::Get('phpfpm.enabled') == 0), + 'websrv_avail' => array( + 'apache2' + ) + ), 'system_apachereload_command' => array( 'label' => $lng['serversettings']['apachereload_command'], 'settinggroup' => 'system', 'varname' => 'apachereload_command', 'type' => 'string', 'default' => '/etc/init.d/apache2 reload', - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'system_phpreload_command' => array( 'label' => $lng['serversettings']['phpreload_command'], 'settinggroup' => 'system', @@ -156,8 +295,10 @@ return array( 'type' => 'string', 'default' => '', 'save_method' => 'storeSettingField', - 'websrv_avail' => array('nginx') - ), + 'websrv_avail' => array( + 'nginx' + ) + ), 'system_nginx_php_backend' => array( 'label' => $lng['serversettings']['nginx_php_backend'], 'settinggroup' => 'system', @@ -165,8 +306,10 @@ return array( 'type' => 'string', 'default' => '127.0.0.1:8888', 'save_method' => 'storeSettingField', - 'websrv_avail' => array('nginx') - ), + 'websrv_avail' => array( + 'nginx' + ) + ), 'nginx_fastcgiparams' => array( 'label' => $lng['serversettings']['nginx_fastcgiparams'], 'settinggroup' => 'nginx', @@ -175,16 +318,18 @@ return array( 'string_type' => 'file', 'default' => '/etc/nginx/fastcgi_params', 'save_method' => 'storeSettingField', - 'websrv_avail' => array('nginx') - ), + 'websrv_avail' => array( + 'nginx' + ) + ), 'defaultwebsrverrhandler_enabled' => array( 'label' => $lng['serversettings']['defaultwebsrverrhandler_enabled'], 'settinggroup' => 'defaultwebsrverrhandler', 'varname' => 'enabled', 'type' => 'bool', 'default' => false, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'defaultwebsrverrhandler_err401' => array( 'label' => $lng['serversettings']['defaultwebsrverrhandler_err401'], 'settinggroup' => 'defaultwebsrverrhandler', @@ -192,8 +337,11 @@ return array( 'type' => 'string', 'default' => '', 'save_method' => 'storeSettingField', - 'websrv_avail' => array('apache2', 'nginx') - ), + 'websrv_avail' => array( + 'apache2', + 'nginx' + ) + ), 'defaultwebsrverrhandler_err403' => array( 'label' => $lng['serversettings']['defaultwebsrverrhandler_err403'], 'settinggroup' => 'defaultwebsrverrhandler', @@ -201,16 +349,19 @@ return array( 'type' => 'string', 'default' => '', 'save_method' => 'storeSettingField', - 'websrv_avail' => array('apache2', 'nginx') - ), + 'websrv_avail' => array( + 'apache2', + 'nginx' + ) + ), 'defaultwebsrverrhandler_err404' => array( 'label' => $lng['serversettings']['defaultwebsrverrhandler_err404'], 'settinggroup' => 'defaultwebsrverrhandler', 'varname' => 'err404', 'type' => 'string', 'default' => '', - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'defaultwebsrverrhandler_err500' => array( 'label' => $lng['serversettings']['defaultwebsrverrhandler_err500'], 'settinggroup' => 'defaultwebsrverrhandler', @@ -218,17 +369,19 @@ return array( 'type' => 'string', 'default' => '', 'save_method' => 'storeSettingField', - 'websrv_avail' => array('apache2', 'nginx') - ), + 'websrv_avail' => array( + 'apache2', + 'nginx' + ) + ), 'customredirect_enabled' => array( 'label' => $lng['serversettings']['customredirect_enabled'], 'settinggroup' => 'customredirect', 'varname' => 'enabled', 'type' => 'bool', 'default' => false, - 'save_method' => 'storeSettingField', - 'websrv_avail' => array('apache2', 'lighttpd') - ), + 'save_method' => 'storeSettingField' + ), 'customredirect_default' => array( 'label' => $lng['serversettings']['customredirect_default'], 'settinggroup' => 'customredirect', @@ -236,11 +389,10 @@ return array( 'type' => 'option', 'default' => '1', 'option_mode' => 'one', - 'option_options_method' => 'getRedirectCodes', - 'save_method' => 'storeSettingField', - 'websrv_avail' => array('apache2', 'lighttpd') - ) + 'option_options_method' => array('\\Froxlor\\Domain\\Domain', 'getRedirectCodes'), + 'save_method' => 'storeSettingField' ) ) ) - ); + ) +); diff --git a/actions/admin/settings/131.ssl.php b/actions/admin/settings/131.ssl.php index 92077c01..973dbf2b 100644 --- a/actions/admin/settings/131.ssl.php +++ b/actions/admin/settings/131.ssl.php @@ -13,137 +13,215 @@ * @author Florian Lippert (2003-2009) * @author Froxlor team (2010-) * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt - * @package Settings + * @package \Froxlor\Settings * */ - return array( 'groups' => array( - 'ssl' => array( - 'title' => $lng['admin']['sslsettings'], - 'fields' => array( - 'system_ssl_enabled' => array( - 'label' => $lng['serversettings']['ssl']['use_ssl'], - 'settinggroup' => 'system', - 'varname' => 'use_ssl', - 'type' => 'bool', - 'default' => false, - 'save_method' => 'storeSettingField', - 'overview_option' => true - ), - 'system_ssl_cipher_list' => array( - 'label' => $lng['serversettings']['ssl']['ssl_cipher_list'], - 'settinggroup' => 'system', - 'varname' => 'ssl_cipher_list', - 'type' => 'string', - 'string_emptyallowed' => false, - 'default' => 'ECDH+AESGCM:ECDH+AES256:!aNULL:!MD5:!DSS:!DH:!AES128', - 'save_method' => 'storeSettingField', - ), - 'system_ssl_cert_file' => array( - 'label' => $lng['serversettings']['ssl']['ssl_cert_file'], - 'settinggroup' => 'system', - 'varname' => 'ssl_cert_file', - 'type' => 'string', - 'string_type' => 'file', - 'string_emptyallowed' => true, - 'default' => '/etc/apache2/apache2.pem', - 'save_method' => 'storeSettingField', - ), - 'system_ssl_key_file' => array( - 'label' => $lng['serversettings']['ssl']['ssl_key_file'], - 'settinggroup' => 'system', - 'varname' => 'ssl_key_file', - 'type' => 'string', - 'string_type' => 'file', - 'string_emptyallowed' => true, - 'default' => '/etc/apache2/apache2.key', - 'save_method' => 'storeSettingField', - ), - 'system_ssl_cert_chainfile' => array( - 'label' => $lng['admin']['ipsandports']['ssl_cert_chainfile'], - 'settinggroup' => 'system', - 'varname' => 'ssl_cert_chainfile', - 'type' => 'string', - 'string_type' => 'file', - 'string_emptyallowed' => true, - 'default' => '', - 'save_method' => 'storeSettingField', - ), - 'system_ssl_ca_file' => array( - 'label' => $lng['serversettings']['ssl']['ssl_ca_file'], - 'settinggroup' => 'system', - 'varname' => 'ssl_ca_file', - 'type' => 'string', - 'string_type' => 'file', - 'string_emptyallowed' => true, - 'default' => '', - 'save_method' => 'storeSettingField', - ), - 'system_leenabled' => array( - 'label' => $lng['serversettings']['leenabled'], - 'settinggroup' => 'system', - 'varname' => 'leenabled', - 'type' => 'bool', - 'default' => false, - 'cronmodule' => 'froxlor/letsencrypt', - 'save_method' => 'storeSettingField' - ), - 'system_letsencryptca' => array( - 'label' => $lng['serversettings']['letsencryptca'], - 'settinggroup' => 'system', - 'varname' => 'letsencryptca', - 'type' => 'option', - 'default' => 'testing', - 'option_mode' => 'one', - 'option_options' => array('testing' => 'https://acme-staging.api.letsencrypt.org (Test)', 'production' => 'https://acme-v01.api.letsencrypt.org (Live)'), - 'save_method' => 'storeSettingField', - ), - 'system_letsencryptcountrycode' => array( - 'label' => $lng['serversettings']['letsencryptcountrycode'], - 'settinggroup' => 'system', - 'varname' => 'letsencryptcountrycode', - 'type' => 'string', - 'string_emptyallowed' => false, - 'default' => 'DE', - 'save_method' => 'storeSettingField', - ), - 'system_letsencryptstate' => array( - 'label' => $lng['serversettings']['letsencryptstate'], - 'settinggroup' => 'system', - 'varname' => 'letsencryptstate', - 'type' => 'string', - 'string_emptyallowed' => false, - 'default' => 'Germany', - 'save_method' => 'storeSettingField', - ), - 'system_letsencryptchallengepath' => array( - 'label' => $lng['serversettings']['letsencryptchallengepath'], - 'settinggroup' => 'system', - 'varname' => 'letsencryptchallengepath', - 'type' => 'string', - 'string_emptyallowed' => false, - 'default' => FROXLOR_INSTALL_DIR, - 'save_method' => 'storeSettingField', - ), - 'system_letsencryptkeysize' => array( - 'label' => $lng['serversettings']['letsencryptkeysize'], - 'settinggroup' => 'system', - 'varname' => 'letsencryptkeysize', - 'type' => 'int', - 'int_min' => 2048, - 'default' => 4096, - 'save_method' => 'storeSettingField', - ), - 'system_letsencryptreuseold' => array( - 'label' => $lng['serversettings']['letsencryptreuseold'], - 'settinggroup' => 'system', - 'varname' => 'letsencryptreuseold', - 'type' => 'bool', - 'default' => false, - 'save_method' => 'storeSettingField', - ), - ) + 'ssl' => array( + 'title' => $lng['admin']['sslsettings'], + 'fields' => array( + 'system_ssl_enabled' => array( + 'label' => $lng['serversettings']['ssl']['use_ssl'], + 'settinggroup' => 'system', + 'varname' => 'use_ssl', + 'type' => 'bool', + 'default' => false, + 'save_method' => 'storeSettingField', + 'overview_option' => true + ), + 'system_ssl_protocols' => array( + 'label' => $lng['serversettings']['ssl']['ssl_protocols'], + 'settinggroup' => 'system', + 'varname' => 'ssl_protocols', + 'type' => 'option', + 'default' => 'TLSv1.2', + 'option_mode' => 'multiple', + 'option_options' => array( + 'TLSv1' => 'TLSv1', + 'TLSv1.1' => 'TLSv1.1', + 'TLSv1.2' => 'TLSv1.2', + 'TLSv1.3' => 'TLSv1.3' + ), + 'save_method' => 'storeSettingField' + ), + 'system_ssl_cipher_list' => array( + 'label' => $lng['serversettings']['ssl']['ssl_cipher_list'], + 'settinggroup' => 'system', + 'varname' => 'ssl_cipher_list', + 'type' => 'string', + 'string_emptyallowed' => false, + 'default' => 'ECDH+AESGCM:ECDH+AES256:!aNULL:!MD5:!DSS:!DH:!AES128', + 'save_method' => 'storeSettingField' + ), + 'system_tlsv13_cipher_list' => array( + 'label' => $lng['serversettings']['ssl']['tlsv13_cipher_list'], + 'settinggroup' => 'system', + 'varname' => 'tlsv13_cipher_list', + 'type' => 'string', + 'string_emptyallowed' => true, + 'default' => '', + 'visible' => \Froxlor\Settings::Get('system.webserver') == "apache2" && \Froxlor\Settings::Get('system.apache24') == 1, + 'save_method' => 'storeSettingField' + ), + 'system_ssl_cert_file' => array( + 'label' => $lng['serversettings']['ssl']['ssl_cert_file'], + 'settinggroup' => 'system', + 'varname' => 'ssl_cert_file', + 'type' => 'string', + 'string_type' => 'file', + 'string_emptyallowed' => true, + 'default' => '/etc/apache2/apache2.pem', + 'save_method' => 'storeSettingField' + ), + 'system_ssl_key_file' => array( + 'label' => $lng['serversettings']['ssl']['ssl_key_file'], + 'settinggroup' => 'system', + 'varname' => 'ssl_key_file', + 'type' => 'string', + 'string_type' => 'file', + 'string_emptyallowed' => true, + 'default' => '/etc/apache2/apache2.key', + 'save_method' => 'storeSettingField' + ), + 'system_ssl_cert_chainfile' => array( + 'label' => $lng['admin']['ipsandports']['ssl_cert_chainfile'], + 'settinggroup' => 'system', + 'varname' => 'ssl_cert_chainfile', + 'type' => 'string', + 'string_type' => 'file', + 'string_emptyallowed' => true, + 'default' => '', + 'save_method' => 'storeSettingField' + ), + 'system_ssl_ca_file' => array( + 'label' => $lng['serversettings']['ssl']['ssl_ca_file'], + 'settinggroup' => 'system', + 'varname' => 'ssl_ca_file', + 'type' => 'string', + 'string_type' => 'file', + 'string_emptyallowed' => true, + 'default' => '', + 'save_method' => 'storeSettingField' + ), + 'system_apache24_ocsp_cache_path' => array( + 'label' => $lng['serversettings']['ssl']['apache24_ocsp_cache_path'], + 'settinggroup' => 'system', + 'varname' => 'apache24_ocsp_cache_path', + 'type' => 'string', + 'string_type' => 'string', + 'string_emptyallowed' => false, + 'default' => 'shmcb:/var/run/apache2/ocsp-stapling.cache(131072)', + 'visible' => \Froxlor\Settings::Get('system.webserver') == "apache2" && \Froxlor\Settings::Get('system.apache24') == 1, + 'save_method' => 'storeSettingField' + ), + 'system_sessionticketsenabled' => array( + 'label' => $lng['admin']['domain_sessionticketsenabled'], + 'settinggroup' => 'system', + 'varname' => 'sessionticketsenabled', + '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)) + ), + 'system_leenabled' => array( + 'label' => $lng['serversettings']['leenabled'], + 'settinggroup' => 'system', + 'varname' => 'leenabled', + 'type' => 'bool', + 'default' => false, + 'cronmodule' => 'froxlor/letsencrypt', + 'save_method' => 'storeSettingField' + ), + 'system_letsencryptacmeconf' => array( + 'label' => $lng['serversettings']['letsencryptacmeconf'], + 'settinggroup' => 'system', + 'varname' => 'letsencryptacmeconf', + 'type' => 'string', + 'string_type' => 'file', + 'default' => '/etc/apache2/conf-enabled/acme.conf', + 'save_method' => 'storeSettingField' + ), + 'system_leapiversion' => array( + 'label' => $lng['serversettings']['leapiversion'], + 'settinggroup' => 'system', + 'varname' => 'leapiversion', + 'type' => 'option', + 'default' => '2', + 'option_mode' => 'one', + 'option_options' => array( + '2' => 'ACME v2' + ), + 'save_method' => 'storeSettingField' + ), + 'system_letsencryptca' => array( + 'label' => $lng['serversettings']['letsencryptca'], + 'settinggroup' => 'system', + 'varname' => 'letsencryptca', + 'type' => 'option', + 'default' => 'production', + '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)' + ), + 'save_method' => 'storeSettingField' + ), + 'system_letsencryptchallengepath' => array( + 'label' => $lng['serversettings']['letsencryptchallengepath'], + 'settinggroup' => 'system', + 'varname' => 'letsencryptchallengepath', + 'type' => 'string', + 'string_emptyallowed' => false, + 'default' => \Froxlor\Froxlor::getInstallDir(), + 'save_method' => 'storeSettingField' + ), + 'system_letsencryptkeysize' => array( + 'label' => $lng['serversettings']['letsencryptkeysize'], + 'settinggroup' => 'system', + 'varname' => 'letsencryptkeysize', + 'type' => 'option', + 'default' => '2048', + 'option_mode' => 'one', + 'option_options' => array( + '2048' => '2048', + '3072' => '3072', + '4096' => '4096', + '8192' => '8192' + ), + 'save_method' => 'storeSettingField' + ), + 'system_leecc' => array( + 'label' => $lng['serversettings']['letsencryptecc'], + 'settinggroup' => 'system', + 'varname' => 'leecc', + 'type' => 'option', + 'default' => '0', + 'option_mode' => 'one', + 'option_options' => array( + '0' => '-', + '256' => 'ec-256', + '384' => 'ec-384' + ), + 'save_method' => 'storeSettingField' + ), + 'system_letsencryptreuseold' => array( + 'label' => $lng['serversettings']['letsencryptreuseold'], + 'settinggroup' => 'system', + 'varname' => 'letsencryptreuseold', + 'type' => 'bool', + 'default' => true, + 'save_method' => 'storeSettingField' + ), + 'system_disable_le_selfcheck' => array( + 'label' => $lng['serversettings']['le_domain_dnscheck'], + 'settinggroup' => 'system', + 'varname' => 'le_domain_dnscheck', + 'type' => 'bool', + 'default' => true, + 'save_method' => 'storeSettingField' + ) ) ) - ); + ) +); diff --git a/actions/admin/settings/135.fcgid.php b/actions/admin/settings/135.fcgid.php index 847ccdd5..e3f289e2 100644 --- a/actions/admin/settings/135.fcgid.php +++ b/actions/admin/settings/135.fcgid.php @@ -14,12 +14,14 @@ * @package Settings * */ - return array( 'groups' => array( 'fcgid' => array( 'title' => $lng['admin']['fcgid_settings'], - 'websrv_avail' => array('apache2', 'lighttpd'), + 'websrv_avail' => array( + 'apache2', + 'lighttpd' + ), 'fields' => array( 'system_mod_fcgid_enabled' => array( 'label' => $lng['serversettings']['mod_fcgid'], @@ -28,9 +30,12 @@ return array( 'type' => 'bool', 'default' => false, 'save_method' => 'storeSettingField', - 'plausibility_check_method' => 'checkFcgidPhpFpm', - 'overview_option' => true + 'plausibility_check_method' => array( + '\\Froxlor\\Validate\\Check', + 'checkFcgidPhpFpm' ), + 'overview_option' => true + ), 'system_mod_fcgid_configdir' => array( 'label' => $lng['serversettings']['mod_fcgid']['configdir'], 'settinggroup' => 'system', @@ -38,9 +43,12 @@ return array( 'type' => 'string', 'string_type' => 'confdir', 'default' => '/var/www/php-fcgi-scripts/', - 'plausibility_check_method' => 'checkPathConflicts', - 'save_method' => 'storeSettingField', + 'plausibility_check_method' => array( + '\\Froxlor\\Validate\\Check', + 'checkPathConflicts' ), + 'save_method' => 'storeSettingField' + ), 'system_mod_fcgid_tmpdir' => array( 'label' => $lng['serversettings']['mod_fcgid']['tmpdir'], 'settinggroup' => 'system', @@ -48,8 +56,8 @@ return array( 'type' => 'string', 'string_type' => 'dir', 'default' => '/var/customers/tmp/', - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'system_mod_fcgid_peardir' => array( 'label' => $lng['serversettings']['mod_fcgid']['peardir'], 'settinggroup' => 'system', @@ -59,34 +67,39 @@ return array( 'string_delimiter' => ':', 'string_emptyallowed' => true, 'default' => '/usr/share/php/:/usr/share/php5/', - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'system_mod_fcgid_wrapper' => array( 'label' => $lng['serversettings']['mod_fcgid']['wrapper'], 'settinggroup' => 'system', 'varname' => 'mod_fcgid_wrapper', 'type' => 'option', - 'option_options' => array(0 => 'ScriptAlias', 1=> 'FcgidWrapper'), + 'option_options' => array( + 0 => 'ScriptAlias', + 1 => 'FcgidWrapper' + ), 'default' => 1, 'save_method' => 'storeSettingField', - 'websrv_avail' => array('apache2') - ), + 'websrv_avail' => array( + 'apache2' + ) + ), 'system_mod_fcgid_starter' => array( 'label' => $lng['serversettings']['mod_fcgid']['starter'], 'settinggroup' => 'system', 'varname' => 'mod_fcgid_starter', 'type' => 'int', 'default' => 0, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'system_mod_fcgid_maxrequests' => array( 'label' => $lng['serversettings']['mod_fcgid']['maxrequests'], 'settinggroup' => 'system', 'varname' => 'mod_fcgid_maxrequests', 'type' => 'int', 'default' => 250, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'system_mod_fcgid_defaultini' => array( 'label' => $lng['serversettings']['mod_fcgid']['defaultini'], 'settinggroup' => 'system', @@ -94,47 +107,11 @@ return array( 'type' => 'option', 'default' => '1', 'option_mode' => 'one', - 'option_options_method' => 'getPhpConfigs', - 'save_method' => 'storeSettingField', - ), - 'system_mod_fcgid_enabled_ownvhost' => array( - 'label' => $lng['serversettings']['mod_fcgid_ownvhost'], - 'settinggroup' => 'system', - 'varname' => 'mod_fcgid_ownvhost', - 'type' => 'bool', - 'default' => false, - 'save_method' => 'storeSettingField', - 'websrv_avail' => array('apache2') - ), - 'system_mod_fcgid_httpuser' => array( - 'label' => $lng['admin']['mod_fcgid_user'], - 'settinggroup' => 'system', - 'varname' => 'mod_fcgid_httpuser', - 'type' => 'string', - 'default' => 'froxlorlocal', - 'save_method' => 'storeSettingWebserverFcgidFpmUser', - 'websrv_avail' => array('apache2') - ), - 'system_mod_fcgid_httpgroup' => array( - 'label' => $lng['admin']['mod_fcgid_group'], - 'settinggroup' => 'system', - 'varname' => 'mod_fcgid_httpgroup', - 'type' => 'string', - 'default' => 'froxlorlocal', - 'save_method' => 'storeSettingField', - 'websrv_avail' => array('apache2') - ), - 'system_mod_fcgid_defaultini_ownvhost' => array( - 'label' => $lng['serversettings']['mod_fcgid']['defaultini_ownvhost'], - 'settinggroup' => 'system', - 'varname' => 'mod_fcgid_defaultini_ownvhost', - 'type' => 'option', - 'default' => '2', - 'option_mode' => 'one', - 'option_options_method' => 'getPhpConfigs', - 'save_method' => 'storeSettingField', - 'websrv_avail' => array('apache2') - ), + 'option_options_method' => array( + '\\Froxlor\\Http\\PhpConfig', + 'getPhpConfigs'), + 'save_method' => 'storeSettingField' + ), 'system_mod_fcgid_idle_timeout' => array( 'label' => $lng['serversettings']['mod_fcgid']['idle_timeout'], 'settinggroup' => 'system', @@ -142,10 +119,10 @@ return array( 'type' => 'int', 'default' => 30, 'save_method' => 'storeSettingField' - ), ) ) ) - ); + ) +); ?> diff --git a/actions/admin/settings/136.phpfpm.php b/actions/admin/settings/136.phpfpm.php index 914da31c..eca70ba4 100644 --- a/actions/admin/settings/136.phpfpm.php +++ b/actions/admin/settings/136.phpfpm.php @@ -1,59 +1,37 @@ - (2010-) - * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt - * @package Settings - * - */ - -return array( - 'groups' => array( - 'phpfpm' => array( - 'title' => $lng['admin']['phpfpm_settings'], - 'fields' => array( - 'system_phpfpm_enabled' => array( - 'label' => $lng['serversettings']['phpfpm'], - 'settinggroup' => 'phpfpm', - 'varname' => 'enabled', - 'type' => 'bool', - 'default' => false, - 'save_method' => 'storeSettingField', - 'plausibility_check_method' => 'checkFcgidPhpFpm', - 'overview_option' => true - ), - 'system_phpfpm_enabled_ownvhost' => array( - 'label' => $lng['phpfpm']['ownvhost'], - 'settinggroup' => 'phpfpm', - 'varname' => 'enabled_ownvhost', - 'type' => 'bool', - 'default' => false, - 'save_method' => 'storeSettingField' - ), - 'system_phpfpm_httpuser' => array( - 'label' => $lng['phpfpm']['vhost_httpuser'], - 'settinggroup' => 'phpfpm', - 'varname' => 'vhost_httpuser', - 'type' => 'string', - 'default' => 'froxlorlocal', - 'save_method' => 'storeSettingWebserverFcgidFpmUser' - ), - 'system_phpfpm_httpgroup' => array( - 'label' => $lng['phpfpm']['vhost_httpgroup'], - 'settinggroup' => 'phpfpm', - 'varname' => 'vhost_httpgroup', - 'type' => 'string', - 'default' => 'froxlorlocal', - 'save_method' => 'storeSettingField' - ), + (2010-) + * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt + * @package \Froxlor\Settings + * + */ +return array( + 'groups' => array( + 'phpfpm' => array( + 'title' => $lng['admin']['phpfpm_settings'], + 'fields' => array( + 'system_phpfpm_enabled' => array( + 'label' => $lng['serversettings']['phpfpm'], + 'settinggroup' => 'phpfpm', + 'varname' => 'enabled', + 'type' => 'bool', + 'default' => false, + 'save_method' => 'storeSettingField', + 'plausibility_check_method' => array( + '\\Froxlor\\Validate\\Check', + 'checkFcgidPhpFpm' + ), + 'overview_option' => true + ), 'system_phpfpm_defaultini' => array( 'label' => $lng['serversettings']['mod_fcgid']['defaultini'], 'settinggroup' => 'phpfpm', @@ -61,140 +39,103 @@ return array( 'type' => 'option', 'default' => '1', 'option_mode' => 'one', - 'option_options_method' => 'getPhpConfigs', + 'option_options_method' => array( + '\\Froxlor\\Http\\PhpConfig', + 'getPhpConfigs' + ), 'save_method' => 'storeSettingField' - ), - 'system_phpfpm_defaultini_ownvhost' => array( - 'label' => $lng['serversettings']['mod_fcgid']['defaultini_ownvhost'], - 'settinggroup' => 'phpfpm', - 'varname' => 'vhost_defaultini', - 'type' => 'option', - 'default' => '2', - 'option_mode' => 'one', - 'option_options_method' => 'getPhpConfigs', - 'save_method' => 'storeSettingField' - ), - 'system_phpfpm_configdir' => array( - 'label' => $lng['serversettings']['phpfpm_settings']['configdir'], - 'settinggroup' => 'phpfpm', - 'varname' => 'configdir', - 'type' => 'string', - 'string_type' => 'confdir', - 'default' => '/etc/php-fpm.d/', - 'save_method' => 'storeSettingField' - ), - 'system_phpfpm_aliasconfigdir' => array( - 'label' => $lng['serversettings']['phpfpm_settings']['aliasconfigdir'], - 'settinggroup' => 'phpfpm', - 'varname' => 'aliasconfigdir', - 'type' => 'string', - 'string_type' => 'confdir', - 'default' => '/var/www/php-fpm/', - 'save_method' => 'storeSettingField' - ), - 'system_phpfpm_tmpdir' => array( - 'label' => $lng['serversettings']['mod_fcgid']['tmpdir'], - 'settinggroup' => 'phpfpm', - 'varname' => 'tmpdir', - 'type' => 'string', - 'string_type' => 'dir', - 'default' => '/var/customers/tmp/', - 'save_method' => 'storeSettingField' - ), - 'system_phpfpm_peardir' => array( - 'label' => $lng['serversettings']['mod_fcgid']['peardir'], - 'settinggroup' => 'phpfpm', - 'varname' => 'peardir', - 'type' => 'string', - 'string_type' => 'dir', - 'default' => '/usr/share/php/:/usr/share/php5/', - 'save_method' => 'storeSettingField' - ), - 'system_phpfpm_fastcgi_ipcdir' => array( - 'label' => $lng['serversettings']['phpfpm_settings']['ipcdir'], - 'settinggroup' => 'phpfpm', - 'varname' => 'fastcgi_ipcdir', - 'type' => 'string', - 'string_type' => 'dir', - 'default' => '/var/lib/apache2/fastcgi/', - 'save_method' => 'storeSettingField' - ), - 'system_phpfpm_reload' => array( - 'label' => $lng['serversettings']['phpfpm_settings']['reload'], - 'settinggroup' => 'phpfpm', - 'varname' => 'reload', - 'type' => 'string', - 'default' => '/etc/init.d/php-fpm restart', - 'save_method' => 'storeSettingField' - ), - 'system_phpfpm_pm' => array( - 'label' => $lng['serversettings']['phpfpm_settings']['pm'], - 'settinggroup' => 'phpfpm', - 'varname' => 'pm', - 'type' => 'option', - 'default' => 'static', - 'option_mode' => 'one', - 'option_options' => array('static' => 'static', 'dynamic' => 'dynamic', 'ondemand' => 'ondemand'), - 'save_method' => 'storeSettingField' - ), - 'system_phpfpm_max_children' => array( - 'label' => $lng['serversettings']['phpfpm_settings']['max_children'], - 'settinggroup' => 'phpfpm', - 'varname' => 'max_children', - 'type' => 'int', - 'default' => 1, - 'save_method' => 'storeSettingField' - ), - 'system_phpfpm_start_servers' => array( - 'label' => $lng['serversettings']['phpfpm_settings']['start_servers'], - 'settinggroup' => 'phpfpm', - 'varname' => 'start_servers', - 'type' => 'int', - 'default' => 20, - 'save_method' => 'storeSettingField' - ), - 'system_phpfpm_min_spare_servers' => array( - 'label' => $lng['serversettings']['phpfpm_settings']['min_spare_servers'], - 'settinggroup' => 'phpfpm', - 'varname' => 'min_spare_servers', - 'type' => 'int', - 'default' => 5, - 'save_method' => 'storeSettingField' - ), - 'system_phpfpm_max_spare_servers' => array( - 'label' => $lng['serversettings']['phpfpm_settings']['max_spare_servers'], - 'settinggroup' => 'phpfpm', - 'varname' => 'max_spare_servers', - 'type' => 'int', - 'default' => 35, - 'save_method' => 'storeSettingField' - ), - 'system_phpfpm_max_requests' => array( - 'label' => $lng['serversettings']['phpfpm_settings']['max_requests'], - 'settinggroup' => 'phpfpm', - 'varname' => 'max_requests', - 'type' => 'int', - 'default' => 0, - 'save_method' => 'storeSettingField' - ), - 'system_phpfpm_idle_timeout' => array( - 'label' => $lng['serversettings']['phpfpm_settings']['idle_timeout'], - 'settinggroup' => 'phpfpm', - 'varname' => 'idle_timeout', - 'type' => 'int', - 'default' => 30, - 'save_method' => 'storeSettingField' - ), - 'system_phpfpm_use_mod_proxy' => array( - 'label' => $lng['phpfpm']['use_mod_proxy'], - 'settinggroup' => 'phpfpm', - 'varname' => 'use_mod_proxy', - 'type' => 'bool', - 'default' => false, - 'visible' => Settings::Get('system.apache24'), - 'save_method' => 'storeSettingField' - ), - ), - ), - ), - ); + ), + 'system_phpfpm_aliasconfigdir' => array( + 'label' => $lng['serversettings']['phpfpm_settings']['aliasconfigdir'], + 'settinggroup' => 'phpfpm', + 'varname' => 'aliasconfigdir', + 'type' => 'string', + 'string_type' => 'confdir', + 'default' => '/var/www/php-fpm/', + 'save_method' => 'storeSettingField' + ), + 'system_phpfpm_tmpdir' => array( + 'label' => $lng['serversettings']['mod_fcgid']['tmpdir'], + 'settinggroup' => 'phpfpm', + 'varname' => 'tmpdir', + 'type' => 'string', + 'string_type' => 'dir', + 'default' => '/var/customers/tmp/', + 'save_method' => 'storeSettingField' + ), + 'system_phpfpm_peardir' => array( + 'label' => $lng['serversettings']['mod_fcgid']['peardir'], + 'settinggroup' => 'phpfpm', + 'varname' => 'peardir', + 'type' => 'string', + 'string_type' => 'dir', + 'string_delimiter' => ':', + 'string_emptyallowed' => true, + 'default' => '/usr/share/php/:/usr/share/php5/', + 'save_method' => 'storeSettingField' + ), + 'system_phpfpm_envpath' => array( + 'label' => $lng['serversettings']['phpfpm_settings']['envpath'], + 'settinggroup' => 'phpfpm', + 'varname' => 'envpath', + 'type' => 'string', + 'string_type' => 'dir', + 'string_delimiter' => ':', + 'string_emptyallowed' => true, + 'default' => '/usr/local/bin:/usr/bin:/bin', + 'save_method' => 'storeSettingField' + ), + 'system_phpfpm_fastcgi_ipcdir' => array( + 'label' => $lng['serversettings']['phpfpm_settings']['ipcdir'], + 'settinggroup' => 'phpfpm', + 'varname' => 'fastcgi_ipcdir', + 'type' => 'string', + 'string_type' => 'dir', + 'default' => '/var/lib/apache2/fastcgi/', + 'save_method' => 'storeSettingField' + ), + 'system_phpfpm_use_mod_proxy' => array( + 'label' => $lng['phpfpm']['use_mod_proxy'], + 'settinggroup' => 'phpfpm', + 'varname' => 'use_mod_proxy', + 'type' => 'bool', + 'default' => true, + 'visible' => \Froxlor\Settings::Get('system.apache24'), + 'save_method' => 'storeSettingField' + ), + 'system_phpfpm_ini_flags' => array( + 'label' => $lng['phpfpm']['ini_flags'], + 'settinggroup' => 'phpfpm', + 'varname' => 'ini_flags', + 'type' => 'text', + 'default' => '', + 'save_method' => 'storeSettingField' + ), + 'system_phpfpm_ini_values' => array( + 'label' => $lng['phpfpm']['ini_values'], + 'settinggroup' => 'phpfpm', + 'varname' => 'ini_values', + 'type' => 'text', + 'default' => '', + 'save_method' => 'storeSettingField' + ), + 'system_phpfpm_ini_admin_flags' => array( + 'label' => $lng['phpfpm']['ini_admin_flags'], + 'settinggroup' => 'phpfpm', + 'varname' => 'ini_admin_flags', + 'type' => 'text', + 'default' => '', + 'save_method' => 'storeSettingField' + ), + 'system_phpfpm_ini_admin_values' => array( + 'label' => $lng['phpfpm']['ini_admin_values'], + 'settinggroup' => 'phpfpm', + 'varname' => 'ini_admin_values', + 'type' => 'text', + 'default' => '', + 'save_method' => 'storeSettingField' + ) + ) + ) + ) +); diff --git a/actions/admin/settings/137.perl.php b/actions/admin/settings/137.perl.php index 57681bad..9244fec2 100644 --- a/actions/admin/settings/137.perl.php +++ b/actions/admin/settings/137.perl.php @@ -14,7 +14,6 @@ * @package Settings * */ - return array( 'groups' => array( 'perl' => array( @@ -27,8 +26,10 @@ return array( 'type' => 'string', 'default' => '/usr/bin/perl', 'save_method' => 'storeSettingField', - 'websrv_avail' => array('lighttpd') - ), + 'websrv_avail' => array( + 'lighttpd' + ) + ), 'system_perl_suexecworkaround' => array( 'label' => $lng['serversettings']['perl']['suexecworkaround'], 'settinggroup' => 'perl', @@ -36,8 +37,10 @@ return array( 'type' => 'bool', 'default' => false, 'save_method' => 'storeSettingField', - 'websrv_avail' => array('apache2') - ), + 'websrv_avail' => array( + 'apache2' + ) + ), 'system_perl_suexeccgipath' => array( 'label' => $lng['serversettings']['perl']['suexeccgipath'], 'settinggroup' => 'perl', @@ -46,8 +49,10 @@ return array( 'string_type' => 'dir', 'default' => '/var/www/cgi-bin/', 'save_method' => 'storeSettingField', - 'websrv_avail' => array('apache2') - ), + 'websrv_avail' => array( + 'apache2' + ) + ), 'perl_server' => array( 'label' => $lng['serversettings']['perl_server'], 'settinggroup' => 'serversettings', @@ -55,11 +60,13 @@ return array( 'type' => 'string', 'default' => 'unix:/var/run/nginx/cgiwrap-dispatch.sock', 'save_method' => 'storeSettingField', - 'websrv_avail' => array('nginx') - ), - ), - ), - ), - ); + 'websrv_avail' => array( + 'nginx' + ) + ) + ) + ) + ) +); ?> diff --git a/actions/admin/settings/140.statistics.php b/actions/admin/settings/140.statistics.php index dbb48518..23b51a63 100644 --- a/actions/admin/settings/140.statistics.php +++ b/actions/admin/settings/140.statistics.php @@ -16,7 +16,6 @@ * @package Settings * */ - return array( 'groups' => array( 'statistics' => array( @@ -29,17 +28,22 @@ return array( 'type' => 'option', 'default' => 2, 'option_mode' => 'one', - 'option_options' => array(0 => $lng['admin']['webalizer']['normal'], 1 => $lng['admin']['webalizer']['quiet'], 2 => $lng['admin']['webalizer']['veryquiet']), - 'save_method' => 'storeSettingField', + 'option_options' => array( + 0 => $lng['admin']['webalizer']['normal'], + 1 => $lng['admin']['webalizer']['quiet'], + 2 => $lng['admin']['webalizer']['veryquiet'] ), + 'save_method' => 'storeSettingField', + 'visible' => \Froxlor\Settings::Get('system.awstats_enabled') == 0 + ), 'system_awstats_enabled' => array( 'label' => $lng['serversettings']['awstats_enabled'], 'settinggroup' => 'system', 'varname' => 'awstats_enabled', 'type' => 'bool', 'default' => false, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'system_awstats_path' => array( 'label' => $lng['serversettings']['awstats_path'], 'settinggroup' => 'system', @@ -48,7 +52,8 @@ return array( 'string_type' => 'dir', 'default' => '/usr/bin/', 'save_method' => 'storeSettingField', - ), + 'visible' => \Froxlor\Settings::Get('system.awstats_enabled') == 1 + ), 'system_awstats_awstatspath' => array( 'label' => $lng['serversettings']['awstats_awstatspath'], 'settinggroup' => 'system', @@ -57,7 +62,8 @@ return array( 'string_type' => 'dir', 'default' => '/usr/bin/', 'save_method' => 'storeSettingField', - ), + 'visible' => \Froxlor\Settings::Get('system.awstats_enabled') == 1 + ), 'system_awstats_conf' => array( 'label' => $lng['serversettings']['awstats_conf'], 'settinggroup' => 'system', @@ -66,7 +72,8 @@ return array( 'string_type' => 'dir', 'default' => '/etc/awstats/', 'save_method' => 'storeSettingField', - ), + 'visible' => \Froxlor\Settings::Get('system.awstats_enabled') == 1 + ), 'system_awstats_icons' => array( 'label' => $lng['serversettings']['awstats_icons'], 'settinggroup' => 'system', @@ -75,10 +82,20 @@ return array( 'string_type' => 'dir', 'default' => '/usr/share/awstats/icon/', 'save_method' => 'storeSettingField', - ) + 'visible' => \Froxlor\Settings::Get('system.awstats_enabled') == 1 + ), + 'system_awstats_logformat' => array( + 'label' => $lng['serversettings']['awstats']['logformat'], + 'settinggroup' => 'system', + 'varname' => 'awstats_logformat', + 'type' => 'string', + 'default' => '1', + 'save_method' => 'storeSettingField', + 'visible' => \Froxlor\Settings::Get('system.awstats_enabled') == 1 ) ) ) - ); + ) +); ?> \ No newline at end of file diff --git a/actions/admin/settings/150.mail.php b/actions/admin/settings/150.mail.php index b5ce0522..260471d2 100644 --- a/actions/admin/settings/150.mail.php +++ b/actions/admin/settings/150.mail.php @@ -16,7 +16,6 @@ * @package Settings * */ - return array( 'groups' => array( 'mail' => array( @@ -30,8 +29,8 @@ return array( 'default' => 2000, 'int_min' => 1, 'int_max' => 65535, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'system_vmail_gid' => array( 'label' => $lng['serversettings']['vmail_gid'], 'settinggroup' => 'system', @@ -40,8 +39,8 @@ return array( 'default' => 2000, 'int_min' => 1, 'int_max' => 65535, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'system_vmail_homedir' => array( 'label' => $lng['serversettings']['vmail_homedir'], 'settinggroup' => 'system', @@ -49,8 +48,8 @@ return array( 'type' => 'string', 'string_type' => 'dir', 'default' => '/var/customers/mail/', - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'system_vmail_maildirname' => array( 'label' => $lng['serversettings']['vmail_maildirname'], 'settinggroup' => 'system', @@ -59,48 +58,48 @@ return array( 'string_type' => 'dir', 'default' => 'Maildir', 'string_emptyallowed' => true, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'panel_sendalternativemail' => array( 'label' => $lng['serversettings']['sendalternativemail'], 'settinggroup' => 'panel', 'varname' => 'sendalternativemail', 'type' => 'bool', 'default' => false, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'system_mail_quota_enabled' => array( 'label' => $lng['serversettings']['mail_quota_enabled'], 'settinggroup' => 'system', 'varname' => 'mail_quota_enabled', 'type' => 'bool', 'default' => false, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'system_mail_quota' => array( 'label' => $lng['serversettings']['mail_quota'], 'settinggroup' => 'system', 'varname' => 'mail_quota', 'type' => 'int', 'default' => 100, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'system_catchall_enabled' => array( 'label' => $lng['serversettings']['catchall_enabled'], 'settinggroup' => 'catchall', 'varname' => 'catchall_enabled', 'type' => 'bool', 'default' => true, - 'save_method' => 'storeSettingResetCatchall', - ), + 'save_method' => 'storeSettingResetCatchall' + ), 'system_mailtraffic_enabled' => array( 'label' => $lng['serversettings']['mailtraffic_enabled'], 'settinggroup' => 'system', 'varname' => 'mailtraffic_enabled', 'type' => 'bool', 'default' => true, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'system_mdaserver' => array( 'label' => $lng['serversettings']['mdaserver'], 'settinggroup' => 'system', @@ -108,9 +107,12 @@ return array( 'type' => 'option', 'option_mode' => 'one', 'default' => 'dovecot', - 'option_options' => array('courier' => 'Courier', 'dovecot' => 'Dovecot'), - 'save_method' => 'storeSettingField', + 'option_options' => array( + 'courier' => 'Courier', + 'dovecot' => 'Dovecot' ), + 'save_method' => 'storeSettingField' + ), 'system_mdalog' => array( 'label' => $lng['serversettings']['mdalog'], 'settinggroup' => 'system', @@ -119,8 +121,8 @@ return array( 'string_type' => 'file', 'default' => '/var/log/mail.log', 'string_emptyallowed' => true, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'system_mtaserver' => array( 'label' => $lng['serversettings']['mtaserver'], 'settinggroup' => 'system', @@ -128,9 +130,12 @@ return array( 'type' => 'option', 'option_mode' => 'one', 'default' => 'postfix', - 'option_options' => array('exim4' => 'Exim4', 'postfix' => 'Postfix'), - 'save_method' => 'storeSettingField', + 'option_options' => array( + 'exim4' => 'Exim4', + 'postfix' => 'Postfix' ), + 'save_method' => 'storeSettingField' + ), 'system_mtalog' => array( 'label' => $lng['serversettings']['mtalog'], 'settinggroup' => 'system', @@ -139,11 +144,11 @@ return array( 'string_type' => 'file', 'default' => '/var/log/mail.log', 'string_emptyallowed' => true, - 'save_method' => 'storeSettingField', - ), - ), - ), - ), - ); + 'save_method' => 'storeSettingField' + ) + ) + ) + ) +); ?> diff --git a/actions/admin/settings/155.ftpserver.php b/actions/admin/settings/155.ftpserver.php index 8f7eab9b..e6797127 100644 --- a/actions/admin/settings/155.ftpserver.php +++ b/actions/admin/settings/155.ftpserver.php @@ -16,10 +16,9 @@ * @package Settings * */ - return array( 'groups' => array( - 'ftpserver' => array( + 'ftpserver' => array( 'title' => $lng['admin']['ftpserversettings'], 'fields' => array( 'ftpserver' => array( @@ -29,11 +28,14 @@ return array( 'type' => 'option', 'default' => 'proftpd', 'option_mode' => 'one', - 'option_options' => array('proftpd' => 'Proftpd', 'pureftpd' => 'Pureftpd'), - 'save_method' => 'storeSettingField', - ), - ), - ), + 'option_options' => array( + 'proftpd' => 'Proftpd', + 'pureftpd' => 'Pureftpd' + ), + 'save_method' => 'storeSettingField' + ) + ) + ) ) ); diff --git a/actions/admin/settings/160.nameserver.php b/actions/admin/settings/160.nameserver.php index e738c3f3..67260bfa 100644 --- a/actions/admin/settings/160.nameserver.php +++ b/actions/admin/settings/160.nameserver.php @@ -16,7 +16,6 @@ * @package Settings * */ - return array( 'groups' => array( 'nameserver' => array( @@ -30,7 +29,28 @@ return array( 'default' => true, 'save_method' => 'storeSettingField', 'overview_option' => true + ), + 'system_dnsenabled' => array( + 'label' => $lng['serversettings']['dnseditorenable'], + 'settinggroup' => 'system', + 'varname' => 'dnsenabled', + 'type' => 'bool', + 'default' => false, + 'save_method' => 'storeSettingField' + ), + 'system_dns_server' => array( + 'label' => $lng['serversettings']['dns_server'], + 'settinggroup' => 'system', + 'varname' => 'dns_server', + 'type' => 'option', + 'default' => 'Bind', + 'option_mode' => 'one', + 'option_options' => array( + 'Bind' => 'Bind9', + 'PowerDNS' => 'PowerDNS' ), + 'save_method' => 'storeSettingField' + ), 'system_bindconf_directory' => array( 'label' => $lng['serversettings']['bindconf_directory'], 'settinggroup' => 'system', @@ -38,16 +58,16 @@ return array( 'type' => 'string', 'string_type' => 'dir', 'default' => '/etc/bind/', - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'system_bindreload_command' => array( 'label' => $lng['serversettings']['bindreload_command'], 'settinggroup' => 'system', 'varname' => 'bindreload_command', 'type' => 'string', 'default' => '/etc/init.d/bind9 reload', - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'system_nameservers' => array( 'label' => $lng['serversettings']['nameservers'], 'settinggroup' => 'system', @@ -56,8 +76,8 @@ return array( 'string_regexp' => '/^(([a-z0-9\-\._]+, ?)*[a-z0-9\-\._]+)?$/i', 'string_emptyallowed' => true, 'default' => '', - 'save_method' => 'storeSettingFieldInsertBindTask', - ), + 'save_method' => 'storeSettingFieldInsertBindTask' + ), 'system_mxservers' => array( 'label' => $lng['serversettings']['mxservers'], 'settinggroup' => 'system', @@ -66,8 +86,8 @@ return array( 'string_regexp' => '/^(([0-9]+ [a-z0-9\-\._]+, ?)*[0-9]+ [a-z0-9\-\._]+)?$/i', 'string_emptyallowed' => true, 'default' => '', - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'system_axfrservers' => array( 'label' => $lng['serversettings']['axfrservers'], 'settinggroup' => 'system', @@ -77,14 +97,6 @@ return array( 'string_delimiter' => ',', 'string_emptyallowed' => true, 'default' => '', - 'save_method' => 'storeSettingField', - ), - 'system_dns_createhostnameentry' => array( - 'label' => $lng['serversettings']['dns_createhostnameentry'], - 'settinggroup' => 'system', - 'varname' => 'dns_createhostnameentry', - 'type' => 'bool', - 'default' => false, 'save_method' => 'storeSettingField' ), 'system_dns_createmailentry' => array( @@ -94,7 +106,23 @@ return array( 'type' => 'bool', 'default' => false, 'save_method' => 'storeSettingField' - ), + ), + 'system_dns_createcaaentry' => array( + 'label' => $lng['serversettings']['caa_entry'], + 'settinggroup' => 'system', + 'varname' => 'dns_createcaaentry', + 'type' => 'bool', + 'default' => true, + 'save_method' => 'storeSettingField' + ), + 'caa_caa_entry' => array( + 'label' => $lng['serversettings']['caa_entry_custom'], + 'settinggroup' => 'caa', + 'varname' => 'caa_entry', + 'type' => 'text', + 'default' => '', + 'save_method' => 'storeSettingField' + ), 'system_defaultttl' => array( 'label' => $lng['serversettings']['defaultttl'], 'settinggroup' => 'system', @@ -103,11 +131,9 @@ return array( 'default' => 604800, /* 1 week */ 'int_min' => 3600, /* 1 hour */ 'int_max' => 2147483647, /* integer max */ - 'save_method' => 'storeSettingField', - ), - ), - ), - ), - ); - -?> \ No newline at end of file + 'save_method' => 'storeSettingField' + ) + ) + ) + ) +); diff --git a/actions/admin/settings/170.logger.php b/actions/admin/settings/170.logger.php index 2b0e730d..023a5ce3 100644 --- a/actions/admin/settings/170.logger.php +++ b/actions/admin/settings/170.logger.php @@ -16,7 +16,6 @@ * @package Settings * */ - return array( 'groups' => array( 'logging' => array( @@ -30,7 +29,7 @@ return array( 'default' => false, 'save_method' => 'storeSettingField', 'overview_option' => true - ), + ), 'logger_severity' => array( 'label' => $lng['serversettings']['logger']['severity'], 'settinggroup' => 'logger', @@ -38,9 +37,12 @@ return array( 'type' => 'option', 'default' => 1, 'option_mode' => 'one', - 'option_options' => array(1 => $lng['admin']['logger']['normal'], 2 => $lng['admin']['logger']['paranoid']), - 'save_method' => 'storeSettingField', + 'option_options' => array( + 1 => $lng['admin']['logger']['normal'], + 2 => $lng['admin']['logger']['paranoid'] ), + 'save_method' => 'storeSettingField' + ), 'logger_logtypes' => array( 'label' => $lng['serversettings']['logger']['types'], 'settinggroup' => 'logger', @@ -48,9 +50,13 @@ return array( 'type' => 'option', 'default' => 'syslog,mysql', 'option_mode' => 'multiple', - 'option_options' => array('syslog' => 'syslog', 'file' => 'file', 'mysql' => 'mysql'), - 'save_method' => 'storeSettingField', + 'option_options' => array( + 'syslog' => 'syslog', + 'file' => 'file', + 'mysql' => 'mysql' ), + 'save_method' => 'storeSettingField' + ), 'logger_logfile' => array( 'label' => $lng['serversettings']['logger']['logfile'], 'settinggroup' => 'logger', @@ -59,8 +65,8 @@ return array( 'string_type' => 'file', 'string_emptyallowed' => true, 'default' => '', - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'logger_log_cron' => array( 'label' => $lng['serversettings']['logger']['logcron'], 'settinggroup' => 'logger', @@ -69,15 +75,15 @@ return array( 'default' => 0, 'option_mode' => 'one', 'option_options' => array( - 0 => $lng['serversettings']['logger']['logcronoption']['never'], - 1 => $lng['serversettings']['logger']['logcronoption']['once'], - 2 => $lng['serversettings']['logger']['logcronoption']['always'] - ), - 'save_method' => 'storeSettingField', + 0 => $lng['serversettings']['logger']['logcronoption']['never'], + 1 => $lng['serversettings']['logger']['logcronoption']['once'], + 2 => $lng['serversettings']['logger']['logcronoption']['always'] ), - ), - ), + 'save_method' => 'storeSettingField' + ) + ) ) - ); + ) +); ?> diff --git a/actions/admin/settings/180.dkim.php b/actions/admin/settings/180.dkim.php index 79b2879e..36625d16 100644 --- a/actions/admin/settings/180.dkim.php +++ b/actions/admin/settings/180.dkim.php @@ -13,10 +13,9 @@ * @author Florian Lippert (2003-2009) * @author Froxlor team (2010-) * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt - * @package Settings + * @package \Froxlor\Settings * */ - return array( 'groups' => array( 'dkim' => array( @@ -30,7 +29,7 @@ return array( 'default' => false, 'save_method' => 'storeSettingFieldInsertBindTask', 'overview_option' => true - ), + ), 'dkim_prefix' => array( 'label' => $lng['dkim']['dkim_prefix'], 'settinggroup' => 'dkim', @@ -38,8 +37,8 @@ return array( 'type' => 'string', 'string_type' => 'dir', 'default' => '/etc/postfix/dkim/', - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'dkim_domains' => array( 'label' => $lng['dkim']['dkim_domains'], 'settinggroup' => 'dkim', @@ -47,8 +46,8 @@ return array( 'type' => 'string', 'string_regexp' => '/^[a-z0-9\._]+$/i', 'default' => 'domains', - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'dkim_dkimkeys' => array( 'label' => $lng['dkim']['dkim_dkimkeys'], 'settinggroup' => 'dkim', @@ -56,8 +55,8 @@ return array( 'type' => 'string', 'string_regexp' => '/^[a-z0-9\._]+$/i', 'default' => 'dkim-keys.conf', - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'dkim_algorithm' => array( 'label' => $lng['dkim']['dkim_algorithm'], 'settinggroup' => 'dkim', @@ -65,9 +64,13 @@ return array( 'type' => 'option', 'default' => 'all', 'option_mode' => 'multiple', - 'option_options' => array('all' => 'All', 'sha1' => 'SHA1', 'sha256' => 'SHA256'), - 'save_method' => 'storeSettingFieldInsertBindTask', + 'option_options' => array( + 'all' => 'All', + 'sha1' => 'SHA1', + 'sha256' => 'SHA256' ), + 'save_method' => 'storeSettingFieldInsertBindTask' + ), 'dkim_servicetype' => array( 'label' => $lng['dkim']['dkim_servicetype'], 'settinggroup' => 'dkim', @@ -75,22 +78,28 @@ return array( 'type' => 'option', 'default' => '0', 'option_mode' => 'one', - 'option_options' => array('0' => 'All', '1' => 'E-Mail'), - 'save_method' => 'storeSettingFieldInsertBindTask', + 'option_options' => array( + '0' => 'All', + '1' => 'E-Mail' ), + 'save_method' => 'storeSettingFieldInsertBindTask' + ), 'dkim_keylength' => array( 'label' => array( 'title' => $lng['dkim']['dkim_keylength']['title'], - 'description' => sprintf($lng['dkim']['dkim_keylength']['description'], Settings::Get('dkim.dkim_prefix')) + 'description' => sprintf($lng['dkim']['dkim_keylength']['description'], \Froxlor\Settings::Get('dkim.dkim_prefix')) ), 'settinggroup' => 'dkim', 'varname' => 'dkim_keylength', 'type' => 'option', 'default' => '1024', 'option_mode' => 'one', - 'option_options' => array('1024' => '1024 Bit', '2048' => '2048 Bit'), - 'save_method' => 'storeSettingFieldInsertBindTask', + 'option_options' => array( + '1024' => '1024 Bit', + '2048' => '2048 Bit' ), + 'save_method' => 'storeSettingFieldInsertBindTask' + ), 'dkim_notes' => array( 'label' => $lng['dkim']['dkim_notes'], 'settinggroup' => 'dkim', @@ -98,37 +107,19 @@ return array( 'type' => 'string', 'string_regexp' => '/^[a-z0-9\._]+$/i', 'default' => '', - 'save_method' => 'storeSettingFieldInsertBindTask', - ), - 'dkim_add_adsp' => array( - 'label' => $lng['dkim']['dkim_add_adsp'], - 'settinggroup' => 'dkim', - 'varname' => 'dkim_add_adsp', - 'type' => 'bool', - 'default' => true, - 'save_method' => 'storeSettingFieldInsertBindTask', - ), - 'dkim_add_adsppolicy' => array( - 'label' => $lng['dkim']['dkim_add_adsppolicy'], - 'settinggroup' => 'dkim', - 'varname' => 'dkim_add_adsppolicy', - 'type' => 'option', - 'default' => '1', - 'option_mode' => 'one', - 'option_options' => array('0' => 'Unknown', '1' => 'All', '2' => 'Discardable'), - 'save_method' => 'storeSettingFieldInsertBindTask', - ), + 'save_method' => 'storeSettingFieldInsertBindTask' + ), 'dkimrestart_command' => array( 'label' => $lng['dkim']['dkimrestart_command'], 'settinggroup' => 'dkim', 'varname' => 'dkimrestart_command', 'type' => 'string', 'default' => '/etc/init.d/dkim-filter restart', - 'save_method' => 'storeSettingField', - ), - ), - ), - ), - ); + 'save_method' => 'storeSettingField' + ) + ) + ) + ) +); ?> diff --git a/actions/admin/settings/185.spf.php b/actions/admin/settings/185.spf.php index c4d14cf5..9d0fbcee 100644 --- a/actions/admin/settings/185.spf.php +++ b/actions/admin/settings/185.spf.php @@ -14,7 +14,6 @@ * @package Settings * */ - return array( 'groups' => array( 'spf' => array( @@ -28,18 +27,18 @@ return array( 'default' => false, 'save_method' => 'storeSettingField', 'overview_option' => true - ), + ), 'spf_entry' => array( 'label' => $lng['spf']['spf_entry'], 'settinggroup' => 'spf', 'varname' => 'spf_entry', 'type' => 'string', - 'default' => '@ IN TXT "v=spf1 a mx -all"', + 'default' => '"v=spf1 a mx -all"', 'save_method' => 'storeSettingField' - ) ) ) ) - ); + ) +); ?> diff --git a/actions/admin/settings/190.ticket.php b/actions/admin/settings/190.ticket.php deleted file mode 100644 index a2d0cf08..00000000 --- a/actions/admin/settings/190.ticket.php +++ /dev/null @@ -1,144 +0,0 @@ - (2003-2009) - * @author Froxlor team (2010-) - * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt - * @package Settings - * - */ - -return array( - 'groups' => array( - 'ticket' => array( - 'title' => $lng['admin']['ticketsettings'], - 'fields' => array( - 'ticket_enabled' => array( - 'label' => $lng['serversettings']['ticket']['enable'], - 'settinggroup' => 'ticket', - 'varname' => 'enabled', - 'type' => 'bool', - 'default' => false, - 'cronmodule' => 'froxlor/ticket', - 'save_method' => 'storeSettingField', - 'overview_option' => true - ), - 'ticket_noreply_email' => array( - 'label' => $lng['serversettings']['ticket']['noreply_email'], - 'settinggroup' => 'ticket', - 'varname' => 'noreply_email', - 'type' => 'string', - 'string_type' => 'mail', - 'default' => '', - 'save_method' => 'storeSettingField', - ), - 'ticket_noreply_name' => array( - 'label' => $lng['serversettings']['ticket']['noreply_name'], - 'settinggroup' => 'ticket', - 'varname' => 'noreply_name', - 'type' => 'string', - 'default' => '', - 'save_method' => 'storeSettingField', - ), - 'ticket_reset_cycle' => array( - 'label' => $lng['serversettings']['ticket']['reset_cycle'], - 'settinggroup' => 'ticket', - 'varname' => 'reset_cycle', - 'type' => 'option', - 'default' => 1, - 'option_mode' => 'one', - 'option_options' => array(0 => html_entity_decode($lng['admin']['tickets']['daily']), 1 => html_entity_decode($lng['admin']['tickets']['weekly']), 2 => html_entity_decode($lng['admin']['tickets']['monthly']), 3 => html_entity_decode($lng['admin']['tickets']['yearly'])), - 'save_method' => 'storeSettingField', - 'plausibility_check_method' => 'setCycleOfCronjob', - ), - 'ticket_concurrently_open' => array( - 'label' => $lng['serversettings']['ticket']['concurrentlyopen'], - 'settinggroup' => 'ticket', - 'varname' => 'concurrently_open', - 'type' => 'int', - 'default' => 5, - 'save_method' => 'storeSettingField', - ), - 'ticket_archiving_days' => array( - 'label' => $lng['serversettings']['ticket']['archiving_days'], - 'settinggroup' => 'ticket', - 'varname' => 'archiving_days', - 'type' => 'int', - 'int_min' => 1, - 'int_max' => 99, - 'default' => 5, - 'save_method' => 'storeSettingField', - ), - 'ticket_worktime_all' => array( - 'label' => $lng['serversettings']['ticket']['worktime_all'], - 'settinggroup' => 'ticket', - 'varname' => 'worktime_all', - 'type' => 'bool', - 'default' => false, - 'save_method' => 'storeSettingField', - ), - 'ticket_worktime_begin' => array( - 'label' => $lng['serversettings']['ticket']['worktime_begin'], - 'settinggroup' => 'ticket', - 'varname' => 'worktime_begin', - 'type' => 'string', - 'string_regexp' => '/^[012][0-9]:[0-6][0-9]$/', - 'default' => '', - 'save_method' => 'storeSettingField', - ), - 'ticket_worktime_end' => array( - 'label' => $lng['serversettings']['ticket']['worktime_end'], - 'settinggroup' => 'ticket', - 'varname' => 'worktime_end', - 'type' => 'string', - 'string_regexp' => '/^[012][0-9]:[0-6][0-9]$/', - 'default' => '', - 'save_method' => 'storeSettingField', - ), - 'ticket_worktime_sat' => array( - 'label' => $lng['serversettings']['ticket']['worktime_sat'], - 'settinggroup' => 'ticket', - 'varname' => 'worktime_sat', - 'type' => 'bool', - 'default' => false, - 'save_method' => 'storeSettingField', - ), - 'ticket_worktime_sun' => array( - 'label' => $lng['serversettings']['ticket']['worktime_sun'], - 'settinggroup' => 'ticket', - 'varname' => 'worktime_sun', - 'type' => 'bool', - 'default' => false, - 'save_method' => 'storeSettingField', - ), - 'system_last_archive_run' => array( - 'settinggroup' => 'system', - 'varname' => 'last_archive_run', - 'type' => 'hidden', - 'default' => '', - ), - 'ticket_default_priority' => array( - 'label' => $lng['serversettings']['ticket']['default_priority'], - 'settinggroup' => 'ticket', - 'varname' => 'default_priority', - 'type' => 'option', - 'default' => 2, - 'option_mode' => 'one', - 'option_options' => array(1 => $lng['ticket']['high'], 2 => $lng['ticket']['normal'], 3 => $lng['ticket']['low']), - 'save_method' => 'storeSettingField', - ), - ), - ), - ) - ); - -?> diff --git a/actions/admin/settings/210.security.php b/actions/admin/settings/210.security.php index 4456b6e1..62542c67 100644 --- a/actions/admin/settings/210.security.php +++ b/actions/admin/settings/210.security.php @@ -16,7 +16,6 @@ * @package Settings * */ - return array( 'groups' => array( 'security' => array( @@ -28,16 +27,16 @@ return array( 'varname' => 'unix_names', 'type' => 'bool', 'default' => true, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'system_mailpwcleartext' => array( 'label' => $lng['serversettings']['mailpwcleartext'], 'settinggroup' => 'system', 'varname' => 'mailpwcleartext', 'type' => 'bool', - 'default' => true, - 'save_method' => 'storeSettingField', - ), + 'default' => false, + 'save_method' => 'storeSettingField' + ), 'system_passwordcryptfunc' => array( 'label' => $lng['serversettings']['passwordcryptfunc'], 'settinggroup' => 'system', @@ -45,26 +44,46 @@ return array( 'type' => 'option', 'default' => 0, 'option_mode' => 'one', - 'option_options_method' => 'getAvailablePasswordHashes', - 'save_method' => 'storeSettingField', + 'option_options_method' => array( + '\\Froxlor\\System\\Crypt', + 'getAvailablePasswordHashes' ), + 'save_method' => 'storeSettingField' + ), 'system_allow_error_report_admin' => array( 'label' => $lng['serversettings']['allow_error_report_admin'], 'settinggroup' => 'system', 'varname' => 'allow_error_report_admin', 'type' => 'bool', 'default' => false, - 'save_method' => 'storeSettingField', - ), + 'save_method' => 'storeSettingField' + ), 'system_allow_error_report_customer' => array( 'label' => $lng['serversettings']['allow_error_report_customer'], 'settinggroup' => 'system', 'varname' => 'allow_error_report_customer', 'type' => 'bool', 'default' => false, - 'save_method' => 'storeSettingField', - ) + 'save_method' => 'storeSettingField' + ), + 'system_allow_customer_shell' => array( + 'label' => $lng['serversettings']['allow_allow_customer_shell'], + 'settinggroup' => 'system', + 'varname' => 'allow_customer_shell', + 'type' => 'bool', + 'default' => false, + 'save_method' => 'storeSettingField' + ), + 'system_available_shells' => array( + 'label' => $lng['serversettings']['available_shells'], + 'settinggroup' => 'system', + 'varname' => 'available_shells', + 'type' => 'string', + 'string_emptyallowed' => true, + 'default' => '', + 'save_method' => 'storeSettingField' ) ) ) - ); + ) +); diff --git a/actions/admin/settings/220.quota.php b/actions/admin/settings/220.quota.php index 52e94379..cf79b4e1 100644 --- a/actions/admin/settings/220.quota.php +++ b/actions/admin/settings/220.quota.php @@ -13,7 +13,6 @@ * @package Settings * */ - return array( 'groups' => array( 'diskquota' => array( @@ -34,7 +33,7 @@ return array( 'varname' => 'diskquota_repquota_path', 'type' => 'string', 'default' => '/usr/sbin/repquota', - 'save_method' => 'storeSettingField', + 'save_method' => 'storeSettingField' ), 'diskquota_quotatool_path' => array( 'label' => $lng['serversettings']['diskquota_quotatool_path']['description'], @@ -42,7 +41,7 @@ return array( 'varname' => 'diskquota_quotatool_path', 'type' => 'string', 'default' => '/usr/bin/quotatool', - 'save_method' => 'storeSettingField', + 'save_method' => 'storeSettingField' ), 'diskquota_customer_partition' => array( 'label' => $lng['serversettings']['diskquota_customer_partition']['description'], @@ -50,11 +49,11 @@ return array( 'varname' => 'diskquota_customer_partition', 'type' => 'string', 'default' => '/dev/root', - 'save_method' => 'storeSettingField', - ), - ), - ), - ), - ); + 'save_method' => 'storeSettingField' + ) + ) + ) + ) +); ?> diff --git a/admin_admins.php b/admin_admins.php index 32e5de12..b404cf8c 100644 --- a/admin_admins.php +++ b/admin_admins.php @@ -16,23 +16,24 @@ * @package Panel * */ - define('AREA', 'admin'); require './lib/init.php'; +use Froxlor\Database\Database; +use Froxlor\Settings; +use Froxlor\Api\Commands\Admins as Admins; + if (isset($_POST['id'])) { $id = intval($_POST['id']); -} elseif(isset($_GET['id'])) { +} elseif (isset($_GET['id'])) { $id = intval($_GET['id']); } -if ($page == 'admins' - && $userinfo['change_serversettings'] == '1' -) { +if ($page == 'admins' && $userinfo['change_serversettings'] == '1') { if ($action == '') { - $log->logAction(ADM_ACTION, LOG_NOTICE, "viewed admin_admins"); + $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "viewed admin_admins"); $fields = array( 'loginname' => $lng['login']['username'], 'name' => $lng['customer']['name'], @@ -42,84 +43,91 @@ if ($page == 'admins' 'traffic_used' => $lng['customer']['traffic'] . ' (' . $lng['panel']['used'] . ')', 'deactivated' => $lng['admin']['deactivated'] ); - $paging = new paging($userinfo, TABLE_PANEL_ADMINS, $fields); + try { + // get total count + $json_result = Admins::getLocal($userinfo)->listingCount(); + $result = json_decode($json_result, true)['data']; + // initialize pagination and filtering + $paging = new \Froxlor\UI\Pagination($userinfo, $fields, $result); + // get list + $json_result = Admins::getLocal($userinfo, $paging->getApiCommandParams())->listing(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; + $admins = ''; - $result_stmt = Database::query("SELECT * FROM `" . TABLE_PANEL_ADMINS . "` " . $paging->getSqlWhere(false) . " " . $paging->getSqlOrderBy() . " " . $paging->getSqlLimit()); - $numrows_admins = Database::num_rows(); - $paging->setEntries($numrows_admins); $sortcode = $paging->getHtmlSortCode($lng, true); $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); $searchcode = $paging->getHtmlSearchCode($lng); $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); - $i = 0; $count = 0; $dec_places = Settings::Get('panel.decimal_places'); - while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { + foreach ($result['list'] as $row) { - if ($paging->checkDisplay($i)) { + $row['traffic_used'] = round($row['traffic_used'] / (1024 * 1024), $dec_places); + $row['traffic'] = round($row['traffic'] / (1024 * 1024), $dec_places); + $row['diskspace_used'] = round($row['diskspace_used'] / 1024, $dec_places); + $row['diskspace'] = round($row['diskspace'] / 1024, $dec_places); - $row['traffic_used'] = round($row['traffic_used'] / (1024 * 1024), $dec_places); - $row['traffic'] = round($row['traffic'] / (1024 * 1024), $dec_places); - $row['diskspace_used'] = round($row['diskspace_used'] / 1024, $dec_places); - $row['diskspace'] = round($row['diskspace'] / 1024, $dec_places); - - // percent-values for progressbar - // For Disk usage - if ($row['diskspace'] > 0) { - $disk_percent = round(($row['diskspace_used']*100)/$row['diskspace'], 0); - $disk_doublepercent = round($disk_percent*2, 2); - } else { - $disk_percent = 0; - $disk_doublepercent = 0; - } - // For Traffic usage - if ($row['traffic'] > 0) { - $traffic_percent = round(($row['traffic_used']*100)/$row['traffic'], 0); - $traffic_doublepercent = round($traffic_percent*2, 2); - } else { - $traffic_percent = 0; - $traffic_doublepercent = 0; - } - - // fix progress-bars if value is >100% - if ($disk_percent > 100) { - $disk_percent = 100; - } - if ($traffic_percent > 100) { - $traffic_percent = 100; - } - - $row = str_replace_array('-1', 'UL', $row, 'customers domains diskspace traffic mysqls emails email_accounts email_forwarders email_quota ftps subdomains tickets'); - $row = htmlentities_array($row); - - $row['custom_notes'] = ($row['custom_notes'] != '') ? nl2br($row['custom_notes']) : ''; - - eval("\$admins.=\"" . getTemplate("admins/admins_admin") . "\";"); - $count++; + // percent-values for progressbar + // For Disk usage + if ($row['diskspace'] > 0) { + $disk_percent = round(($row['diskspace_used'] * 100) / $row['diskspace'], 0); + $disk_doublepercent = round($disk_percent * 2, 2); + } else { + $disk_percent = 0; + $disk_doublepercent = 0; } - $i++; + // For Traffic usage + if ($row['traffic'] > 0) { + $traffic_percent = round(($row['traffic_used'] * 100) / $row['traffic'], 0); + $traffic_doublepercent = round($traffic_percent * 2, 2); + } else { + $traffic_percent = 0; + $traffic_doublepercent = 0; + } + + // fix progress-bars if value is >100% + if ($disk_percent > 100) { + $disk_percent = 100; + } + if ($traffic_percent > 100) { + $traffic_percent = 100; + } + + $row = \Froxlor\PhpHelper::strReplaceArray('-1', 'UL', $row, 'customers domains diskspace traffic mysqls emails email_accounts email_forwarders email_quota ftps subdomains'); + $row = \Froxlor\PhpHelper::htmlentitiesArray($row); + + $row['custom_notes'] = ($row['custom_notes'] != '') ? nl2br($row['custom_notes']) : ''; + + eval("\$admins.=\"" . \Froxlor\UI\Template::getTemplate("admins/admins_admin") . "\";"); + $count ++; } - $admincount = $numrows_admins; - eval("echo \"" . getTemplate("admins/admins") . "\";"); + $admincount = $result['count'] . " / " . $paging->getEntries(); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("admins/admins") . "\";"); + } elseif ($action == 'su') { - } elseif($action == 'su') { - - $result_stmt = Database::prepare(" - SELECT * FROM `" . TABLE_PANEL_ADMINS . "` WHERE `adminid` = :adminid - "); - $result = Database::pexecute_first($result_stmt, array('adminid' => $id)); + try { + $json_result = Admins::getLocal($userinfo, array( + 'id' => $id + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; $destination_admin = $result['loginname']; - if ($destination_admin != '' - && $result['adminid'] != $userinfo['userid'] - ) { + if ($destination_admin != '' && $result['adminid'] != $userinfo['userid']) { $result_stmt = Database::prepare(" SELECT * FROM `" . TABLE_PANEL_SESSIONS . "` WHERE `userid` = :userid "); - $result = Database::pexecute_first($result_stmt, array('userid' => $userinfo['userid'])); + $result = Database::pexecute_first($result_stmt, array( + 'userid' => $userinfo['userid'] + )); $s = md5(uniqid(microtime(), 1)); $ins_stmt = Database::prepare(" @@ -137,641 +145,116 @@ if ($page == 'admins' 'lang' => $result['language'] ); Database::pexecute($ins_stmt, $ins_data); - $log->logAction(ADM_ACTION, LOG_INFO, "switched adminuser and is now '" . $destination_admin . "'"); - redirectTo('admin_index.php', array('s' => $s)); - + $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "switched adminuser and is now '" . $destination_admin . "'"); + \Froxlor\UI\Response::redirectTo('admin_index.php', array( + 's' => $s + )); } else { - redirectTo('index.php', array('action' => 'login')); + \Froxlor\UI\Response::redirectTo('index.php', array( + 'action' => 'login' + )); } - - } elseif ($action == 'delete' - && $id != 0 - ) { - $result_stmt = Database::prepare(" - SELECT * FROM `" . TABLE_PANEL_ADMINS . "` WHERE `adminid` = :adminid - "); - $result = Database::pexecute_first($result_stmt, array('adminid' => $id)); + } elseif ($action == 'delete' && $id != 0) { + try { + $json_result = Admins::getLocal($userinfo, array( + 'id' => $id + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; if ($result['loginname'] != '') { if ($result['adminid'] == $userinfo['userid']) { - standard_error('youcantdeleteyourself'); + \Froxlor\UI\Response::standard_error('youcantdeleteyourself'); } - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { - $del_stmt = Database::prepare(" - DELETE FROM `" . TABLE_PANEL_ADMINS . "` WHERE `adminid` = :adminid - "); - Database::pexecute($del_stmt, array('adminid' => $id)); - - $del_stmt = Database::prepare(" - DELETE FROM `" . TABLE_PANEL_TRAFFIC_ADMINS . "` WHERE `adminid` = :adminid - "); - Database::pexecute($del_stmt, array('adminid' => $id)); - - $upd_stmt = Database::prepare(" - UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET - `adminid` = :userid WHERE `adminid` = :adminid - "); - Database::pexecute($upd_stmt, array('userid' => $userinfo['userid'], 'adminid' => $id)); - - $upd_stmt = Database::prepare(" - UPDATE `" . TABLE_PANEL_DOMAINS . "` SET - `adminid` = :userid WHERE `adminid` = :adminid - "); - Database::pexecute($upd_stmt, array('userid' => $userinfo['userid'], 'adminid' => $id)); - - $log->logAction(ADM_ACTION, LOG_INFO, "deleted admin '" . $result['loginname'] . "'"); - updateCounters(); - redirectTo($filename, array('page' => $page, 's' => $s)); - + if (isset($_POST['send']) && $_POST['send'] == 'send') { + Admins::getLocal($userinfo, array( + 'id' => $id + ))->delete(); + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); } else { - ask_yesno('admin_admin_reallydelete', $filename, array('id' => $id, 'page' => $page, 'action' => $action), $result['loginname']); + \Froxlor\UI\HTML::askYesNo('admin_admin_reallydelete', $filename, array( + 'id' => $id, + 'page' => $page, + 'action' => $action + ), $result['loginname']); } } + } elseif ($action == 'add') { - } elseif($action == 'add') { - - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { - - $name = validate($_POST['name'], 'name'); - $email = $idna_convert->encode(validate($_POST['email'], 'email')); - - $custom_notes = validate(str_replace("\r\n", "\n", $_POST['custom_notes']), 'custom_notes', '/^[^\0]*$/'); - $custom_notes_show = 0; - if (isset($_POST['custom_notes_show'])) { - $custom_notes_show = intval_ressource($_POST['custom_notes_show']); + if (isset($_POST['send']) && $_POST['send'] == 'send') { + try { + Admins::getLocal($userinfo, $_POST)->add(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } - - $loginname = validate($_POST['loginname'], 'loginname'); - $password = validate($_POST['admin_password'], 'password'); - $password = validatePassword($password); - $def_language = validate($_POST['def_language'], 'default language'); - - $customers = intval_ressource($_POST['customers']); - if (isset($_POST['customers_ul'])) { - $customers = -1; - } - - $domains = intval_ressource($_POST['domains']); - if (isset($_POST['domains_ul'])) { - $domains = -1; - } - - $subdomains = intval_ressource($_POST['subdomains']); - if (isset($_POST['subdomains_ul'])) { - $subdomains = -1; - } - - $emails = intval_ressource($_POST['emails']); - if (isset($_POST['emails_ul'])) { - $emails = -1; - } - - $email_accounts = intval_ressource($_POST['email_accounts']); - if (isset($_POST['email_accounts_ul'])) { - $email_accounts = -1; - } - - $email_forwarders = intval_ressource($_POST['email_forwarders']); - if (isset($_POST['email_forwarders_ul'])) { - $email_forwarders = -1; - } - - if (Settings::Get('system.mail_quota_enabled') == '1') { - - $email_quota = validate($_POST['email_quota'], 'email_quota', '/^\d+$/', 'vmailquotawrong', array('0', '')); - if (isset($_POST['email_quota_ul'])) { - $email_quota = -1; - } - } else { - $email_quota = -1; - } - - $ftps = intval_ressource($_POST['ftps']); - if (isset($_POST['ftps_ul'])) { - $ftps = -1; - } - - if (Settings::Get('ticket.enabled') == 1) { - - $tickets = intval_ressource($_POST['tickets']); - if (isset($_POST['tickets_ul'])) { - $tickets = -1; - } - } else { - $tickets = 0; - } - - $mysqls = intval_ressource($_POST['mysqls']); - if (isset($_POST['mysqls_ul'])) { - $mysqls = -1; - } - - $customers_see_all = 0; - if (isset($_POST['customers_see_all'])) { - $customers_see_all = intval($_POST['customers_see_all']); - } - - $domains_see_all = 0; - if (isset($_POST['domains_see_all'])) { - $domains_see_all = intval($_POST['domains_see_all']); - } - - $caneditphpsettings = 0; - if (isset($_POST['caneditphpsettings'])) { - $caneditphpsettings = intval($_POST['caneditphpsettings']); - } - - $change_serversettings = 0; - if (isset($_POST['change_serversettings'])) { - $change_serversettings = intval($_POST['change_serversettings']); - } - - $diskspace = intval_ressource($_POST['diskspace']); - if (isset($_POST['diskspace_ul'])) { - $diskspace = -1; - } - - $traffic = doubleval_ressource($_POST['traffic']); - if (isset($_POST['traffic_ul'])) { - $traffic = -1; - } - - $tickets_see_all = 0; - if (isset($_POST['tickets_see_all'])) { - $tickets_see_all = intval($_POST['tickets_see_all']); - } - - $diskspace = $diskspace * 1024; - $traffic = $traffic * 1024 * 1024; - $ipaddress = intval_ressource($_POST['ipaddress']); - - // Check if the account already exists - $loginname_check_stmt = Database::prepare(" - SELECT `loginname` FROM `" . TABLE_PANEL_CUSTOMERS . "` WHERE `loginname` = :login - "); - $loginname_check = Database::pexecute_first($loginname_check_stmt, array('login' => $loginname)); - - $loginname_check_admin_stmt = Database::prepare(" - SELECT `loginname` FROM `" . TABLE_PANEL_ADMINS . "` WHERE `loginname` = :login - "); - $loginname_check_admin = Database::pexecute_first($loginname_check_admin_stmt, array('login' => $loginname)); - - if ($loginname == '') { - standard_error(array('stringisempty', 'myloginname')); - } - elseif (strtolower($loginname_check['loginname']) == strtolower($loginname) - || strtolower($loginname_check_admin['loginname']) == strtolower($loginname) - ) { - standard_error('loginnameexists', $loginname); - } - // Accounts which match systemaccounts are not allowed, filtering them - elseif (preg_match('/^' . preg_quote(Settings::Get('customer.accountprefix'), '/') . '([0-9]+)/', $loginname)) { - standard_error('loginnameissystemaccount', Settings::Get('customer.accountprefix')); - } - elseif (!validateUsername($loginname)) { - standard_error('loginnameiswrong', $loginname); - } - elseif ($name == '') { - standard_error(array('stringisempty', 'myname')); - } - elseif ($email == '') { - standard_error(array('stringisempty', 'emailadd')); - } - elseif ($password == '') { - standard_error(array('stringisempty', 'mypassword')); - } - elseif (!validateEmail($email)) { - standard_error('emailiswrong', $email); - - } else { - - if ($customers_see_all != '1') { - $customers_see_all = '0'; - } - - if ($domains_see_all != '1') { - $domains_see_all = '0'; - } - - if ($caneditphpsettings != '1') { - $caneditphpsettings = '0'; - } - - if ($change_serversettings != '1') { - $change_serversettings = '0'; - } - - if ($tickets_see_all != '1') { - $tickets_see_all = '0'; - } - - $_theme = Settings::Get('panel.default_theme'); - - $ins_data = array( - 'loginname' => $loginname, - 'password' => makeCryptPassword($password), - 'name' => $name, - 'email' => $email, - 'lang' => $def_language, - 'change_serversettings' => $change_serversettings, - 'customers' => $customers, - 'customers_see_all' => $customers_see_all, - 'domains' => $domains, - 'domains_see_all' => $domains_see_all, - 'caneditphpsettings' => $caneditphpsettings, - 'diskspace' => $diskspace, - 'traffic' => $traffic, - 'subdomains' => $subdomains, - 'emails' => $emails, - 'accounts' => $email_accounts, - 'forwarders' => $email_forwarders, - 'quota' => $email_quota, - 'ftps' => $ftps, - 'tickets' => $tickets, - 'tickets_see_all' => $tickets_see_all, - 'mysqls' => $mysqls, - 'ip' => $ipaddress, - 'theme' => $_theme, - 'custom_notes' => $custom_notes, - 'custom_notes_show' => $custom_notes_show - ); - - $ins_stmt = Database::prepare(" - INSERT INTO `" . TABLE_PANEL_ADMINS . "` SET - `loginname` = :loginname, - `password` = :password, - `name` = :name, - `email` = :email, - `def_language` = :lang, - `change_serversettings` = :change_serversettings, - `customers` = :customers, - `customers_see_all` = :customers_see_all, - `domains` = :domains, - `domains_see_all` = :domains_see_all, - `caneditphpsettings` = :caneditphpsettings, - `diskspace` = :diskspace, - `traffic` = :traffic, - `subdomains` = :subdomains, - `emails` = :emails, - `email_accounts` = :accounts, - `email_forwarders` = :forwarders, - `email_quota` = :quota, - `ftps` = :ftps, - `tickets` = :tickets, - `tickets_see_all` = :tickets_see_all, - `mysqls` = :mysqls, - `ip` = :ip, - `theme` = :theme, - `custom_notes` = :custom_notes, - `custom_notes_show` = :custom_notes_show - "); - Database::pexecute($ins_stmt, $ins_data); - - $adminid = Database::lastInsertId(); - $log->logAction(ADM_ACTION, LOG_INFO, "added admin '" . $loginname . "'"); - redirectTo($filename, array('page' => $page, 's' => $s)); - } - + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); } else { $language_options = ''; - while (list($language_file, $language_name) = each($languages)) { - $language_options.= makeoption($language_name, $language_file, $userinfo['language'], true); + foreach ($languages as $language_file => $language_name) { + $language_options .= \Froxlor\UI\HTML::makeoption($language_name, $language_file, $userinfo['language'], true); } - $ipaddress = makeoption($lng['admin']['allips'], "-1"); + $ipaddress = \Froxlor\UI\HTML::makeoption($lng['admin']['allips'], "-1"); $ipsandports_stmt = Database::query(" SELECT `id`, `ip` FROM `" . TABLE_PANEL_IPSANDPORTS . "` GROUP BY `ip` ORDER BY `ip` ASC "); while ($row = $ipsandports_stmt->fetch(PDO::FETCH_ASSOC)) { - $ipaddress.= makeoption($row['ip'], $row['id']); + $ipaddress .= \Froxlor\UI\HTML::makeoption($row['ip'], $row['id']); } - $customers_ul = makecheckbox('customers_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); - $diskspace_ul = makecheckbox('diskspace_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); - $traffic_ul = makecheckbox('traffic_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); - $domains_ul = makecheckbox('domains_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); - $subdomains_ul = makecheckbox('subdomains_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); - $emails_ul = makecheckbox('emails_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); - $email_accounts_ul = makecheckbox('email_accounts_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); - $email_forwarders_ul = makecheckbox('email_forwarders_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); - $email_quota_ul = makecheckbox('email_quota_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); - $ftps_ul = makecheckbox('ftps_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); - $tickets_ul = makecheckbox('tickets_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); - $mysqls_ul = makecheckbox('mysqls_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); + $customers_ul = \Froxlor\UI\HTML::makecheckbox('customers_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); + $diskspace_ul = \Froxlor\UI\HTML::makecheckbox('diskspace_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); + $traffic_ul = \Froxlor\UI\HTML::makecheckbox('traffic_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); + $domains_ul = \Froxlor\UI\HTML::makecheckbox('domains_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); + $subdomains_ul = \Froxlor\UI\HTML::makecheckbox('subdomains_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); + $emails_ul = \Froxlor\UI\HTML::makecheckbox('emails_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); + $email_accounts_ul = \Froxlor\UI\HTML::makecheckbox('email_accounts_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); + $email_forwarders_ul = \Froxlor\UI\HTML::makecheckbox('email_forwarders_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); + $email_quota_ul = \Froxlor\UI\HTML::makecheckbox('email_quota_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); + $ftps_ul = \Froxlor\UI\HTML::makecheckbox('ftps_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); + $mysqls_ul = \Froxlor\UI\HTML::makecheckbox('mysqls_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); - $admin_add_data = include_once dirname(__FILE__).'/lib/formfields/admin/admin/formfield.admin_add.php'; - $admin_add_form = htmlform::genHTMLForm($admin_add_data); + $admin_add_data = include_once dirname(__FILE__) . '/lib/formfields/admin/admin/formfield.admin_add.php'; + $admin_add_form = \Froxlor\UI\HtmlForm::genHTMLForm($admin_add_data); $title = $admin_add_data['admin_add']['title']; $image = $admin_add_data['admin_add']['image']; - eval("echo \"" . getTemplate("admins/admins_add") . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("admins/admins_add") . "\";"); } - - } elseif($action == 'edit' - && $id != 0 - ) { - - $result_stmt = Database::prepare(" - SELECT * FROM `" . TABLE_PANEL_ADMINS . "` WHERE `adminid` = :adminid - "); - $result = Database::pexecute_first($result_stmt, array('adminid' => $id)); + } elseif ($action == 'edit' && $id != 0) { + try { + $json_result = Admins::getLocal($userinfo, array( + 'id' => $id + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; if ($result['loginname'] != '') { - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { - $name = validate($_POST['name'], 'name'); - $email = $idna_convert->encode(validate($_POST['email'], 'email')); - - $custom_notes = validate(str_replace("\r\n", "\n", $_POST['custom_notes']), 'custom_notes', '/^[^\0]*$/'); - $custom_notes_show = $result['custom_notes_show']; - if (isset($_POST['custom_notes_show'])) { - $custom_notes_show = intval_ressource($_POST['custom_notes_show']); + if (isset($_POST['send']) && $_POST['send'] == 'send') { + try { + Admins::getLocal($userinfo, $_POST)->update(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } - - if ($result['adminid'] == $userinfo['userid']) { - - $password = ''; - $def_language = $result['def_language']; - $deactivated = $result['deactivated']; - $customers = $result['customers']; - $domains = $result['domains']; - $subdomains = $result['subdomains']; - $emails = $result['emails']; - $email_accounts = $result['email_accounts']; - $email_forwarders = $result['email_forwarders']; - $email_quota = $result['email_quota']; - $ftps = $result['ftps']; - $tickets = $result['tickets']; - $mysqls = $result['mysqls']; - $tickets_see_all = $result['tickets_see_all']; - $customers_see_all = $result['customers_see_all']; - $domains_see_all = $result['domains_see_all']; - $caneditphpsettings = $result['caneditphpsettings']; - $change_serversettings = $result['change_serversettings']; - $diskspace = $result['diskspace']; - $traffic = $result['traffic']; - $ipaddress = $result['ip']; - - } else { - - $password = validate($_POST['admin_password'], 'new password'); - $def_language = validate($_POST['def_language'], 'default language'); - $deactivated = isset($_POST['deactivated']) ? 1 : 0; - - $customers = intval_ressource($_POST['customers']); - if (isset($_POST['customers_ul'])) { - $customers = -1; - } - - $domains = intval_ressource($_POST['domains']); - if (isset($_POST['domains_ul'])) { - $domains = -1; - } - - $subdomains = intval_ressource($_POST['subdomains']); - if (isset($_POST['subdomains_ul'])) { - $subdomains = -1; - } - - $emails = intval_ressource($_POST['emails']); - if (isset($_POST['emails_ul'])) { - $emails = -1; - } - - $email_accounts = intval_ressource($_POST['email_accounts']); - if (isset($_POST['email_accounts_ul'])) { - $email_accounts = -1; - } - - $email_forwarders = intval_ressource($_POST['email_forwarders']); - if (isset($_POST['email_forwarders_ul'])) { - $email_forwarders = -1; - } - - if (Settings::Get('system.mail_quota_enabled') == '1') { - $email_quota = validate($_POST['email_quota'], 'email_quota', '/^\d+$/', 'vmailquotawrong', array('0', '')); - if (isset($_POST['email_quota_ul'])) { - $email_quota = -1; - } - } else { - $email_quota = -1; - } - - $ftps = intval_ressource($_POST['ftps']); - if (isset($_POST['ftps_ul'])) { - $ftps = -1; - } - - if (Settings::Get('ticket.enabled') == 1) { - $tickets = intval_ressource($_POST['tickets']); - if (isset($_POST['tickets_ul'])) { - $tickets = -1; - } - } else { - $tickets = 0; - } - - $mysqls = intval_ressource($_POST['mysqls']); - if (isset($_POST['mysqls_ul'])) { - $mysqls = -1; - } - - $customers_see_all = 0; - if (isset($_POST['customers_see_all'])) { - $customers_see_all = intval($_POST['customers_see_all']); - } - - $domains_see_all = 0; - if (isset($_POST['domains_see_all'])) { - $domains_see_all = intval($_POST['domains_see_all']); - } - - $caneditphpsettings = 0; - if (isset($_POST['caneditphpsettings'])) { - $caneditphpsettings = intval($_POST['caneditphpsettings']); - } - - $change_serversettings = 0; - if (isset($_POST['change_serversettings'])) { - $change_serversettings = isset($_POST['change_serversettings']) ? 1 : 0; - } - - $tickets_see_all = 0; - if (isset($_POST['tickets_see_all'])) { - $tickets_see_all = intval($_POST['tickets_see_all']); - } - - $diskspace = intval($_POST['diskspace']); - if (isset($_POST['diskspace_ul'])) { - $diskspace = -1; - } - - $traffic = doubleval_ressource($_POST['traffic']); - if (isset($_POST['traffic_ul'])) { - $traffic = -1; - } - - $diskspace = $diskspace * 1024; - $traffic = $traffic * 1024 * 1024; - $ipaddress = intval_ressource($_POST['ipaddress']); - } - - if ($name == '') { - standard_error(array('stringisempty', 'myname')); - } elseif($email == '') { - standard_error(array('stringisempty', 'emailadd')); - } elseif(!validateEmail($email)) { - standard_error('emailiswrong', $email); - } else { - if ($password != '') { - $password = validatePassword($password); - $password = makeCryptPassword($password); - } else { - $password = $result['password']; - } - - if ($deactivated != '1') { - $deactivated = '0'; - } - - if ($customers_see_all != '1') { - $customers_see_all = '0'; - } - - if ($domains_see_all != '1') { - $domains_see_all = '0'; - } - - if ($caneditphpsettings != '1') { - $caneditphpsettings = '0'; - } - - if ($change_serversettings != '1') { - $change_serversettings = '0'; - } - - if ($tickets_see_all != '1') { - $tickets_see_all = '0'; - } - - // check if a resource was set to something lower - // than actually used by the admin/reseller - $res_warning = ""; - if ($customers != $result['customers'] && $customers != -1 && $customers < $result['customers_used']) { - $res_warning .= sprintf($lng['error']['setlessthanalreadyused'], 'customers'); - } - if ($domains != $result['domains'] && $domains != -1 && $domains < $result['domains_used']) { - $res_warning .= sprintf($lng['error']['setlessthanalreadyused'], 'domains'); - } - if ($diskspace != $result['diskspace'] && ($diskspace / 1024) != -1 && $diskspace < $result['diskspace_used']) { - $res_warning .= sprintf($lng['error']['setlessthanalreadyused'], 'diskspace'); - } - if ($traffic != $result['traffic'] && ($traffic / 1024 / 1024) != -1 && $traffic < $result['traffic_used']) { - $res_warning .= sprintf($lng['error']['setlessthanalreadyused'], 'traffic'); - } - if ($emails != $result['emails'] && $emails != -1 && $emails < $result['emails_used']) { - $res_warning .= sprintf($lng['error']['setlessthanalreadyused'], 'emails'); - } - if ($email_accounts != $result['email_accounts'] && $email_accounts != -1 && $email_accounts < $result['email_accounts_used']) { - $res_warning .= sprintf($lng['error']['setlessthanalreadyused'], 'email accounts'); - } - if ($email_forwarders != $result['email_forwarders'] && $email_forwarders != -1 && $email_forwarders < $result['email_forwarders_used']) { - $res_warning .= sprintf($lng['error']['setlessthanalreadyused'], 'email forwarders'); - } - if ($email_quota != $result['email_quota'] && $email_quota != -1 && $email_quota < $result['email_quota_used']) { - $res_warning .= sprintf($lng['error']['setlessthanalreadyused'], 'email quota'); - } - if ($ftps != $result['ftps'] && $ftps != -1 && $ftps < $result['ftps_used']) { - $res_warning .= sprintf($lng['error']['setlessthanalreadyused'], 'ftps'); - } - if ($tickets != $result['tickets'] && $tickets != -1 && $tickets < $result['tickets_used']) { - $res_warning .= sprintf($lng['error']['setlessthanalreadyused'], 'tickets'); - } - if ($mysqls != $result['mysqls'] && $mysqls != -1 && $mysqls < $result['mysqls_used']) { - $res_warning .= sprintf($lng['error']['setlessthanalreadyused'], 'mysqls'); - } - - if ($res_warning != "") { - $link = ''; - $error = $res_warning; - eval("echo \"" . getTemplate('misc/error', '1') . "\";"); - exit; - } - - $upd_data = array( - 'password' => $password, - 'name' => $name, - 'email' => $email, - 'lang' => $def_language, - 'change_serversettings' => $change_serversettings, - 'customers' => $customers, - 'customers_see_all' => $customers_see_all, - 'domains' => $domains, - 'domains_see_all' => $domains_see_all, - 'caneditphpsettings' => $caneditphpsettings, - 'diskspace' => $diskspace, - 'traffic' => $traffic, - 'subdomains' => $subdomains, - 'emails' => $emails, - 'accounts' => $email_accounts, - 'forwarders' => $email_forwarders, - 'quota' => $email_quota, - 'ftps' => $ftps, - 'tickets' => $tickets, - 'tickets_see_all' => $tickets_see_all, - 'mysqls' => $mysqls, - 'ip' => $ipaddress, - 'deactivated' => $deactivated, - 'custom_notes' => $custom_notes, - 'custom_notes_show' => $custom_notes_show, - 'adminid' => $id - ); - - $upd_stmt = Database::prepare(" - UPDATE `" . TABLE_PANEL_ADMINS . "` SET - `password` = :password, - `name` = :name, - `email` = :email, - `def_language` = :lang, - `change_serversettings` = :change_serversettings, - `customers` = :customers, - `customers_see_all` = :customers_see_all, - `domains` = :domains, - `domains_see_all` = :domains_see_all, - `caneditphpsettings` = :caneditphpsettings, - `diskspace` = :diskspace, - `traffic` = :traffic, - `subdomains` = :subdomains, - `emails` = :emails, - `email_accounts` = :accounts, - `email_forwarders` = :forwarders, - `email_quota` = :quota, - `ftps` = :ftps, - `tickets` = :tickets, - `tickets_see_all` = :tickets_see_all, - `mysqls` = :mysqls, - `ip` = :ip, - `deactivated` = :deactivated, - `custom_notes` = :custom_notes, - `custom_notes_show` = :custom_notes_show - WHERE `adminid` = :adminid - "); - Database::pexecute($upd_stmt, $upd_data); - - $log->logAction(ADM_ACTION, LOG_INFO, "edited admin '#" . $id . "'"); - redirectTo($filename, array('page' => $page, 's' => $s)); - } - + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); } else { $dec_places = Settings::Get('panel.decimal_places'); @@ -779,89 +262,84 @@ if ($page == 'admins' $result['diskspace'] = round($result['diskspace'] / 1024, $dec_places); $result['email'] = $idna_convert->decode($result['email']); - $customers_ul = makecheckbox('customers_ul', $lng['customer']['unlimited'], '-1', false, $result['customers'], true, true); + $customers_ul = \Froxlor\UI\HTML::makecheckbox('customers_ul', $lng['customer']['unlimited'], '-1', false, $result['customers'], true, true); if ($result['customers'] == '-1') { $result['customers'] = ''; } - $diskspace_ul = makecheckbox('diskspace_ul', $lng['customer']['unlimited'], '-1', false, $result['diskspace'], true, true); + $diskspace_ul = \Froxlor\UI\HTML::makecheckbox('diskspace_ul', $lng['customer']['unlimited'], '-1', false, $result['diskspace'], true, true); if ($result['diskspace'] == '-1') { $result['diskspace'] = ''; } - $traffic_ul = makecheckbox('traffic_ul', $lng['customer']['unlimited'], '-1', false, $result['traffic'], true, true); + $traffic_ul = \Froxlor\UI\HTML::makecheckbox('traffic_ul', $lng['customer']['unlimited'], '-1', false, $result['traffic'], true, true); if ($result['traffic'] == '-1') { $result['traffic'] = ''; } - $domains_ul = makecheckbox('domains_ul', $lng['customer']['unlimited'], '-1', false, $result['domains'], true, true); + $domains_ul = \Froxlor\UI\HTML::makecheckbox('domains_ul', $lng['customer']['unlimited'], '-1', false, $result['domains'], true, true); if ($result['domains'] == '-1') { $result['domains'] = ''; } - $subdomains_ul = makecheckbox('subdomains_ul', $lng['customer']['unlimited'], '-1', false, $result['subdomains'], true, true); + $subdomains_ul = \Froxlor\UI\HTML::makecheckbox('subdomains_ul', $lng['customer']['unlimited'], '-1', false, $result['subdomains'], true, true); if ($result['subdomains'] == '-1') { $result['subdomains'] = ''; } - $emails_ul = makecheckbox('emails_ul', $lng['customer']['unlimited'], '-1', false, $result['emails'], true, true); + $emails_ul = \Froxlor\UI\HTML::makecheckbox('emails_ul', $lng['customer']['unlimited'], '-1', false, $result['emails'], true, true); if ($result['emails'] == '-1') { $result['emails'] = ''; } - $email_accounts_ul = makecheckbox('email_accounts_ul', $lng['customer']['unlimited'], '-1', false, $result['email_accounts'], true, true); + $email_accounts_ul = \Froxlor\UI\HTML::makecheckbox('email_accounts_ul', $lng['customer']['unlimited'], '-1', false, $result['email_accounts'], true, true); if ($result['email_accounts'] == '-1') { $result['email_accounts'] = ''; } - $email_forwarders_ul = makecheckbox('email_forwarders_ul', $lng['customer']['unlimited'], '-1', false, $result['email_forwarders'], true, true); + $email_forwarders_ul = \Froxlor\UI\HTML::makecheckbox('email_forwarders_ul', $lng['customer']['unlimited'], '-1', false, $result['email_forwarders'], true, true); if ($result['email_forwarders'] == '-1') { $result['email_forwarders'] = ''; } - $email_quota_ul = makecheckbox('email_quota_ul', $lng['customer']['unlimited'], '-1', false, $result['email_quota'], true, true); + $email_quota_ul = \Froxlor\UI\HTML::makecheckbox('email_quota_ul', $lng['customer']['unlimited'], '-1', false, $result['email_quota'], true, true); if ($result['email_quota'] == '-1') { $result['email_quota'] = ''; } - $ftps_ul = makecheckbox('ftps_ul', $lng['customer']['unlimited'], '-1', false, $result['ftps'], true, true); + $ftps_ul = \Froxlor\UI\HTML::makecheckbox('ftps_ul', $lng['customer']['unlimited'], '-1', false, $result['ftps'], true, true); if ($result['ftps'] == '-1') { $result['ftps'] = ''; } - $tickets_ul = makecheckbox('tickets_ul', $lng['customer']['unlimited'], '-1', false, $result['tickets'], true, true); - if ($result['tickets'] == '-1') { - $result['tickets'] = ''; - } - - $mysqls_ul = makecheckbox('mysqls_ul', $lng['customer']['unlimited'], '-1', false, $result['mysqls'], true, true); + $mysqls_ul = \Froxlor\UI\HTML::makecheckbox('mysqls_ul', $lng['customer']['unlimited'], '-1', false, $result['mysqls'], true, true); if ($result['mysqls'] == '-1') { $result['mysqls'] = ''; } $language_options = ''; - while (list($language_file, $language_name) = each($languages)) { - $language_options.= makeoption($language_name, $language_file, $result['def_language'], true); + foreach ($languages as $language_file => $language_name) { + $language_options .= \Froxlor\UI\HTML::makeoption($language_name, $language_file, $result['def_language'], true); } - $ipaddress = makeoption($lng['admin']['allips'], "-1", $result['ip']); + $ipaddress = \Froxlor\UI\HTML::makeoption($lng['admin']['allips'], "-1", $result['ip']); $ipsandports_stmt = Database::query(" - SELECT `id`, `ip` FROM `" . TABLE_PANEL_IPSANDPORTS . "` GROUP BY `ip` ORDER BY `ip`, `port` ASC + SELECT `id`, `ip` FROM `" . TABLE_PANEL_IPSANDPORTS . "` GROUP BY `id`, `ip` ORDER BY `ip`, `port` ASC "); while ($row = $ipsandports_stmt->fetch(PDO::FETCH_ASSOC)) { - $ipaddress.= makeoption($row['ip'], $row['id'], $result['ip']); + $ipaddress .= \Froxlor\UI\HTML::makeoption($row['ip'], $row['id'], $result['ip']); } - $result = htmlentities_array($result); + $result = \Froxlor\PhpHelper::htmlentitiesArray($result); - $admin_edit_data = include_once dirname(__FILE__).'/lib/formfields/admin/admin/formfield.admin_edit.php'; - $admin_edit_form = htmlform::genHTMLForm($admin_edit_data); + $admin_edit_data = include_once dirname(__FILE__) . '/lib/formfields/admin/admin/formfield.admin_edit.php'; + $admin_edit_form = \Froxlor\UI\HtmlForm::genHTMLForm($admin_edit_data); $title = $admin_edit_data['admin_edit']['title']; $image = $admin_edit_data['admin_edit']['image']; - eval("echo \"" . getTemplate("admins/admins_edit") . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("admins/admins_edit") . "\";"); } } } diff --git a/admin_apcuinfo.php b/admin_apcuinfo.php index 55c255ab..a0b0f937 100644 --- a/admin_apcuinfo.php +++ b/admin_apcuinfo.php @@ -1,415 +1,440 @@ | - | Rasmus Lerdorf | - | Ilia Alshanetsky | - +----------------------------------------------------------------------+ - - All other licensing and usage conditions are those of the PHP Group. - - Based on https://github.com/krakjoe/apcu/blob/master/apc.php - Implemented into Froxlor: Janos Muzsi - + * +----------------------------------------------------------------------+ + * | APC | + * +----------------------------------------------------------------------+ + * | Copyright (c) 2006-2011 The PHP Group | + * +----------------------------------------------------------------------+ + * | This source file is subject to version 3.01 of the PHP license, | + * | that is bundled with this package in the file LICENSE, and is | + * | available through the world-wide-web at the following url: | + * | http://www.php.net/license/3_01.txt | + * | If you did not receive a copy of the PHP license and are unable to | + * | obtain it through the world-wide-web, please send a note to | + * | license@php.net so we can mail you a copy immediately. | + * +----------------------------------------------------------------------+ + * | Authors: Ralf Becker | + * | Rasmus Lerdorf | + * | Ilia Alshanetsky | + * +----------------------------------------------------------------------+ + * + * All other licensing and usage conditions are those of the PHP Group. + * + * Based on https://github.com/krakjoe/apcu/blob/master/apc.php + * Implemented into Froxlor: Janos Muzsi + * */ - define('AREA', 'admin'); require './lib/init.php'; - $horizontal_bar_size = 950; // 1280px window width -if ($action == 'delete' && - function_exists('apcu_clear_cache') && - $userinfo['change_serversettings'] == '1' -) { - apcu_clear_cache(); - $log->logAction(ADM_ACTION, LOG_INFO, "cleared APCu cache"); - header('Location: ' . $linker->getLink(array('section' => 'apcuinfo', 'page' => 'showinfo'))); - exit(); +if ($action == 'delete' && function_exists('apcu_clear_cache') && $userinfo['change_serversettings'] == '1') { + apcu_clear_cache(); + $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "cleared APCu cache"); + header('Location: ' . $linker->getLink(array( + 'section' => 'apcuinfo', + 'page' => 'showinfo' + ))); + exit(); } -if (!function_exists('apcu_cache_info') || - !function_exists('apcu_sma_info') -) { - standard_error($lng['error']['no_apcuinfo']); +if (! function_exists('apcu_cache_info') || ! function_exists('apcu_sma_info')) { + \Froxlor\UI\Response::standard_error($lng['error']['no_apcuinfo']); } -if ($page == 'showinfo' -) { - $cache = apcu_cache_info(); - $mem = apcu_sma_info(); - $time = time(); - $log->logAction(ADM_ACTION, LOG_NOTICE, "viewed admin_apcuinfo"); +if ($page == 'showinfo') { + $cache = apcu_cache_info(); + $mem = apcu_sma_info(); + $time = time(); + $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "viewed admin_apcuinfo"); - $passtime = $time - $cache['start_time'] > 0 ? $time - $cache['start_time'] : 1; // zero division - $mem_size = $mem['num_seg'] * $mem['seg_size']; - $mem_avail = $mem['avail_mem']; - $mem_used = $mem_size - $mem_avail; - $seg_size = bsize($mem['seg_size']); - $sharedmem = sprintf($lng['apcuinfo']['sharedmemval'], $mem['num_seg'], $seg_size, $cache['memory_type']); - $req_rate_user = sprintf("%.2f", $cache['num_hits'] ? (($cache['num_hits'] + $cache['num_misses']) / $passtime) : 0); - $hit_rate_user = sprintf("%.2f", $cache['num_hits'] ? (($cache['num_hits']) / $passtime) : 0); - $miss_rate_user = sprintf("%.2f", $cache['num_misses'] ? (($cache['num_misses']) / $passtime) : 0); - $insert_rate_user = sprintf("%.2f", $cache['num_inserts'] ? (($cache['num_inserts']) / $passtime) : 0); - $apcversion = phpversion('apcu'); - $phpversion = phpversion(); - $number_vars = $cache['num_entries']; - $starttime = date('Y-m-d H:i:s', $cache['start_time']); - $uptime_duration = duration($cache['start_time']); - $size_vars = bsize($cache['mem_size']); + $passtime = $time - $cache['start_time'] > 0 ? $time - $cache['start_time'] : 1; // zero division + $mem_size = $mem['num_seg'] * $mem['seg_size']; + $mem_avail = $mem['avail_mem']; + $mem_used = $mem_size - $mem_avail; + $seg_size = bsize($mem['seg_size']); + $sharedmem = sprintf($lng['apcuinfo']['sharedmemval'], $mem['num_seg'], $seg_size, $cache['memory_type']); + $req_rate_user = sprintf("%.2f", $cache['num_hits'] ? (($cache['num_hits'] + $cache['num_misses']) / $passtime) : 0); + $hit_rate_user = sprintf("%.2f", $cache['num_hits'] ? (($cache['num_hits']) / $passtime) : 0); + $miss_rate_user = sprintf("%.2f", $cache['num_misses'] ? (($cache['num_misses']) / $passtime) : 0); + $insert_rate_user = sprintf("%.2f", $cache['num_inserts'] ? (($cache['num_inserts']) / $passtime) : 0); + $apcversion = phpversion('apcu'); + $phpversion = phpversion(); + $number_vars = $cache['num_entries']; + $starttime = date('Y-m-d H:i:s', $cache['start_time']); + $uptime_duration = duration($cache['start_time']); + $size_vars = bsize($cache['mem_size']); - // check for possible empty values that are used in the templates - if (!isset($cache['file_upload_progress'])) { - $cache['file_upload_progress'] = $lng['logger']['unknown']; - } + // check for possible empty values that are used in the templates + if (! isset($cache['file_upload_progress'])) { + $cache['file_upload_progress'] = $lng['logger']['unknown']; + } - if (!isset($cache['num_expunges'])) { - $cache['num_expunges'] = $lng['logger']['unknown']; - } + if (! isset($cache['num_expunges'])) { + $cache['num_expunges'] = $lng['logger']['unknown']; + } - $runtimelines = ''; - foreach (ini_get_all('apcu') as $name => $v) { - $value = $v['local_value']; - eval("\$runtimelines.=\"" . getTemplate("settings/apcuinfo/runtime_line") . "\";"); - } + $runtimelines = ''; + foreach (ini_get_all('apcu') as $name => $v) { + $value = $v['local_value']; + eval("\$runtimelines.=\"" . \Froxlor\UI\Template::getTemplate("settings/apcuinfo/runtime_line") . "\";"); + } - $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'])); + $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'])); - // Fragementation: (freeseg - 1) / total_seg - $nseg = $freeseg = $fragsize = $freetotal = 0; - for ($i = 0; $i < $mem['num_seg']; $i++) { - $ptr = 0; - foreach ($mem['block_lists'][$i] as $block) { - if ($block['offset'] != $ptr) { - ++$nseg; - } - $ptr = $block['offset'] + $block['size']; - /* Only consider blocks <5M for the fragmentation % */ - if ($block['size'] < (5 * 1024 * 1024)) - $fragsize+=$block['size']; - $freetotal+=$block['size']; - } - $freeseg += count($mem['block_lists'][$i]); - } + // Fragementation: (freeseg - 1) / total_seg + $nseg = $freeseg = $fragsize = $freetotal = 0; + for ($i = 0; $i < $mem['num_seg']; $i ++) { + $ptr = 0; + foreach ($mem['block_lists'][$i] as $block) { + if ($block['offset'] != $ptr) { + ++ $nseg; + } + $ptr = $block['offset'] + $block['size']; + /* Only consider blocks <5M for the fragmentation % */ + if ($block['size'] < (5 * 1024 * 1024)) + $fragsize += $block['size']; + $freetotal += $block['size']; + } + $freeseg += count($mem['block_lists'][$i]); + } - if ($freeseg > 1) { - $frag = sprintf("%.2f%% (%s out of %s in %d fragments)", ($fragsize / $freetotal) * 100, bsize($fragsize), bsize($freetotal), $freeseg); - } else { - $frag = "0%"; - } + if ($freeseg > 1) { + $frag = sprintf("%.2f%% (%s out of %s in %d fragments)", ($fragsize / $freetotal) * 100, bsize($fragsize), bsize($freetotal), $freeseg); + } else { + $frag = "0%"; + } - foreach (ini_get_all('apcu') as $name => $v) { - $value = $v['local_value']; - } + foreach (ini_get_all('apcu') as $name => $v) { + $value = $v['local_value']; + } - $img_src1 = ''; - $img_src2 = ''; - $img_src3 = ''; - if (graphics_avail()) { - $img_src = $linker->getLink(array('section' => 'apcuinfo', 'page' => 'img1', 'action' => mt_rand(0, 1000000))); - eval("\$img_src1=\"" . getTemplate("settings/apcuinfo/img_line") . "\";"); - $img_src = $linker->getLink(array('section' => 'apcuinfo', 'page' => 'img2', 'action' => mt_rand(0, 1000000))); - eval("\$img_src2=\"" . getTemplate("settings/apcuinfo/img_line") . "\";"); - $img_src = $linker->getLink(array('section' => 'apcuinfo', 'page' => 'img3', 'action' => mt_rand(0, 1000000))); - eval("\$img_src3=\"" . getTemplate("settings/apcuinfo/img_line") . "\";"); - } + $img_src1 = ''; + $img_src2 = ''; + $img_src3 = ''; + if (graphics_avail()) { + $img_src = $linker->getLink(array( + 'section' => 'apcuinfo', + 'page' => 'img1', + 'action' => mt_rand(0, 1000000) + )); + eval("\$img_src1=\"" . \Froxlor\UI\Template::getTemplate("settings/apcuinfo/img_line") . "\";"); + $img_src = $linker->getLink(array( + 'section' => 'apcuinfo', + 'page' => 'img2', + 'action' => mt_rand(0, 1000000) + )); + eval("\$img_src2=\"" . \Froxlor\UI\Template::getTemplate("settings/apcuinfo/img_line") . "\";"); + $img_src = $linker->getLink(array( + 'section' => 'apcuinfo', + 'page' => 'img3', + 'action' => mt_rand(0, 1000000) + )); + eval("\$img_src3=\"" . \Froxlor\UI\Template::getTemplate("settings/apcuinfo/img_line") . "\";"); + } - eval("echo \"" . getTemplate("settings/apcuinfo/showinfo") . "\";"); - -} elseif ($page == 'img1' -) { + eval("echo \"" . \Froxlor\UI\Template::getTemplate("settings/apcuinfo/showinfo") . "\";"); +} elseif ($page == 'img1') { - $mem = apcu_sma_info(); + $mem = apcu_sma_info(); - $size = 460; - $image = imagecreate($size + 5, $size + 5); + $size = 460; + $image = imagecreate($size + 5, $size + 5); - $col_white = imagecolorallocate($image, 0xFF, 0xFF, 0xFF); - $col_red = imagecolorallocate($image, 0xD0, 0x60, 0x30); - $col_green = imagecolorallocate($image, 0x60, 0xF0, 0x60); - $col_black = imagecolorallocate($image, 0, 0, 0); + $col_white = imagecolorallocate($image, 0xFF, 0xFF, 0xFF); + $col_red = imagecolorallocate($image, 0xD0, 0x60, 0x30); + $col_green = imagecolorallocate($image, 0x60, 0xF0, 0x60); + $col_black = imagecolorallocate($image, 0, 0, 0); - imagecolortransparent($image, $col_white); + imagecolortransparent($image, $col_white); - $s = $mem['num_seg'] * $mem['seg_size']; - $a = $mem['avail_mem']; - $x = $y = $size / 2; - $fuzz = 0.000001; + $s = $mem['num_seg'] * $mem['seg_size']; + $a = $mem['avail_mem']; + $x = $y = $size / 2; + $fuzz = 0.000001; - // This block of code creates the pie chart. It is a lot more complex than you - // would expect because we try to visualize any memory fragmentation as well. - $angle_from = 0; - $string_placement = array(); - for ($i = 0; $i < $mem['num_seg']; $i++) { - $ptr = 0; - $free = $mem['block_lists'][$i]; - uasort($free, 'block_sort'); - foreach ($free as $block) { - if ($block['offset'] != $ptr) { // Used block - $angle_to = $angle_from + ($block['offset'] - $ptr) / $s; - if (($angle_to + $fuzz) > 1) - $angle_to = 1; - if (($angle_to * 360) - ($angle_from * 360) >= 1) { - fill_arc($image, $x, $y, $size, $angle_from * 360, $angle_to * 360, $col_black, $col_red); - if (($angle_to - $angle_from) > 0.05) { - array_push($string_placement, array($angle_from, $angle_to)); - } - } - $angle_from = $angle_to; - } - $angle_to = $angle_from + ($block['size']) / $s; - if (($angle_to + $fuzz) > 1) - $angle_to = 1; - if (($angle_to * 360) - ($angle_from * 360) >= 1) { - fill_arc($image, $x, $y, $size, $angle_from * 360, $angle_to * 360, $col_black, $col_green); - if (($angle_to - $angle_from) > 0.05) { - array_push($string_placement, array($angle_from, $angle_to)); - } - } - $angle_from = $angle_to; - $ptr = $block['offset'] + $block['size']; - } - if ($ptr < $mem['seg_size']) { // memory at the end - $angle_to = $angle_from + ($mem['seg_size'] - $ptr) / $s; - if (($angle_to + $fuzz) > 1) - $angle_to = 1; - fill_arc($image, $x, $y, $size, $angle_from * 360, $angle_to * 360, $col_black, $col_red); - if (($angle_to - $angle_from) > 0.05) { - array_push($string_placement, array($angle_from, $angle_to)); - } - } - } - foreach ($string_placement as $angle) { - text_arc($image, $x, $y, $size, $angle[0] * 360, $angle[1] * 360, $col_black, bsize($s * ($angle[1] - $angle[0]))); - } + // This block of code creates the pie chart. It is a lot more complex than you + // would expect because we try to visualize any memory fragmentation as well. + $angle_from = 0; + $string_placement = array(); + for ($i = 0; $i < $mem['num_seg']; $i ++) { + $ptr = 0; + $free = $mem['block_lists'][$i]; + uasort($free, 'block_sort'); + foreach ($free as $block) { + if ($block['offset'] != $ptr) { // Used block + $angle_to = $angle_from + ($block['offset'] - $ptr) / $s; + if (($angle_to + $fuzz) > 1) + $angle_to = 1; + if (($angle_to * 360) - ($angle_from * 360) >= 1) { + fill_arc($image, $x, $y, $size, $angle_from * 360, $angle_to * 360, $col_black, $col_red); + if (($angle_to - $angle_from) > 0.05) { + array_push($string_placement, array( + $angle_from, + $angle_to + )); + } + } + $angle_from = $angle_to; + } + $angle_to = $angle_from + ($block['size']) / $s; + if (($angle_to + $fuzz) > 1) + $angle_to = 1; + if (($angle_to * 360) - ($angle_from * 360) >= 1) { + fill_arc($image, $x, $y, $size, $angle_from * 360, $angle_to * 360, $col_black, $col_green); + if (($angle_to - $angle_from) > 0.05) { + array_push($string_placement, array( + $angle_from, + $angle_to + )); + } + } + $angle_from = $angle_to; + $ptr = $block['offset'] + $block['size']; + } + if ($ptr < $mem['seg_size']) { // memory at the end + $angle_to = $angle_from + ($mem['seg_size'] - $ptr) / $s; + if (($angle_to + $fuzz) > 1) + $angle_to = 1; + fill_arc($image, $x, $y, $size, $angle_from * 360, $angle_to * 360, $col_black, $col_red); + if (($angle_to - $angle_from) > 0.05) { + array_push($string_placement, array( + $angle_from, + $angle_to + )); + } + } + } + foreach ($string_placement as $angle) { + text_arc($image, $x, $y, $size, $angle[0] * 360, $angle[1] * 360, $col_black, bsize($s * ($angle[1] - $angle[0]))); + } - header("Content-type: image/png"); - imagepng($image); - exit; -} elseif ($page == 'img2' -) { + header("Content-type: image/png"); + imagepng($image); + exit(); +} elseif ($page == 'img2') { - $cache = apcu_cache_info(); + $cache = apcu_cache_info(); - $size = $horizontal_bar_size; - $image = imagecreate($size + 5, 140); + $size = $horizontal_bar_size; + $image = imagecreate($size + 5, 140); - $col_white = imagecolorallocate($image, 0xFF, 0xFF, 0xFF); - $col_red = imagecolorallocate($image, 0xD0, 0x60, 0x30); - $col_green = imagecolorallocate($image, 0x60, 0xF0, 0x60); - $col_black = imagecolorallocate($image, 0, 0, 0); + $col_white = imagecolorallocate($image, 0xFF, 0xFF, 0xFF); + $col_red = imagecolorallocate($image, 0xD0, 0x60, 0x30); + $col_green = imagecolorallocate($image, 0x60, 0xF0, 0x60); + $col_black = imagecolorallocate($image, 0, 0, 0); - imagecolortransparent($image, $col_white); + imagecolortransparent($image, $col_white); - $s = $cache['num_hits'] + $cache['num_misses']; - $a = $cache['num_hits']; + $s = $cache['num_hits'] + $cache['num_misses']; + $a = $cache['num_hits']; - fill_box($image, 1, 10, $s ? ($a * ($size - 21) / $s) : $size, 50, $col_black, $col_green/* , sprintf("%.1f%%", $s ? $cache['num_hits'] * 100 / $s : 0) */); - fill_box($image, 1, 80, $s ? max(4, ($s - $a) * ($size - 21) / $s) : $size, 50, $col_black, $col_red/* , sprintf("%.1f%%", $s ? $cache['num_misses'] * 100 / $s : 0) */); + fill_box($image, 1, 10, $s ? ($a * ($size - 21) / $s) : $size, 50, $col_black, $col_green /* , sprintf("%.1f%%", $s ? $cache['num_hits'] * 100 / $s : 0) */ + ); + fill_box($image, 1, 80, $s ? max(4, ($s - $a) * ($size - 21) / $s) : $size, 50, $col_black, $col_red /* , sprintf("%.1f%%", $s ? $cache['num_misses'] * 100 / $s : 0) */ + ); - header("Content-type: image/png"); - imagepng($image); - exit; -} elseif ($page == 'img3' -) { + header("Content-type: image/png"); + imagepng($image); + exit(); +} elseif ($page == 'img3') { - $mem = apcu_sma_info(); + $mem = apcu_sma_info(); - $size = $horizontal_bar_size; - $image = imagecreate($size, 70); + $size = $horizontal_bar_size; + $image = imagecreate($size, 70); - $col_white = imagecolorallocate($image, 0xFF, 0xFF, 0xFF); - $col_red = imagecolorallocate($image, 0xD0, 0x60, 0x30); - $col_green = imagecolorallocate($image, 0x60, 0xF0, 0x60); - $col_black = imagecolorallocate($image, 0, 0, 0); + $col_white = imagecolorallocate($image, 0xFF, 0xFF, 0xFF); + $col_red = imagecolorallocate($image, 0xD0, 0x60, 0x30); + $col_green = imagecolorallocate($image, 0x60, 0xF0, 0x60); + $col_black = imagecolorallocate($image, 0, 0, 0); - imagecolortransparent($image, $col_white); + imagecolortransparent($image, $col_white); - $s = $mem['num_seg'] * $mem['seg_size']; - $a = $mem['avail_mem']; - $x = 10; - $y = 0; + $s = $mem['num_seg'] * $mem['seg_size']; + $a = $mem['avail_mem']; + $x = 10; + $y = 0; - // This block of code creates the bar chart. It is a lot more complex than you - // would expect because we try to visualize any memory fragmentation as well. - for ($i = 0; $i < $mem['num_seg']; $i++) { - $ptr = 0; - $free = $mem['block_lists'][$i]; - uasort($free, 'block_sort'); - foreach ($free as $block) { - if ($block['offset'] != $ptr) { // Used block - $h = ($size - 5) * ($block['offset'] - $ptr) / $s; - if ($h > 0) { - fill_box($image, $y, $x, $h, 50, $col_black, $col_red); - } - $y+=$h; - } - $h = ($size - 5) * ($block['size']) / $s; - if ($h > 0) { - fill_box($image, $y, $x, $h, 50, $col_black, $col_green); - } - $y+=$h; - $ptr = $block['offset'] + $block['size']; - } - if ($ptr < $mem['seg_size']) { // memory at the end - $h = ($size - 5) * ($mem['seg_size'] - $ptr) / $s; - if ($h > 0) { - fill_box($image, $y, $x, $h, 50, $col_black, $col_red, bsize($mem['seg_size'] - $ptr), $j++); - } - } - } + // This block of code creates the bar chart. It is a lot more complex than you + // would expect because we try to visualize any memory fragmentation as well. + for ($i = 0; $i < $mem['num_seg']; $i ++) { + $ptr = 0; + $free = $mem['block_lists'][$i]; + uasort($free, 'block_sort'); + foreach ($free as $block) { + if ($block['offset'] != $ptr) { // Used block + $h = ($size - 5) * ($block['offset'] - $ptr) / $s; + if ($h > 0) { + fill_box($image, $y, $x, $h, 50, $col_black, $col_red); + } + $y += $h; + } + $h = ($size - 5) * ($block['size']) / $s; + if ($h > 0) { + fill_box($image, $y, $x, $h, 50, $col_black, $col_green); + } + $y += $h; + $ptr = $block['offset'] + $block['size']; + } + if ($ptr < $mem['seg_size']) { // memory at the end + $h = ($size - 5) * ($mem['seg_size'] - $ptr) / $s; + if ($h > 0) { + fill_box($image, $y, $x, $h, 50, $col_black, $col_red, bsize($mem['seg_size'] - $ptr), $j ++); + } + } + } - header("Content-type: image/png"); - imagepng($image); - exit; + header("Content-type: image/png"); + imagepng($image); + exit(); } -function graphics_avail() { - return extension_loaded('gd'); +function graphics_avail() +{ + return extension_loaded('gd'); } // pretty printer for byte values // -function bsize($s) { - foreach (array('', 'K', 'M', 'G') as $i => $k) { - if ($s < 1024) - break; - $s/=1024; - } - return sprintf("%5.1f %sBytes", $s, $k); +function bsize($s) +{ + foreach (array( + '', + 'K', + 'M', + 'G' + ) as $i => $k) { + if ($s < 1024) + break; + $s /= 1024; + } + return sprintf("%5.1f %sBytes", $s, $k); } -function duration($ts) { - global $time; - $years = (int) ((($time - $ts) / (7 * 86400)) / 52.177457); - $rem = (int) (($time - $ts) - ($years * 52.177457 * 7 * 86400)); - $weeks = (int) (($rem) / (7 * 86400)); - $days = (int) (($rem) / 86400) - $weeks * 7; - $hours = (int) (($rem) / 3600) - $days * 24 - $weeks * 7 * 24; - $mins = (int) (($rem) / 60) - $hours * 60 - $days * 24 * 60 - $weeks * 7 * 24 * 60; - $str = ''; - if ($years == 1) - $str .= "$years year, "; - if ($years > 1) - $str .= "$years years, "; - if ($weeks == 1) - $str .= "$weeks week, "; - if ($weeks > 1) - $str .= "$weeks weeks, "; - if ($days == 1) - $str .= "$days day,"; - if ($days > 1) - $str .= "$days days,"; - if ($hours == 1) - $str .= " $hours hour and"; - if ($hours > 1) - $str .= " $hours hours and"; - if ($mins == 1) - $str .= " 1 minute"; - else - $str .= " $mins minutes"; - return $str; +function duration($ts) +{ + global $time; + $years = (int) ((($time - $ts) / (7 * 86400)) / 52.177457); + $rem = (int) (($time - $ts) - ($years * 52.177457 * 7 * 86400)); + $weeks = (int) (($rem) / (7 * 86400)); + $days = (int) (($rem) / 86400) - $weeks * 7; + $hours = (int) (($rem) / 3600) - $days * 24 - $weeks * 7 * 24; + $mins = (int) (($rem) / 60) - $hours * 60 - $days * 24 * 60 - $weeks * 7 * 24 * 60; + $str = ''; + if ($years == 1) + $str .= "$years year, "; + if ($years > 1) + $str .= "$years years, "; + if ($weeks == 1) + $str .= "$weeks week, "; + if ($weeks > 1) + $str .= "$weeks weeks, "; + if ($days == 1) + $str .= "$days day,"; + if ($days > 1) + $str .= "$days days,"; + if ($hours == 1) + $str .= " $hours hour and"; + if ($hours > 1) + $str .= " $hours hours and"; + if ($mins == 1) + $str .= " 1 minute"; + else + $str .= " $mins minutes"; + return $str; } -function block_sort($array1, $array2) { - if ($array1['offset'] > $array2['offset']) { - return 1; - } else { - return -1; - } +function block_sort($array1, $array2) +{ + if ($array1['offset'] > $array2['offset']) { + return 1; + } else { + return - 1; + } } -function fill_arc($im, $centerX, $centerY, $diameter, $start, $end, $color1, $color2, $text = '', $placeindex = 0) { - $r = $diameter / 2; - $w = deg2rad((360 + $start + ($end - $start) / 2) % 360); +function fill_arc($im, $centerX, $centerY, $diameter, $start, $end, $color1, $color2, $text = '', $placeindex = 0) +{ + $r = $diameter / 2; + $w = deg2rad((360 + $start + ($end - $start) / 2) % 360); - - if (function_exists("imagefilledarc")) { - // exists only if GD 2.0.1 is available - imagefilledarc($im, $centerX + 1, $centerY + 1, $diameter, $diameter, $start, $end, $color1, IMG_ARC_PIE); - imagefilledarc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color2, IMG_ARC_PIE); - imagefilledarc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color1, IMG_ARC_NOFILL | IMG_ARC_EDGED); - } else { - imagearc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color2); - imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($start)) * $r, $centerY + sin(deg2rad($start)) * $r, $color2); - imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($start + 1)) * $r, $centerY + sin(deg2rad($start)) * $r, $color2); - imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($end - 1)) * $r, $centerY + sin(deg2rad($end)) * $r, $color2); - imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($end)) * $r, $centerY + sin(deg2rad($end)) * $r, $color2); - imagefill($im, $centerX + $r * cos($w) / 2, $centerY + $r * sin($w) / 2, $color2); - } - if ($text) { - if ($placeindex > 0) { - imageline($im, $centerX + $r * cos($w) / 2, $centerY + $r * sin($w) / 2, $diameter, $placeindex * 12, $color1); - imagestring($im, 4, $diameter, $placeindex * 12, $text, $color1); - } else { - imagestring($im, 4, $centerX + $r * cos($w) / 2, $centerY + $r * sin($w) / 2, $text, $color1); - } - } + if (function_exists("imagefilledarc")) { + // exists only if GD 2.0.1 is available + imagefilledarc($im, $centerX + 1, $centerY + 1, $diameter, $diameter, $start, $end, $color1, IMG_ARC_PIE); + imagefilledarc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color2, IMG_ARC_PIE); + imagefilledarc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color1, IMG_ARC_NOFILL | IMG_ARC_EDGED); + } else { + imagearc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color2); + imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($start)) * $r, $centerY + sin(deg2rad($start)) * $r, $color2); + imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($start + 1)) * $r, $centerY + sin(deg2rad($start)) * $r, $color2); + imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($end - 1)) * $r, $centerY + sin(deg2rad($end)) * $r, $color2); + imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($end)) * $r, $centerY + sin(deg2rad($end)) * $r, $color2); + imagefill($im, $centerX + $r * cos($w) / 2, $centerY + $r * sin($w) / 2, $color2); + } + if ($text) { + if ($placeindex > 0) { + imageline($im, $centerX + $r * cos($w) / 2, $centerY + $r * sin($w) / 2, $diameter, $placeindex * 12, $color1); + imagestring($im, 4, $diameter, $placeindex * 12, $text, $color1); + } else { + imagestring($im, 4, $centerX + $r * cos($w) / 2, $centerY + $r * sin($w) / 2, $text, $color1); + } + } } -function text_arc($im, $centerX, $centerY, $diameter, $start, $end, $color1, $text, $placeindex = 0) { - $r = $diameter / 2; - $w = deg2rad((360 + $start + ($end - $start) / 2) % 360); +function text_arc($im, $centerX, $centerY, $diameter, $start, $end, $color1, $text, $placeindex = 0) +{ + $r = $diameter / 2; + $w = deg2rad((360 + $start + ($end - $start) / 2) % 360); - if ($placeindex > 0) { - imageline($im, $centerX + $r * cos($w) / 2, $centerY + $r * sin($w) / 2, $diameter, $placeindex * 12, $color1); - imagestring($im, 4, $diameter, $placeindex * 12, $text, $color1); - } else { - imagestring($im, 4, $centerX + $r * cos($w) / 2, $centerY + $r * sin($w) / 2, $text, $color1); - } + if ($placeindex > 0) { + imageline($im, $centerX + $r * cos($w) / 2, $centerY + $r * sin($w) / 2, $diameter, $placeindex * 12, $color1); + imagestring($im, 4, $diameter, $placeindex * 12, $text, $color1); + } else { + imagestring($im, 4, $centerX + $r * cos($w) / 2, $centerY + $r * sin($w) / 2, $text, $color1); + } } -function fill_box($im, $x, $y, $w, $h, $color1, $color2, $text = '', $placeindex = '') { - global $col_black; - $x1 = $x + $w - 1; - $y1 = $y + $h - 1; +function fill_box($im, $x, $y, $w, $h, $color1, $color2, $text = '', $placeindex = '') +{ + global $col_black; + $x1 = $x + $w - 1; + $y1 = $y + $h - 1; - imagerectangle($im, $x, $y1, $x1 + 1, $y + 1, $col_black); - if ($y1 > $y) - imagefilledrectangle($im, $x, $y, $x1, $y1, $color2); - else - imagefilledrectangle($im, $x, $y1, $x1, $y, $color2); - imagerectangle($im, $x, $y1, $x1, $y, $color1); - if ($text) { - if ($placeindex > 0) { + imagerectangle($im, $x, $y1, $x1 + 1, $y + 1, $col_black); + if ($y1 > $y) + imagefilledrectangle($im, $x, $y, $x1, $y1, $color2); + else + imagefilledrectangle($im, $x, $y1, $x1, $y, $color2); + imagerectangle($im, $x, $y1, $x1, $y, $color1); + if ($text) { + if ($placeindex > 0) { - if ($placeindex < 16) { - $px = 5; - $py = $placeindex * 12 + 6; - imagefilledrectangle($im, $px + 90, $py + 3, $px + 90 - 4, $py - 3, $color2); - imageline($im, $x, $y + $h / 2, $px + 90, $py, $color2); - imagestring($im, 2, $px, $py - 6, $text, $color1); - } else { - if ($placeindex < 31) { - $px = $x + 40 * 2; - $py = ($placeindex - 15) * 12 + 6; - } else { - $px = $x + 40 * 2 + 100 * intval(($placeindex - 15) / 15); - $py = ($placeindex % 15) * 12 + 6; - } - imagefilledrectangle($im, $px, $py + 3, $px - 4, $py - 3, $color2); - imageline($im, $x + $w, $y + $h / 2, $px, $py, $color2); - imagestring($im, 2, $px + 2, $py - 6, $text, $color1); - } - } else { - imagestring($im, 4, $x + 5, $y1 - 16, $text, $color1); - } - } + if ($placeindex < 16) { + $px = 5; + $py = $placeindex * 12 + 6; + imagefilledrectangle($im, $px + 90, $py + 3, $px + 90 - 4, $py - 3, $color2); + imageline($im, $x, $y + $h / 2, $px + 90, $py, $color2); + imagestring($im, 2, $px, $py - 6, $text, $color1); + } else { + if ($placeindex < 31) { + $px = $x + 40 * 2; + $py = ($placeindex - 15) * 12 + 6; + } else { + $px = $x + 40 * 2 + 100 * intval(($placeindex - 15) / 15); + $py = ($placeindex % 15) * 12 + 6; + } + imagefilledrectangle($im, $px, $py + 3, $px - 4, $py - 3, $color2); + imageline($im, $x + $w, $y + $h / 2, $px, $py, $color2); + imagestring($im, 2, $px + 2, $py - 6, $text, $color1); + } + } else { + imagestring($im, 4, $x + 5, $y1 - 16, $text, $color1); + } + } } diff --git a/admin_autoupdate.php b/admin_autoupdate.php index a6d47dc2..8ef41962 100644 --- a/admin_autoupdate.php +++ b/admin_autoupdate.php @@ -17,84 +17,92 @@ * @since 0.9.35 * */ - define('AREA', 'admin'); require './lib/init.php'; +use Froxlor\Http\HttpClient; + // define update-uri -define('UPDATE_URI', "https://version.froxlor.org/Froxlor/legacy/" . $version); +define('UPDATE_URI', "https://version.froxlor.org/Froxlor/api/" . $version); define('RELEASE_URI', "https://autoupdate.froxlor.org/froxlor-{version}.zip"); define('CHECKSUM_URI', "https://autoupdate.froxlor.org/froxlor-{version}.zip.sha256"); -// check for allow_url_fopen -if (ini_get('allow_url_fopen') === false) { - redirectTo($filename, array('s' => $s, 'page' => 'error', 'errno' => 1)); +// check for archive-stuff +if (! extension_loaded('zip')) { + \Froxlor\UI\Response::redirectTo($filename, array( + 's' => $s, + 'page' => 'error', + 'errno' => 2 + )); } -// check for archive-stuff -if (function_exists('gzopen') === false) { - redirectTo($filename, array('s' => $s, 'page' => 'error', 'errno' => 2)); +// 0.10.x requires 7.0 at least +if (version_compare("7.0.0", PHP_VERSION, ">=")) { + \Froxlor\UI\Response::redirectTo($filename, array( + 's' => $s, + 'page' => 'error', + 'errno' => 10 + )); } // display initial version check if ($page == 'overview') { // log our actions - $log->logAction(ADM_ACTION, LOG_NOTICE, "checking auto-update"); + $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "checking auto-update"); // check for new version - $latestversion = @file(UPDATE_URI); + try { + $latestversion = HttpClient::urlGet(UPDATE_URI, true, 3); + } catch (\Exception $e) { + \Froxlor\UI\Response::dynamic_error("Version-check currently unavailable, please try again later"); + } + $latestversion = explode('|', $latestversion); - if (isset($latestversion[0])) { - $latestversion = explode('|', $latestversion[0]); + if (is_array($latestversion) && count($latestversion) >= 1) { + $_version = $latestversion[0]; + $_message = isset($latestversion[1]) ? $latestversion[1] : ''; + $_link = isset($latestversion[2]) ? $latestversion[2] : htmlspecialchars($filename . '?s=' . urlencode($s) . '&page=' . urlencode($page) . '&lookfornewversion=yes'); - if (is_array($latestversion) - && count($latestversion) >= 1 - ) { - $_version = $latestversion[0]; - $_message = isset($latestversion[1]) ? $latestversion[1] : ''; - $_link = isset($latestversion[2]) ? $latestversion[2] : htmlspecialchars($filename . '?s=' . urlencode($s) . '&page=' . urlencode($page) . '&lookfornewversion=yes'); + // add the branding so debian guys are not gettings confused + // about their version-number + $version_label = $_version . $branding; + $version_link = $_link; + $message_addinfo = $_message; - // add the branding so debian guys are not gettings confused - // about their version-number - $version_label = $_version.$branding; - $version_link = $_link; - $message_addinfo = $_message; + // not numeric -> error-message + if (! preg_match('/^((\d+\\.)(\d+\\.)(\d+\\.)?(\d+)?(\-(svn|dev|rc)(\d+))?)$/', $_version)) { + // check for customized version to not output + // "There is a newer version of froxlor" besides the error-message + \Froxlor\UI\Response::redirectTo($filename, array( + 's' => $s, + 'page' => 'error', + 'errno' => 3 + )); + } elseif (\Froxlor\Froxlor::versionCompare2($version, $_version) == - 1) { + // there is a newer version - yay + $isnewerversion = 1; + } else { + // nothing new + $isnewerversion = 0; + } - // not numeric -> error-message - if (!preg_match('/^((\d+\\.)(\d+\\.)(\d+\\.)?(\d+)?(\-(svn|dev|rc)(\d+))?)$/', $_version)) { - // check for customized version to not output - // "There is a newer version of froxlor" besides the error-message - redirectTo($filename, array('s' => $s, 'page' => 'error', 'errno' => 3)); - } elseif (version_compare2($version, $_version) == -1) { - // there is a newer version - yay - $isnewerversion = 1; - } else { - // nothing new - $isnewerversion = 0; - } - - // anzeige über version-status mit ggfls. formular - // zum update schritt #1 -> download - if ($isnewerversion == 1) { - $text = 'There is a newer version available. Update to version '.$_version.' now?
(Your current version is: '.$version.')'; - $hiddenparams = ''; - $yesfile = $filename.'?s='.$s.'&page=getdownload'; - eval("echo \"" . getTemplate("misc/question_yesno", true) . "\";"); - exit; - } - elseif ($isnewerversion == 0) { - // all good - standard_success ('noupdatesavail'); - } else { - standard_error ('customized_version'); - } + // anzeige über version-status mit ggfls. formular + // zum update schritt #1 -> download + if ($isnewerversion == 1) { + $text = 'There is a newer version available. Update to version ' . $_version . ' now?
(Your current version is: ' . $version . ')'; + $hiddenparams = ''; + $yesfile = $filename . '?s=' . $s . '&page=getdownload'; + eval("echo \"" . \Froxlor\UI\Template::getTemplate("misc/question_yesno", true) . "\";"); + exit(); + } elseif ($isnewerversion == 0) { + // all good + \Froxlor\UI\Response::standard_success('noupdatesavail'); + } else { + \Froxlor\UI\Response::standard_error('customized_version'); } } - // error (something weird came from version.froxlor.org) - redirectTo($filename, array('s' => $s, 'page' => 'error', 'errno' => 5)); -} -// download the new archive +} // download the new archive elseif ($page == 'getdownload') { // retrieve the new version from the form @@ -107,96 +115,113 @@ elseif ($page == 'getdownload') { $toLoad = str_replace('{version}', $newversion, RELEASE_URI); $toCheck = str_replace('{version}', $newversion, CHECKSUM_URI); - // get archive data - $newArchive = @file_get_contents($toLoad); - // check for local destination folder - if (!is_dir(FROXLOR_INSTALL_DIR.'/updates/')) { - mkdir(FROXLOR_INSTALL_DIR.'/updates/'); + if (! is_dir(\Froxlor\Froxlor::getInstallDir() . '/updates/')) { + mkdir(\Froxlor\Froxlor::getInstallDir() . '/updates/'); } // name archive - $localArchive = FROXLOR_INSTALL_DIR.'/updates/'.basename($toLoad); + $localArchive = \Froxlor\Froxlor::getInstallDir() . '/updates/' . basename($toLoad); - $log->logAction(ADM_ACTION, LOG_NOTICE, "Downloading ".$toLoad." to ".$localArchive); + $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "Downloading " . $toLoad . " to " . $localArchive); // remove old archive if (file_exists($localArchive)) { - @unlink($localArchive); + @unlink($localArchive); } - // store archive - $fh = fopen($localArchive, 'w'); - if (!fwrite($fh, $newArchive)) { - redirectTo($filename, array('s' => $s, 'page' => 'error', 'errno' => 4)); + // get archive data + try { + HttpClient::fileGet($toLoad, $localArchive); + } catch (Exception $e) { + \Froxlor\UI\Response::redirectTo($filename, array( + 's' => $s, + 'page' => 'error', + 'errno' => 4 + )); } - // close file-handle - fclose($fh); - // validate the integrity of the downloaded file - $_shouldsum = @file_get_contents($toCheck); - if (!empty($_shouldsum)) { - $_t = explode(" ", $_shouldsum); - $shouldsum = $_t[0]; + $_shouldsum = HttpClient::urlGet($toCheck); + if (! empty($_shouldsum)) { + $_t = explode(" ", $_shouldsum); + $shouldsum = $_t[0]; } else { - $shouldsum = null; + $shouldsum = null; } $filesum = hash_file('sha256', $localArchive); if ($filesum != $shouldsum) { - redirectTo($filename, array('s' => $s, 'page' => 'error', 'errno' => 9)); + \Froxlor\UI\Response::redirectTo($filename, array( + 's' => $s, + 'page' => 'error', + 'errno' => 9 + )); } // to the next step - redirectTo($filename, array('s' => $s, 'page' => 'extract', 'archive' => basename($localArchive))); + \Froxlor\UI\Response::redirectTo($filename, array( + 's' => $s, + 'page' => 'extract', + 'archive' => basename($localArchive) + )); } - redirectTo($filename, array('s' => $s, 'page' => 'error', 'errno' => 6)); -} -// extract and install new version + \Froxlor\UI\Response::redirectTo($filename, array( + 's' => $s, + 'page' => 'error', + 'errno' => 6 + )); +} // extract and install new version elseif ($page == 'extract') { $toExtract = isset($_GET['archive']) ? $_GET['archive'] : null; - $localArchive = FROXLOR_INSTALL_DIR.'/updates/'.$toExtract; + $localArchive = \Froxlor\Froxlor::getInstallDir() . '/updates/' . $toExtract; - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { + if (isset($_POST['send']) && $_POST['send'] == 'send') { // decompress from zip - $zip = new ZipArchive; + $zip = new ZipArchive(); $res = $zip->open($localArchive); if ($res === true) { - $log->logAction(ADM_ACTION, LOG_NOTICE, "Extracting ".$localArchive." to ".dirname(FROXLOR_INSTALL_DIR)); - $zip->extractTo(dirname(FROXLOR_INSTALL_DIR)); + $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "Extracting " . $localArchive . " to " . \Froxlor\Froxlor::getInstallDir()); + $zip->extractTo(\Froxlor\Froxlor::getInstallDir()); $zip->close(); // success - remove unused archive @unlink($localArchive); + // wait a bit before we redirect to be sure + sleep(2); } else { // error - redirectTo($filename, array('s' => $s, 'page' => 'error', 'errno' => 8)); + \Froxlor\UI\Response::redirectTo($filename, array( + 's' => $s, + 'page' => 'error', + 'errno' => 8 + )); } // redirect to update-page? - redirectTo('admin_updates.php', array('s' => $s)); + \Froxlor\UI\Response::redirectTo('admin_updates.php', array( + 's' => $s + )); } - if (!file_exists($localArchive)) { - redirectTo($filename, array('s' => $s, 'page' => 'error', 'errno' => 7)); + if (! file_exists($localArchive)) { + \Froxlor\UI\Response::redirectTo($filename, array( + 's' => $s, + 'page' => 'error', + 'errno' => 7 + )); } - $text = 'Extract downloaded archive "'.$toExtract.'"?'; + $text = 'Extract downloaded archive "' . $toExtract . '"?'; $hiddenparams = ''; - $yesfile = $filename.'?s='.$s.'&page=extract&archive='.$toExtract; - eval("echo \"" . getTemplate("misc/question_yesno", true) . "\";"); -} - -// display error + $yesfile = $filename . '?s=' . $s . '&page=extract&archive=' . $toExtract; + eval("echo \"" . \Froxlor\UI\Template::getTemplate("misc/question_yesno", true) . "\";"); +} // display error elseif ($page == 'error') { // retrieve error-number via url-parameter - $errno = isset($_GET['errno']) ? (int)$_GET['errno'] : 0; + $errno = isset($_GET['errno']) ? (int) $_GET['errno'] : 0; - // 1 = no allow_url_fopen // 2 = no Zlib // 3 = custom version detected // 4 = could not store archive to local hdd @@ -205,5 +230,6 @@ elseif ($page == 'error') { // 7 = local archive does not exist // 8 = could not extract archive // 9 = checksum mismatch - standard_error ('autoupdate_'.$errno); + // 10 = ' => $sql['user'], - '' => 'MYSQL_PASSWORD', - '' => $sql['db'], - '' => $sql['host'], - '' => isset($sql['socket']) ? $sql['socket'] : null, - '' => Settings::Get('system.hostname'), - '' => Settings::Get('system.ipaddress'), - '' => Settings::Get('system.nameservers'), - '' => Settings::Get('system.vmail_homedir'), - '' => Settings::Get('system.vmail_uid'), - '' => Settings::Get('system.vmail_gid'), - '' => (Settings::Get('system.use_ssl') == '1') ? 'imaps pop3s' : '', - '' => (Settings::Get('system.mod_fcgid_tmpdir') != '') ? makeCorrectDir(Settings::Get('system.mod_fcgid_tmpdir')) : '/tmp/', - '' => makeCorrectDir(FROXLOR_INSTALL_DIR), - '' => makeCorrectDir(Settings::Get('system.bindconf_directory')), - '' => Settings::Get('system.apachereload_command'), - '' => makeCorrectDir(Settings::Get('system.logfiles_directory')), - '' => makeCorrectDir(Settings::Get('phpfpm.fastcgi_ipcdir')), - '' => Settings::Get('system.httpgroup') - ); - - // get distro from URL param - $distribution = (isset($_GET['distribution']) && $_GET['distribution'] != 'choose') ? $_GET['distribution'] : ""; - $service = (isset($_GET['service']) && $_GET['service'] != 'choose') ? $_GET['service'] : ""; - $daemon = (isset($_GET['daemon']) && $_GET['daemon'] != 'choose') ? $_GET['daemon'] : ""; - $distributions_select = ""; - $services_select = ""; - $daemons_select = ""; - - $configfiles = ""; - $services = ""; - $daemons = ""; - - $config_dir = makeCorrectDir(FROXLOR_INSTALL_DIR . '/lib/configfiles/'); - - if ($distribution != "") { - // create configparser object - $configfiles = new ConfigParser($config_dir . '/' . $distribution . ".xml"); - - // get distro-info - $dist_display = getCompleteDistroName($configfiles); - - // get all the services from the distro - $services = $configfiles->getServices(); - - if ($service != "") { - - $daemons = $services[$service]->getDaemons(); - - if ($daemon == "") { - foreach ($daemons as $di => $dd) { - $title = $dd->title; - if ($dd->default) { - $title = $title." (".strtolower($lng['panel']['default']).")"; - } - $daemons_select .= makeoption($title, $di); - } - } - } else { - foreach ($services as $si => $sd) { - $services_select .= makeoption($sd->title, $si); - } - } - } else { - - // show list of available distro's - $distros = glob($config_dir . '*.xml'); - // tmp array - $distributions_select_data = array(); - // read in all the distros - foreach ($distros as $_distribution) { - // get configparser object - $dist = new ConfigParser($_distribution); - // get distro-info - $dist_display = getCompleteDistroName($dist); - // store in tmp array - $distributions_select_data[$dist_display] = str_replace(".xml", "", strtolower(basename($_distribution))); - } - - // sort by distribution name - ksort($distributions_select_data); - - foreach ($distributions_select_data as $dist_display => $dist_index) { - // create select-box-option - $distributions_select .= makeoption($dist_display, $dist_index); - } - } - - if ($distribution != "" && $service != "" && $daemon != "") { - - $confarr = $daemons[$daemon]->getConfig(); - - $configpage = ''; - - $distro_editor = $configfiles->distributionEditor; +use Froxlor\Settings; - $commands_pre = ""; - $commands_file = ""; - $commands_post = ""; - - $lasttype = ''; - $commands = ''; - foreach ($confarr as $idx => $action) { - if ($lasttype != '' && $lasttype != $action['type']) { - $commands = trim($commands); - $numbrows = count(explode("\n", $commands)); - eval("\$configpage.=\"" . getTemplate("configfiles/configfiles_commands") . "\";"); - $lasttype = ''; - $commands = ''; - } - switch ($action['type']) { - case "install": - $commands .= $action['content'] . "\n"; - $lasttype = "install"; - break; - case "command": - $commands .= $action['content'] . "\n"; - $lasttype = "command"; - break; - case "file": - if (array_key_exists('content', $action)) { - $commands_file = getFileContentContainer($action['content'], $replace_arr, $action['name'], $distro_editor); - } elseif (array_key_exists('subcommands', $action)) { - foreach ($action['subcommands'] as $fileaction) { - if (array_key_exists('execute', $fileaction) && $fileaction['execute'] == "pre") { - $commands_pre .= $fileaction['content'] . "\n"; - } elseif (array_key_exists('execute', $fileaction) && $fileaction['execute'] == "post") { - $commands_post .= $fileaction['content'] . "\n"; - } elseif ($fileaction['type'] == 'file') { - $commands_file = getFileContentContainer($fileaction['content'], $replace_arr, $action['name'], $distro_editor); - } - } - } - $realname = $action['name']; - $commands = trim($commands_pre); - if ($commands != "") { - $numbrows = count(explode("\n", $commands)); - eval("\$commands_pre=\"" . getTemplate("configfiles/configfiles_commands") . "\";"); - } - $commands = trim($commands_post); - if ($commands != "") { - $numbrows = count(explode("\n", $commands)); - eval("\$commands_post=\"" . getTemplate("configfiles/configfiles_commands") . "\";"); - } - eval("\$configpage.=\"" . getTemplate("configfiles/configfiles_subfileblock") . "\";"); - $commands = ''; - $commands_pre = ''; - $commands_post = ''; - break; - } - } - $commands = trim($commands); - if ($commands != '') { - $numbrows = count(explode("\n", $commands)); - eval("\$configpage.=\"" . getTemplate("configfiles/configfiles_commands") . "\";"); - } - eval("echo \"" . getTemplate("configfiles/configfiles") . "\";"); - } else { - eval("echo \"" . getTemplate("configfiles/wizard") . "\";"); - } +if ($userinfo['change_serversettings'] == '1') { + + if ($action == 'setconfigured') { + Settings::Set('panel.is_configured', '1', true); + \Froxlor\UI\Response::redirectTo('admin_configfiles.php', array( + 's' => $s + )); + } + + $customer_tmpdir = '/tmp/'; + if (Settings::Get('system.mod_fcgid') == '1' && Settings::Get('system.mod_fcgid_tmpdir') != '') { + $customer_tmpdir = Settings::Get('system.mod_fcgid_tmpdir'); + } elseif (Settings::Get('phpfpm.enabled') == '1' && Settings::Get('phpfpm.tmpdir') != '') { + $customer_tmpdir = Settings::Get('phpfpm.tmpdir'); + } + + // try to convert namserver hosts to ip's + $ns_ips = ""; + if (Settings::Get('system.nameservers') != '') { + $nameservers = explode(',', Settings::Get('system.nameservers')); + foreach ($nameservers as $nameserver) { + $nameserver = trim($nameserver); + $nameserver_ips = \Froxlor\PhpHelper::gethostbynamel6($nameserver); + if (is_array($nameserver_ips) && count($nameserver_ips) > 0) { + $ns_ips .= implode(",", $nameserver_ips); + } + } + } + + $replace_arr = Array( + '' => $sql['user'], + '' => 'FROXLOR_MYSQL_PASSWORD', + '' => $sql['db'], + '' => $sql['host'], + '' => isset($sql['socket']) ? $sql['socket'] : null, + '' => Settings::Get('system.hostname'), + '' => 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'), + '' => (Settings::Get('system.use_ssl') == '1') ? 'imaps pop3s' : '', + '' => \Froxlor\FileDir::makeCorrectDir($customer_tmpdir), + '' => \Froxlor\FileDir::makeCorrectDir(\Froxlor\Froxlor::getInstallDir()), + '' => \Froxlor\FileDir::makeCorrectDir(Settings::Get('system.bindconf_directory')), + '' => Settings::Get('system.apachereload_command'), + '' => \Froxlor\FileDir::makeCorrectDir(Settings::Get('system.logfiles_directory')), + '' => \Froxlor\FileDir::makeCorrectDir(Settings::Get('phpfpm.fastcgi_ipcdir')), + '' => Settings::Get('system.httpgroup') + ); + + // get distro from URL param + $distribution = (isset($_GET['distribution']) && $_GET['distribution'] != 'choose') ? $_GET['distribution'] : ""; + $service = (isset($_GET['service']) && $_GET['service'] != 'choose') ? $_GET['service'] : ""; + $daemon = (isset($_GET['daemon']) && $_GET['daemon'] != 'choose') ? $_GET['daemon'] : ""; + $distributions_select = ""; + $services_select = ""; + $daemons_select = ""; + + $configfiles = ""; + $services = ""; + $daemons = ""; + + $config_dir = \Froxlor\FileDir::makeCorrectDir(\Froxlor\Froxlor::getInstallDir() . '/lib/configfiles/'); + + if ($distribution != "") { + + if (! file_exists($config_dir . '/' . $distribution . ".xml")) { + trigger_error("Unknown distribution, are you playing around with the URL?"); + exit(); + } + + // create configparser object + $configfiles = new \Froxlor\Config\ConfigParser($config_dir . '/' . $distribution . ".xml"); + + // get distro-info + $dist_display = getCompleteDistroName($configfiles); + + // get all the services from the distro + $services = $configfiles->getServices(); + + if ($service != "") { + + if (! isset($services[$service])) { + trigger_error("Unknown service, are you playing around with the URL?"); + exit(); + } + + $daemons = $services[$service]->getDaemons(); + + if ($daemon == "") { + foreach ($daemons as $di => $dd) { + $title = $dd->title; + if ($dd->default) { + $title = $title . " (" . strtolower($lng['panel']['default']) . ")"; + } + $daemons_select .= \Froxlor\UI\HTML::makeoption($title, $di); + } + } + } else { + foreach ($services as $si => $sd) { + $services_select .= \Froxlor\UI\HTML::makeoption($sd->title, $si); + } + } + } else { + + // show list of available distro's + $distros = glob($config_dir . '*.xml'); + // tmp array + $distributions_select_data = array(); + // read in all the distros + foreach ($distros as $_distribution) { + // get configparser object + $dist = new \Froxlor\Config\ConfigParser($_distribution); + // get distro-info + $dist_display = getCompleteDistroName($dist); + // store in tmp array + $distributions_select_data[$dist_display] = str_replace(".xml", "", strtolower(basename($_distribution))); + } + + // sort by distribution name + ksort($distributions_select_data); + + foreach ($distributions_select_data as $dist_display => $dist_index) { + // create select-box-option + $distributions_select .= \Froxlor\UI\HTML::makeoption($dist_display, $dist_index); + } + } + + if ($distribution != "" && $service != "" && $daemon != "") { + + if (! isset($daemons[$daemon])) { + trigger_error("Unknown daemon, are you playing around with the URL?"); + exit(); + } + + $confarr = $daemons[$daemon]->getConfig(); + + $configpage = ''; + + $distro_editor = $configfiles->distributionEditor; + + $commands_pre = ""; + $commands_file = ""; + $commands_post = ""; + + $lasttype = ''; + $commands = ''; + foreach ($confarr as $_action) { + if ($lasttype != '' && $lasttype != $_action['type']) { + $commands = trim($commands); + $numbrows = count(explode("\n", $commands)); + eval("\$configpage.=\"" . \Froxlor\UI\Template::getTemplate("configfiles/configfiles_commands") . "\";"); + $lasttype = ''; + $commands = ''; + } + switch ($_action['type']) { + case "install": + $commands .= strtr($_action['content'], $replace_arr) . "\n"; + $lasttype = "install"; + break; + case "command": + $commands .= strtr($_action['content'], $replace_arr) . "\n"; + $lasttype = "command"; + break; + case "file": + if (array_key_exists('content', $_action)) { + $commands_file = getFileContentContainer($_action['content'], $replace_arr, $_action['name'], $distro_editor); + } elseif (array_key_exists('subcommands', $_action)) { + foreach ($_action['subcommands'] as $fileaction) { + if (array_key_exists('execute', $fileaction) && $fileaction['execute'] == "pre") { + $commands_pre .= $fileaction['content'] . "\n"; + } elseif (array_key_exists('execute', $fileaction) && $fileaction['execute'] == "post") { + $commands_post .= $fileaction['content'] . "\n"; + } elseif ($fileaction['type'] == 'file') { + $commands_file = getFileContentContainer($fileaction['content'], $replace_arr, $_action['name'], $distro_editor); + } + } + } + $realname = $_action['name']; + $commands = trim($commands_pre); + if ($commands != "") { + $numbrows = count(explode("\n", $commands)); + eval("\$commands_pre=\"" . \Froxlor\UI\Template::getTemplate("configfiles/configfiles_commands") . "\";"); + } + $commands = trim($commands_post); + if ($commands != "") { + $numbrows = count(explode("\n", $commands)); + eval("\$commands_post=\"" . \Froxlor\UI\Template::getTemplate("configfiles/configfiles_commands") . "\";"); + } + eval("\$configpage.=\"" . \Froxlor\UI\Template::getTemplate("configfiles/configfiles_subfileblock") . "\";"); + $commands = ''; + $commands_pre = ''; + $commands_post = ''; + break; + } + } + $commands = trim($commands); + if ($commands != '') { + $numbrows = count(explode("\n", $commands)); + eval("\$configpage.=\"" . \Froxlor\UI\Template::getTemplate("configfiles/configfiles_commands") . "\";"); + } + eval("echo \"" . \Froxlor\UI\Template::getTemplate("configfiles/configfiles") . "\";"); + } else { + $basedir = \Froxlor\Froxlor::getInstallDir(); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("configfiles/wizard") . "\";"); + } } else { - die('not allowed to see this page'); - // redirect or similar here + \Froxlor\UI\Response::redirectTo('admin_index.php', array( + 's' => $s + )); } // helper functions function getFileContentContainer($file_content, &$replace_arr, $realname, $distro_editor) { - $files = ""; - $file_content = trim($file_content); - if ($file_content != '') { - $file_content = strtr($file_content, $replace_arr); - $file_content = htmlspecialchars($file_content); - $numbrows = count(explode("\n", $file_content)); - eval("\$files=\"" . getTemplate("configfiles/configfiles_file") . "\";"); - } - return $files; + $files = ""; + $file_content = trim($file_content); + if ($file_content != '') { + $file_content = strtr($file_content, $replace_arr); + $file_content = htmlspecialchars($file_content); + $numbrows = count(explode("\n", $file_content)); + eval("\$files=\"" . \Froxlor\UI\Template::getTemplate("configfiles/configfiles_file") . "\";"); + } + return $files; } function getCompleteDistroName($cparser) { - // get distro-info - $dist_display = $cparser->distributionName; - if ($cparser->distributionCodename != '') { - $dist_display .= " ".$cparser->distributionCodename; - } - if ($cparser->distributionVersion != '') { - $dist_display .= " (" . $cparser->distributionVersion . ")"; - } - if ($cparser->deprecated) { - $dist_display .= " [deprecated]"; - } - return $dist_display; + // get distro-info + $dist_display = $cparser->distributionName; + if ($cparser->distributionCodename != '') { + $dist_display .= " " . $cparser->distributionCodename; + } + if ($cparser->distributionVersion != '') { + $dist_display .= " (" . $cparser->distributionVersion . ")"; + } + if ($cparser->deprecated) { + $dist_display .= " [deprecated]"; + } + return $dist_display; } diff --git a/admin_cronjobs.php b/admin_cronjobs.php index 8cd17276..db528f09 100644 --- a/admin_cronjobs.php +++ b/admin_cronjobs.php @@ -14,95 +14,90 @@ * @package Panel * */ - define('AREA', 'admin'); require './lib/init.php'; +use Froxlor\Api\Commands\Cronjobs; + if (isset($_POST['id'])) { $id = intval($_POST['id']); -} elseif(isset($_GET['id'])) { +} elseif (isset($_GET['id'])) { $id = intval($_GET['id']); } if ($page == 'cronjobs' || $page == 'overview') { if ($action == '') { - $log->logAction(ADM_ACTION, LOG_NOTICE, 'viewed admin_cronjobs'); + $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, 'viewed admin_cronjobs'); $fields = array( + 'c.module' => 'Module', 'c.lastrun' => $lng['cron']['lastrun'], 'c.interval' => $lng['cron']['interval'], 'c.isactive' => $lng['cron']['isactive'] ); - $paging = new paging($userinfo, TABLE_PANEL_CRONRUNS, $fields); + try { + // get total count + $json_result = Cronjobs::getLocal($userinfo)->listingCount(); + $result = json_decode($json_result, true)['data']; + // initialize pagination and filtering + $paging = new \Froxlor\UI\Pagination($userinfo, $fields, $result); + // get list + $json_result = Cronjobs::getLocal($userinfo, $paging->getApiCommandParams())->listing(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; $crons = ''; - $result_stmt = Database::prepare("SELECT `c`.* FROM `" . TABLE_PANEL_CRONRUNS . "` `c` ORDER BY `module` ASC, `cronfile` ASC"); - Database::pexecute($result_stmt); - $paging->setEntries(Database::num_rows()); $sortcode = $paging->getHtmlSortCode($lng); $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); $searchcode = $paging->getHtmlSearchCode($lng); $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); - $i = 0; $count = 0; $cmod = ''; - while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { + foreach ($result['list'] as $row) { if ($cmod != $row['module']) { $_mod = explode("/", $row['module']); $module = ucfirst($_mod[1]); - eval("\$crons.=\"" . getTemplate('cronjobs/cronjobs_cronjobmodule') . "\";"); + eval("\$crons.=\"" . \Froxlor\UI\Template::getTemplate('cronjobs/cronjobs_cronjobmodule') . "\";"); $cmod = $row['module']; } - if ($paging->checkDisplay($i)) { - $row = htmlentities_array($row); + $row = \Froxlor\PhpHelper::htmlentitiesArray($row); + $row['lastrun'] = date('d.m.Y H:i', $row['lastrun']); + $row['isactive'] = ((int) $row['isactive'] == 1) ? $lng['panel']['yes'] : $lng['panel']['no']; + $description = $lng['crondesc'][$row['desc_lng_key']]; - $row['lastrun'] = date('d.m.Y H:i', $row['lastrun']); - $row['isactive'] = ((int)$row['isactive'] == 1) ? $lng['panel']['yes'] : $lng['panel']['no']; - - $description = $lng['crondesc'][$row['desc_lng_key']]; - - eval("\$crons.=\"" . getTemplate('cronjobs/cronjobs_cronjob') . "\";"); - $count++; - } - - $i++; + eval("\$crons.=\"" . \Froxlor\UI\Template::getTemplate('cronjobs/cronjobs_cronjob') . "\";"); + $count ++; } - eval("echo \"" . getTemplate('cronjobs/cronjobs') . "\";"); - + eval("echo \"" . \Froxlor\UI\Template::getTemplate('cronjobs/cronjobs') . "\";"); } elseif ($action == 'new') { /* * @TODO later */ } elseif ($action == 'edit' && $id != 0) { - $result_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_CRONRUNS . "` WHERE `id`= :id"); - Database::pexecute($result_stmt, array('id' => $id)); - $result = $result_stmt->fetch(PDO::FETCH_ASSOC); + try { + $json_result = Cronjobs::getLocal($userinfo, array( + 'id' => $id + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; if ($result['cronfile'] != '') { if (isset($_POST['send']) && $_POST['send'] == 'send') { - $isactive = isset($_POST['isactive']) ? 1 : 0; - $interval_value = validate($_POST['interval_value'], 'interval_value', '/^([0-9]+)$/Di', 'stringisempty'); - $interval_interval = validate($_POST['interval_interval'], 'interval_interval'); - - if ($isactive != 1) { - $isactive = 0; + try { + Cronjobs::getLocal($userinfo, $_POST)->update(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } - - $interval = $interval_value . ' ' . strtoupper($interval_interval); - - $upd = Database::prepare(" - UPDATE `" . TABLE_PANEL_CRONRUNS . "` - SET `isactive` = :isactive, `interval` = :int - WHERE `id` = :id" - ); - Database::pexecute($upd, array('isactive' => $isactive, 'int' => $interval, 'id' => $id)); - - // insert task to re-generate the cron.d-file - inserttask('99'); - - redirectTo($filename, array('page' => $page, 's' => $s)); + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); } else { // interval @@ -110,11 +105,11 @@ if ($page == 'cronjobs' || $page == 'overview') { $interval_value = $interval_nfo[0]; $interval_interval = ''; - $interval_interval .= makeoption($lng['cronmgmt']['minutes'], 'MINUTE', $interval_nfo[1]); - $interval_interval .= makeoption($lng['cronmgmt']['hours'], 'HOUR', $interval_nfo[1]); - $interval_interval .= makeoption($lng['cronmgmt']['days'], 'DAY', $interval_nfo[1]); - $interval_interval .= makeoption($lng['cronmgmt']['weeks'], 'WEEK', $interval_nfo[1]); - $interval_interval .= makeoption($lng['cronmgmt']['months'], 'MONTH', $interval_nfo[1]); + $interval_interval .= \Froxlor\UI\HTML::makeoption($lng['cronmgmt']['minutes'], 'MINUTE', $interval_nfo[1]); + $interval_interval .= \Froxlor\UI\HTML::makeoption($lng['cronmgmt']['hours'], 'HOUR', $interval_nfo[1]); + $interval_interval .= \Froxlor\UI\HTML::makeoption($lng['cronmgmt']['days'], 'DAY', $interval_nfo[1]); + $interval_interval .= \Froxlor\UI\HTML::makeoption($lng['cronmgmt']['weeks'], 'WEEK', $interval_nfo[1]); + $interval_interval .= \Froxlor\UI\HTML::makeoption($lng['cronmgmt']['months'], 'MONTH', $interval_nfo[1]); // end of interval $change_cronfile = false; @@ -122,17 +117,16 @@ if ($page == 'cronjobs' || $page == 'overview') { $change_cronfile = true; } - $cronjobs_edit_data = include_once dirname(__FILE__).'/lib/formfields/admin/cronjobs/formfield.cronjobs_edit.php'; - $cronjobs_edit_form = htmlform::genHTMLForm($cronjobs_edit_data); + $cronjobs_edit_data = include_once dirname(__FILE__) . '/lib/formfields/admin/cronjobs/formfield.cronjobs_edit.php'; + $cronjobs_edit_form = \Froxlor\UI\HtmlForm::genHTMLForm($cronjobs_edit_data); $title = $cronjobs_edit_data['cronjobs_edit']['title']; $image = $cronjobs_edit_data['cronjobs_edit']['image']; - eval("echo \"" . getTemplate('cronjobs/cronjob_edit') . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate('cronjobs/cronjob_edit') . "\";"); } } - } - elseif ($action == 'delete' && $id != 0) { + } elseif ($action == 'delete' && $id != 0) { /* * @TODO later */ diff --git a/admin_customers.php b/admin_customers.php index 2b369b7f..af08c8d1 100644 --- a/admin_customers.php +++ b/admin_customers.php @@ -16,24 +16,26 @@ * @package Panel * */ - define('AREA', 'admin'); require './lib/init.php'; +use Froxlor\Database\Database; +use Froxlor\Settings; +use Froxlor\Api\Commands\Customers as Customers; + if (isset($_POST['id'])) { $id = intval($_POST['id']); -} elseif(isset($_GET['id'])) { +} elseif (isset($_GET['id'])) { $id = intval($_GET['id']); } -if ($page == 'customers' - && $userinfo['customers'] != '0' -) { +if ($page == 'customers' && $userinfo['customers'] != '0') { if ($action == '') { // clear request data unset($_SESSION['requestData']); - $log->logAction(ADM_ACTION, LOG_NOTICE, "viewed admin_customers"); + $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "viewed admin_customers"); + $fields = array( 'c.loginname' => $lng['login']['username'], 'a.loginname' => $lng['admin']['admin'], @@ -46,127 +48,135 @@ if ($page == 'customers' 'c.traffic' => $lng['customer']['traffic'], 'c.traffic_used' => $lng['customer']['traffic'] . ' (' . $lng['panel']['used'] . ')' ); + try { + // get total count + $json_result = Customers::getLocal($userinfo)->listingCount(); + $result = json_decode($json_result, true)['data']; + // initialize pagination and filtering + $paging = new \Froxlor\UI\Pagination($userinfo, $fields, $result); + // get list + $json_result = Customers::getLocal($userinfo, $paging->getApiCommandParams())->listing(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; - $paging = new paging($userinfo, TABLE_PANEL_CUSTOMERS, $fields); $customers = ''; - $result_stmt = Database::prepare(" - SELECT `c`.*, `a`.`loginname` AS `adminname` - FROM `" . TABLE_PANEL_CUSTOMERS . "` `c`, `" . TABLE_PANEL_ADMINS . "` `a` - WHERE " . - ($userinfo['customers_see_all'] ? '' : " `c`.`adminid` = :adminid AND ") . " - `c`.`adminid` = `a`.`adminid` " . - $paging->getSqlWhere(true) . " " . - $paging->getSqlOrderBy() . " " . - $paging->getSqlLimit() - ); - Database::pexecute($result_stmt, array('adminid' => $userinfo['adminid'])); - $num_rows = Database::num_rows(); - $paging->setEntries($num_rows); $sortcode = $paging->getHtmlSortCode($lng, true); $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); $searchcode = $paging->getHtmlSearchCode($lng); $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); - $i = 0; $count = 0; - while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { + foreach ($result['list'] as $row) { - if ($paging->checkDisplay($i)) { + $domains_stmt = Database::prepare(" + SELECT COUNT(`id`) AS `domains` + FROM `" . TABLE_PANEL_DOMAINS . "` + WHERE `customerid` = :cid + AND `parentdomainid` = '0' + AND `id`<> :stdd + "); + Database::pexecute($domains_stmt, array( + 'cid' => $row['customerid'], + 'stdd' => $row['standardsubdomain'] + )); + $domains = $domains_stmt->fetch(PDO::FETCH_ASSOC); + $row['domains'] = intval($domains['domains']); + $dec_places = Settings::Get('panel.decimal_places'); - $domains_stmt = Database::prepare(" - SELECT COUNT(`id`) AS `domains` - FROM `" . TABLE_PANEL_DOMAINS . "` - WHERE `customerid` = :cid - AND `parentdomainid` = '0' - AND `id`<> :stdd" - ); - Database::pexecute($domains_stmt, array('cid' => $row['customerid'], 'stdd' => $row['standardsubdomain'])); - $domains = $domains_stmt->fetch(PDO::FETCH_ASSOC); - $row['domains'] = intval($domains['domains']); - $dec_places = Settings::Get('panel.decimal_places'); - $row['traffic_used'] = round($row['traffic_used'] / (1024 * 1024), $dec_places); - $row['traffic'] = round($row['traffic'] / (1024 * 1024), $dec_places); - $row['diskspace_used'] = round($row['diskspace_used'] / 1024, $dec_places); - $row['diskspace'] = round($row['diskspace'] / 1024, $dec_places); - $last_login = ((int)$row['lastlogin_succ'] == 0) ? $lng['panel']['neverloggedin'] : date('d.m.Y', $row['lastlogin_succ']); + // get disk-space usages for web, mysql and mail + $usages_stmt = Database::prepare(" + SELECT * FROM `" . TABLE_PANEL_DISKSPACE . "` + WHERE `customerid` = :cid + ORDER BY `stamp` DESC LIMIT 1 + "); + $usages = Database::pexecute_first($usages_stmt, array( + 'cid' => $row['customerid'] + )); - /** - * percent-values for progressbar - */ - //For Disk usage - if ($row['diskspace'] > 0) { - $disk_percent = round(($row['diskspace_used']*100)/$row['diskspace'], 0); - $disk_doublepercent = round($disk_percent*2, 2); - } else { - $disk_percent = 0; - $disk_doublepercent = 0; - } + if ($usages) { + $row['webspace_used'] = round($usages['webspace'] / 1024, $dec_places); + $row['mailspace_used'] = round($usages['mail'] / 1024, $dec_places); + $row['dbspace_used'] = round($usages['mysql'] / 1024, $dec_places); + } else { + $row['webspace_used'] = 0; + $row['mailspace_used'] = 0; + $row['dbspace_used'] = 0; + } + $row['traffic_used'] = round($row['traffic_used'] / (1024 * 1024), $dec_places); + $row['traffic'] = round($row['traffic'] / (1024 * 1024), $dec_places); + $row['diskspace_used'] = round($row['diskspace_used'] / 1024, $dec_places); + $row['diskspace'] = round($row['diskspace'] / 1024, $dec_places); + $last_login = ((int) $row['lastlogin_succ'] == 0) ? $lng['panel']['neverloggedin'] : date('d.m.Y', $row['lastlogin_succ']); - if ($row['traffic'] > 0) { - $traffic_percent = round(($row['traffic_used']*100)/$row['traffic'], 0); - $traffic_doublepercent = round($traffic_percent*2, 2); - } else { - $traffic_percent = 0; - $traffic_doublepercent = 0; - } - - $islocked = 0; - if ($row['loginfail_count'] >= Settings::Get('login.maxloginattempts') - && $row['lastlogin_fail'] > (time() - Settings::Get('login.deactivatetime')) - ) { - $islocked = 1; - } - - $row = str_replace_array('-1', 'UL', $row, 'diskspace traffic mysqls emails email_accounts email_forwarders ftps tickets subdomains'); - $row = htmlentities_array($row); - - // fix progress-bars if value is >100% - if ($disk_percent > 100) { - $disk_percent = 100; - } - if ($traffic_percent > 100) { - $traffic_percent = 100; - } - - $row['custom_notes'] = ($row['custom_notes'] != '') ? nl2br($row['custom_notes']) : ''; - - eval("\$customers.=\"" . getTemplate("customers/customers_customer") . "\";"); - $count++; + /** + * percent-values for progressbar + */ + if ($row['diskspace'] > 0) { + $disk_percent = round(($row['diskspace_used'] * 100) / $row['diskspace'], 0); + $disk_doublepercent = round($disk_percent * 2, 2); + } else { + $disk_percent = 0; + $disk_doublepercent = 0; + } + if ($row['traffic'] > 0) { + $traffic_percent = round(($row['traffic_used'] * 100) / $row['traffic'], 0); + $traffic_doublepercent = round($traffic_percent * 2, 2); + } else { + $traffic_percent = 0; + $traffic_doublepercent = 0; } - $i++; + $islocked = 0; + if ($row['loginfail_count'] >= Settings::Get('login.maxloginattempts') && $row['lastlogin_fail'] > (time() - Settings::Get('login.deactivatetime'))) { + $islocked = 1; + } + + $row = \Froxlor\PhpHelper::strReplaceArray('-1', 'UL', $row, 'diskspace traffic mysqls emails email_accounts email_forwarders ftps subdomains'); + $row = \Froxlor\PhpHelper::htmlentitiesArray($row); + + // fix progress-bars if value is >100% + if ($disk_percent > 100) { + $disk_percent = 100; + } + if ($traffic_percent > 100) { + $traffic_percent = 100; + } + + $row['custom_notes'] = ($row['custom_notes'] != '') ? nl2br($row['custom_notes']) : ''; + + eval("\$customers.=\"" . \Froxlor\UI\Template::getTemplate("customers/customers_customer") . "\";"); + $count ++; } - $customercount = $num_rows; - eval("echo \"" . getTemplate("customers/customers") . "\";"); - - } elseif($action == 'su' - && $id != 0 - ) { - $result_stmt = Database::prepare(" - SELECT * FROM `" . TABLE_PANEL_CUSTOMERS . "` - WHERE `customerid` = :id" . - ($userinfo['customers_see_all'] ? '' : " AND `adminid` = :adminid") - ); - $params = array('id' => $id); - if ($userinfo['customers_see_all'] == '0') { - $params['adminid'] = $userinfo['adminid']; + $customercount = $result['count'] . " / " . $paging->getEntries(); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("customers/customers") . "\";"); + } elseif ($action == 'su' && $id != 0) { + try { + $json_result = Customers::getLocal($userinfo, array( + 'id' => $id + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } - $result = Database::pexecute_first($result_stmt, $params); + $result = json_decode($json_result, true)['data']; $destination_user = $result['loginname']; if ($destination_user != '') { if ($result['deactivated'] == '1') { - standard_error("usercurrentlydeactivated", $destination_user); + \Froxlor\UI\Response::standard_error("usercurrentlydeactivated", $destination_user); } $result_stmt = Database::prepare(" SELECT * FROM `" . TABLE_PANEL_SESSIONS . "` WHERE `userid` = :id - AND `hash` = :hash" - ); - $result = Database::pexecute_first($result_stmt, array('id' => $userinfo['userid'], 'hash' => $s)); + AND `hash` = :hash"); + $result = Database::pexecute_first($result_stmt, array( + 'id' => $userinfo['userid'], + 'hash' => $s + )); $s = md5(uniqid(microtime(), 1)); $insert = Database::prepare(" @@ -177,8 +187,7 @@ if ($page == 'customers' `useragent` = :ua, `lastactivity` = :lastact, `language` = :lang, - `adminsession` = '0'" - ); + `adminsession` = '0'"); Database::pexecute($insert, array( 'hash' => $s, 'id' => $id, @@ -187,873 +196,178 @@ if ($page == 'customers' 'lastact' => time(), 'lang' => $result['language'] )); - $log->logAction(ADM_ACTION, LOG_INFO, "switched user and is now '" . $destination_user . "'"); + $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "switched user and is now '" . $destination_user . "'"); $target = (isset($_GET['target']) ? $_GET['target'] : 'index'); - $redirect = "customer_".$target.".php"; - if (!file_exists(FROXLOR_INSTALL_DIR."/".$redirect)) { + $redirect = "customer_" . $target . ".php"; + if (! file_exists(\Froxlor\Froxlor::getInstallDir() . "/" . $redirect)) { $redirect = "customer_index.php"; } - redirectTo($redirect, array('s' => $s), true); - + \Froxlor\UI\Response::redirectTo($redirect, array( + 's' => $s + ), true); } else { - redirectTo('index.php', array('action' => 'login')); + \Froxlor\UI\Response::redirectTo('index.php', array( + 'action' => 'login' + )); } - - } elseif($action == 'unlock' - && $id != 0 - ) { - $result_stmt = Database::prepare(" - SELECT * FROM `" . TABLE_PANEL_CUSTOMERS . "` - WHERE `customerid` = :id" . - ($userinfo['customers_see_all'] ? '' : " AND `adminid` = :adminid") - ); - $result_data = array('id' => $id); - if ($userinfo['customers_see_all'] == '0') { - $result_data['adminid'] = $userinfo['adminid']; + } elseif ($action == 'unlock' && $id != 0) { + try { + $json_result = Customers::getLocal($userinfo, array( + 'id' => $id + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } - $result = Database::pexecute_first($result_stmt, $result_data); + $result = json_decode($json_result, true)['data']; - if ($result['loginname'] != '') { - - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { - $result_stmt = Database::prepare(" - UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET - `loginfail_count` = '0' - WHERE `customerid`= :id" - ); - Database::pexecute($result_stmt, array('id' => $id)); - redirectTo($filename, array('page' => $page, 's' => $s)); - - } else { - ask_yesno('customer_reallyunlock', $filename, array('id' => $id, 'page' => $page, 'action' => $action), $result['loginname']); + if (isset($_POST['send']) && $_POST['send'] == 'send') { + try { + $json_result = Customers::getLocal($userinfo, array( + 'id' => $id + ))->unlock(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); + } else { + \Froxlor\UI\HTML::askYesNo('customer_reallyunlock', $filename, array( + 'id' => $id, + 'page' => $page, + 'action' => $action + ), $result['loginname']); } - - } elseif ($action == 'delete' - && $id != 0 - ) { - $result_stmt = Database::prepare(" - SELECT * FROM `" . TABLE_PANEL_CUSTOMERS . "` - WHERE `customerid` = :id" . - ($userinfo['customers_see_all'] ? '' : " AND `adminid` = :adminid") - ); - $params = array('id' => $id); - if ($userinfo['customers_see_all'] == '0') { - $params['adminid'] = $userinfo['adminid']; + } elseif ($action == 'delete' && $id != 0) { + try { + $json_result = Customers::getLocal($userinfo, array( + 'id' => $id + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } - $result = Database::pexecute_first($result_stmt, $params); + $result = json_decode($json_result, true)['data']; - if ($result['loginname'] != '') { - - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { - $databases_stmt = Database::prepare(" - SELECT * FROM `" . TABLE_PANEL_DATABASES . "` - WHERE `customerid` = :id ORDER BY `dbserver`" - ); - Database::pexecute($databases_stmt, array('id' => $id)); - Database::needRoot(true); - $last_dbserver = 0; - - $dbm = new DbManager($log); - - while ($row_database = $databases_stmt->fetch(PDO::FETCH_ASSOC)) { - - if ($last_dbserver != $row_database['dbserver']) { - Database::needRoot(true, $row_database['dbserver']); - $dbm->getManager()->flushPrivileges(); - $last_dbserver = $row_database['dbserver']; - } - - $dbm->getManager()->deleteDatabase($row_database['databasename']); - } - - $dbm->getManager()->flushPrivileges(); - Database::needRoot(false); - $stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_CUSTOMERS . "` WHERE `customerid` = :id"); - Database::pexecute($stmt, array('id' => $id)); - $stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_DATABASES . "` WHERE `customerid` = :id"); - Database::pexecute($stmt, array('id' => $id)); - // first gather all domain-id's to clean up panel_domaintoip accordingly - $did_stmt = Database::prepare("SELECT `id` FROM `".TABLE_PANEL_DOMAINS."` WHERE `customerid` = :id"); - Database::pexecute($did_stmt, array('id' => $id)); - while ($row = $did_stmt->fetch(PDO::FETCH_ASSOC)) { - $stmt = Database::prepare("DELETE FROM `" . TABLE_DOMAINTOIP . "` WHERE `id_domain` = :did"); - Database::pexecute($stmt, array('did' => $row['id'])); - } - $stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `customerid` = :id"); - Database::pexecute($stmt, array('id' => $id)); - $domains_deleted = $stmt->rowCount(); - $stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_HTPASSWDS . "` WHERE `customerid` = :id"); - Database::pexecute($stmt, array('id' => $id)); - $stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_HTACCESS . "` WHERE `customerid` = :id"); - Database::pexecute($stmt, array('id' => $id)); - $stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_SESSIONS . "` WHERE `userid` = :id AND `adminsession` = '0'"); - Database::pexecute($stmt, array('id' => $id)); - $stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_TRAFFIC . "` WHERE `customerid` = :id"); - Database::pexecute($stmt, array('id' => $id)); - $stmt = Database::prepare("DELETE FROM `" . TABLE_MAIL_USERS . "` WHERE `customerid` = :id"); - Database::pexecute($stmt, array('id' => $id)); - $stmt = Database::prepare("DELETE FROM `" . TABLE_MAIL_VIRTUAL . "` WHERE `customerid` = :id"); - Database::pexecute($stmt, array('id' => $id)); - $result2_stmt = Database::prepare("SELECT `username` FROM `" . TABLE_FTP_USERS . "` WHERE `customerid` = :id"); - Database::pexecute($result2_stmt, array('id' => $id)); - while ($row = $result2_stmt->fetch(PDO::FETCH_ASSOC)) { - $stmt = Database::prepare("DELETE FROM `" . TABLE_FTP_QUOTATALLIES . "` WHERE `name` = :name"); - Database::pexecute($stmt, array('name' => $row['username'])); - } - $stmt = Database::prepare("DELETE FROM `" . TABLE_FTP_GROUPS . "` WHERE `customerid` = :id"); - Database::pexecute($stmt, array('id' => $id)); - $stmt = Database::prepare("DELETE FROM `" . TABLE_FTP_USERS . "` WHERE `customerid` = :id"); - Database::pexecute($stmt, array('id' => $id)); - - // Delete all waiting "create user" -tasks for this user, #276 - // Note: the WHERE selects part of a serialized array, but it should be safe this way - $del_stmt = Database::prepare(" - DELETE FROM `" . TABLE_PANEL_TASKS . "` - WHERE `type` = '2' AND `data` LIKE :loginname" - ); - Database::pexecute($del_stmt, array('loginname' => "%:{$result['loginname']};%")); - - $admin_update_query = "UPDATE `" . TABLE_PANEL_ADMINS . "` SET `customers_used` = `customers_used` - 1 "; - $admin_update_query.= ", `domains_used` = `domains_used` - 0" . (int)($domains_deleted - $result['subdomains_used']); - - if ($result['mysqls'] != '-1') { - $admin_update_query.= ", `mysqls_used` = `mysqls_used` - 0" . (int)$result['mysqls']; - } - - if ($result['emails'] != '-1') { - $admin_update_query.= ", `emails_used` = `emails_used` - 0" . (int)$result['emails']; - } - - if ($result['email_accounts'] != '-1') { - $admin_update_query.= ", `email_accounts_used` = `email_accounts_used` - 0" . (int)$result['email_accounts']; - } - - if ($result['email_forwarders'] != '-1') { - $admin_update_query.= ", `email_forwarders_used` = `email_forwarders_used` - 0" . (int)$result['email_forwarders']; - } - - if ($result['email_quota'] != '-1') { - $admin_update_query.= ", `email_quota_used` = `email_quota_used` - 0" . (int)$result['email_quota']; - } - - if ($result['subdomains'] != '-1') { - $admin_update_query.= ", `subdomains_used` = `subdomains_used` - 0" . (int)$result['subdomains']; - } - - if ($result['ftps'] != '-1') { - $admin_update_query.= ", `ftps_used` = `ftps_used` - 0" . (int)$result['ftps']; - } - - if ($result['tickets'] != '-1') { - $admin_update_query.= ", `tickets_used` = `tickets_used` - 0" . (int)$result['tickets']; - } - - if (($result['diskspace'] / 1024) != '-1') { - $admin_update_query.= ", `diskspace_used` = `diskspace_used` - 0" . (int)$result['diskspace']; - } - - $admin_update_query.= " WHERE `adminid` = '" . (int)$result['adminid'] . "'"; - Database::query($admin_update_query); - $log->logAction(ADM_ACTION, LOG_INFO, "deleted user '" . $result['loginname'] . "'"); - inserttask('1'); - - // Using nameserver, insert a task which rebuilds the server config - inserttask('4'); - - if (isset($_POST['delete_userfiles']) - && (int)$_POST['delete_userfiles'] == 1 - ) { - inserttask('6', $result['loginname']); - } - - // Using filesystem - quota, insert a task which cleans the filesystem - quota - inserttask('10'); - - /* - * move old tickets to archive - */ - $tickets = ticket::customerHasTickets($id); - if ($tickets !== false && isset($tickets[0])) { - foreach ($tickets as $ticket) { - $now = time(); - $mainticket = ticket::getInstanceOf($userinfo, (int)$ticket); - $mainticket->Set('lastchange', $now, true, true); - $mainticket->Set('lastreplier', '1', true, true); - $mainticket->Set('status', '3', true, true); - $mainticket->Update(); - $mainticket->Archive(); - $log->logAction(ADM_ACTION, LOG_NOTICE, "archived ticket '" . $mainticket->Get('subject') . "'"); - } - } - redirectTo($filename, array('page' => $page, 's' => $s)); - - } else { - ask_yesno_withcheckbox('admin_customer_reallydelete', 'admin_customer_alsoremovefiles', $filename, array('id' => $id, 'page' => $page, 'action' => $action), $result['loginname']); + if (isset($_POST['send']) && $_POST['send'] == 'send') { + try { + $json_result = Customers::getLocal($userinfo, array( + 'id' => $id, + 'delete_userfiles' => (isset($_POST['delete_userfiles']) ? (int) $_POST['delete_userfiles'] : 0) + ))->delete(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); + } else { + \Froxlor\UI\HTML::askYesNoWithCheckbox('admin_customer_reallydelete', 'admin_customer_alsoremovefiles', $filename, array( + 'id' => $id, + 'page' => $page, + 'action' => $action + ), $result['loginname']); } + } elseif ($action == 'add') { - } elseif($action == 'add') { + if (isset($_POST['send']) && $_POST['send'] == 'send') { + try { + Customers::getLocal($userinfo, $_POST)->add(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); + } else { + $language_options = ''; - if ($userinfo['customers_used'] < $userinfo['customers'] - || $userinfo['customers'] == '-1' - ) { - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { - $name = validate($_POST['name'], 'name'); - $firstname = validate($_POST['firstname'], 'first name'); - $company = validate($_POST['company'], 'company'); - $street = validate($_POST['street'], 'street'); - $zipcode = validate($_POST['zipcode'], 'zipcode', '/^[0-9 \-A-Z]*$/'); - $city = validate($_POST['city'], 'city'); - $phone = validate($_POST['phone'], 'phone', '/^[0-9\- \+\(\)\/]*$/'); - $fax = validate($_POST['fax'], 'fax', '/^[0-9\- \+\(\)\/]*$/'); - $email = $idna_convert->encode(validate($_POST['email'], 'email')); - $customernumber = validate($_POST['customernumber'], 'customer number', '/^[A-Za-z0-9 \-]*$/Di'); - $def_language = validate($_POST['def_language'], 'default language'); - $gender = intval_ressource($_POST['gender']); + foreach ($languages as $language_file => $language_name) { + $language_options .= \Froxlor\UI\HTML::makeoption($language_name, $language_file, Settings::Get('panel.standardlanguage'), true); + } - $custom_notes = validate(str_replace("\r\n", "\n", $_POST['custom_notes']), 'custom_notes', '/^[^\0]*$/'); - $custom_notes_show = 0; - if (isset($_POST['custom_notes_show'])) { - $custom_notes_show = intval_ressource($_POST['custom_notes_show']); - } + $diskspace_ul = \Froxlor\UI\HTML::makecheckbox('diskspace_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); + $traffic_ul = \Froxlor\UI\HTML::makecheckbox('traffic_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); + $subdomains_ul = \Froxlor\UI\HTML::makecheckbox('subdomains_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); + $emails_ul = \Froxlor\UI\HTML::makecheckbox('emails_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); + $email_accounts_ul = \Froxlor\UI\HTML::makecheckbox('email_accounts_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); + $email_forwarders_ul = \Froxlor\UI\HTML::makecheckbox('email_forwarders_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); + $email_quota_ul = \Froxlor\UI\HTML::makecheckbox('email_quota_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); + $ftps_ul = \Froxlor\UI\HTML::makecheckbox('ftps_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); + $mysqls_ul = \Froxlor\UI\HTML::makecheckbox('mysqls_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); - $diskspace = intval_ressource($_POST['diskspace']); - if (isset($_POST['diskspace_ul'])) { - $diskspace = - 1; - } + $gender_options = \Froxlor\UI\HTML::makeoption($lng['gender']['undef'], 0, true, true, true); + $gender_options .= \Froxlor\UI\HTML::makeoption($lng['gender']['male'], 1, null, true, true); + $gender_options .= \Froxlor\UI\HTML::makeoption($lng['gender']['female'], 2, null, true, true); - $traffic = doubleval_ressource($_POST['traffic']); - if (isset($_POST['traffic_ul'])) { - $traffic = - 1; - } - - $subdomains = intval_ressource($_POST['subdomains']); - if (isset($_POST['subdomains_ul'])) { - $subdomains = - 1; - } - - $emails = intval_ressource($_POST['emails']); - if (isset($_POST['emails_ul'])) { - $emails = - 1; - } - - $email_accounts = intval_ressource($_POST['email_accounts']); - if (isset($_POST['email_accounts_ul'])) { - $email_accounts = - 1; - } - - $email_forwarders = intval_ressource($_POST['email_forwarders']); - if (isset($_POST['email_forwarders_ul'])) { - $email_forwarders = - 1; - } - - if (Settings::Get('system.mail_quota_enabled') == '1') { - $email_quota = validate($_POST['email_quota'], 'email_quota', '/^\d+$/', 'vmailquotawrong', array('0', '')); - if (isset($_POST['email_quota_ul'])) { - $email_quota = - 1; - } + $phpconfigs = array(); + $configs = Database::query(" + SELECT c.*, fc.description as interpreter + FROM `" . TABLE_PANEL_PHPCONFIGS . "` c + LEFT JOIN `" . TABLE_PANEL_FPMDAEMONS . "` fc ON fc.id = c.fpmsettingid + "); + while ($row = $configs->fetch(PDO::FETCH_ASSOC)) { + if ((int) Settings::Get('phpfpm.enabled') == 1) { + $phpconfigs[] = array( + 'label' => $row['description'] . " [" . $row['interpreter'] . "]
", + 'value' => $row['id'] + ); } else { - $email_quota = - 1; - } - - $email_imap = 0; - if (isset($_POST['email_imap'])) { - $email_imap = intval_ressource($_POST['email_imap']); - } - - $email_pop3 = 0; - if (isset($_POST['email_pop3'])) { - $email_pop3 = intval_ressource($_POST['email_pop3']); - } - - $ftps = 0; - if (isset($_POST['ftps'])) { - $ftps = intval_ressource($_POST['ftps']); - } - if (isset($_POST['ftps_ul'])) { - $ftps = - 1; - } - - $tickets = (Settings::Get('ticket.enabled') == 1 ? intval_ressource($_POST['tickets']) : 0); - if (isset($_POST['tickets_ul']) - && Settings::Get('ticket.enabled') == '1' - ) { - $tickets = - 1; - } - - $mysqls = intval_ressource($_POST['mysqls']); - if (isset($_POST['mysqls_ul'])) { - $mysqls = - 1; - } - - $createstdsubdomain = 0; - if(isset($_POST['createstdsubdomain'])) { - $createstdsubdomain = intval($_POST['createstdsubdomain']); - } - - $password = validate($_POST['new_customer_password'], 'password'); - // only check if not empty, - // cause empty == generate password automatically - if ($password != '') { - $password = validatePassword($password); - } - - // gender out of range? [0,2] - if ($gender < 0 || $gender > 2) { - $gender = 0; - } - - $sendpassword = 0; - if (isset($_POST['sendpassword'])) { - $sendpassword = intval($_POST['sendpassword']); - } - - $phpenabled = 0; - if (isset($_POST['phpenabled'])) { - $phpenabled = intval($_POST['phpenabled']); - } - - $perlenabled = 0; - if (isset($_POST['perlenabled'])) { - $perlenabled = intval($_POST['perlenabled']); - } - - $store_defaultindex = 0; - if (isset($_POST['store_defaultindex'])) { - $store_defaultindex = intval($_POST['store_defaultindex']); - } - - $diskspace = $diskspace * 1024; - $traffic = $traffic * 1024 * 1024; - - if (((($userinfo['diskspace_used'] + $diskspace) > $userinfo['diskspace']) && ($userinfo['diskspace'] / 1024) != '-1') - || ((($userinfo['mysqls_used'] + $mysqls) > $userinfo['mysqls']) && $userinfo['mysqls'] != '-1') - || ((($userinfo['emails_used'] + $emails) > $userinfo['emails']) && $userinfo['emails'] != '-1') - || ((($userinfo['email_accounts_used'] + $email_accounts) > $userinfo['email_accounts']) && $userinfo['email_accounts'] != '-1') - || ((($userinfo['email_forwarders_used'] + $email_forwarders) > $userinfo['email_forwarders']) && $userinfo['email_forwarders'] != '-1') - || ((($userinfo['email_quota_used'] + $email_quota) > $userinfo['email_quota']) && $userinfo['email_quota'] != '-1' && Settings::Get('system.mail_quota_enabled') == '1') - || ((($userinfo['ftps_used'] + $ftps) > $userinfo['ftps']) && $userinfo['ftps'] != '-1') - || ((($userinfo['tickets_used'] + $tickets) > $userinfo['tickets']) && $userinfo['tickets'] != '-1') - || ((($userinfo['subdomains_used'] + $subdomains) > $userinfo['subdomains']) && $userinfo['subdomains'] != '-1') - || (($diskspace / 1024) == '-1' && ($userinfo['diskspace'] / 1024) != '-1') - || ($mysqls == '-1' && $userinfo['mysqls'] != '-1') - || ($emails == '-1' && $userinfo['emails'] != '-1') - || ($email_accounts == '-1' && $userinfo['email_accounts'] != '-1') - || ($email_forwarders == '-1' && $userinfo['email_forwarders'] != '-1') - || ($email_quota == '-1' && $userinfo['email_quota'] != '-1' && Settings::Get('system.mail_quota_enabled') == '1') - || ($ftps == '-1' && $userinfo['ftps'] != '-1') - || ($tickets == '-1' && $userinfo['tickets'] != '-1') - || ($subdomains == '-1' && $userinfo['subdomains'] != '-1') - ) { - standard_error('youcantallocatemorethanyouhave'); - } - - // Either $name and $firstname or the $company must be inserted - if ($name == '' && $company == '') { - standard_error(array('stringisempty', 'myname')); - - } elseif($firstname == '' && $company == '') { - standard_error(array('stringisempty', 'myfirstname')); - - } elseif($email == '') { - standard_error(array('stringisempty', 'emailadd')); - - } elseif(!validateEmail($email)) { - standard_error('emailiswrong', $email); - - } else { - - if (isset($_POST['new_loginname']) - && $_POST['new_loginname'] != '' - ) { - $accountnumber = intval(Settings::Get('system.lastaccountnumber')); - $loginname = validate($_POST['new_loginname'], 'loginname', '/^[a-z][a-z0-9\-_]+$/i'); - - // Accounts which match systemaccounts are not allowed, filtering them - if (preg_match('/^' . preg_quote(Settings::Get('customer.accountprefix'), '/') . '([0-9]+)/', $loginname)) { - standard_error('loginnameissystemaccount', Settings::Get('customer.accountprefix')); - } - - // Additional filtering for Bug #962 - if (function_exists('posix_getpwnam') - && !in_array("posix_getpwnam", explode(",", ini_get('disable_functions'))) - && posix_getpwnam($loginname) - ) { - standard_error('loginnameissystemaccount', Settings::Get('customer.accountprefix')); - } - - } else { - $accountnumber = intval(Settings::Get('system.lastaccountnumber')) + 1; - $loginname = Settings::Get('customer.accountprefix') . $accountnumber; - } - - // Check if the account already exists - $loginname_check_stmt = Database::prepare(" - SELECT `loginname` FROM `" . TABLE_PANEL_CUSTOMERS . "` WHERE `loginname` = :loginname" + $phpconfigs[] = array( + 'label' => $row['description'] . "
", + 'value' => $row['id'] ); - $loginname_check = Database::pexecute_first($loginname_check_stmt, array('loginname' => $loginname)); - - $loginname_check_admin_stmt = Database::prepare(" - SELECT `loginname` FROM `" . TABLE_PANEL_ADMINS . "` WHERE `loginname` = :loginname" - ); - $loginname_check_admin = Database::pexecute_first($loginname_check_admin_stmt, array('loginname' => $loginname)); - - if (strtolower($loginname_check['loginname']) == strtolower($loginname) - || strtolower($loginname_check_admin['loginname']) == strtolower($loginname) - ) { - standard_error('loginnameexists', $loginname); - - } elseif (!validateUsername($loginname, Settings::Get('panel.unix_names'), 14 - strlen(Settings::Get('customer.mysqlprefix')))) { - if (strlen($loginname) > 14 - strlen(Settings::Get('customer.mysqlprefix'))) { - standard_error('loginnameiswrong2', 14 - strlen(Settings::Get('customer.mysqlprefix'))); - } else { - standard_error('loginnameiswrong', $loginname); - } - } - - $guid = intval(Settings::Get('system.lastguid')) + 1; - $documentroot = makeCorrectDir(Settings::Get('system.documentroot_prefix') . '/' . $loginname); - - if (file_exists($documentroot)) { - standard_error('documentrootexists', $documentroot); - } - - if ($createstdsubdomain != '1') { - $createstdsubdomain = '0'; - } - - if ($phpenabled != '0') { - $phpenabled = '1'; - } - - if ($perlenabled != '0') { - $perlenabled = '1'; - } - - if ($password == '') { - $password = generatePassword(); - } - - $_theme = Settings::Get('panel.default_theme'); - - $ins_data = array( - 'adminid' => $userinfo['adminid'], - 'loginname' => $loginname, - 'passwd' => makeCryptPassword($password), - 'name' => $name, - 'firstname' => $firstname, - 'gender' => $gender, - 'company' => $company, - 'street' => $street, - 'zipcode' => $zipcode, - 'city' => $city, - 'phone' => $phone, - 'fax' => $fax, - 'email' => $email, - 'customerno' => $customernumber, - 'lang' => $def_language, - 'docroot' => $documentroot, - 'guid' => $guid, - 'diskspace' => $diskspace, - 'traffic' => $traffic, - 'subdomains' => $subdomains, - 'emails' => $emails, - 'email_accounts' => $email_accounts, - 'email_forwarders' => $email_forwarders, - 'email_quota' => $email_quota, - 'ftps' => $ftps, - 'tickets' => $tickets, - 'mysqls' => $mysqls, - 'phpenabled' => $phpenabled, - 'imap' => $email_imap, - 'pop3' => $email_pop3, - 'perlenabled' => $perlenabled, - 'theme' => $_theme, - 'custom_notes' => $custom_notes, - 'custom_notes_show' => $custom_notes_show - ); - - $ins_stmt = Database::prepare(" - INSERT INTO `" . TABLE_PANEL_CUSTOMERS . "` SET - `adminid` = :adminid, - `loginname` = :loginname, - `password` = :passwd, - `name` = :name, - `firstname` = :firstname, - `gender` = :gender, - `company` = :company, - `street` = :street, - `zipcode` = :zipcode, - `city` = :city, - `phone` = :phone, - `fax` = :fax, - `email` = :email, - `customernumber` = :customerno, - `def_language` = :lang, - `documentroot` = :docroot, - `guid` = :guid, - `diskspace` = :diskspace, - `traffic` = :traffic, - `subdomains` = :subdomains, - `emails` = :emails, - `email_accounts` = :email_accounts, - `email_forwarders` = :email_forwarders, - `email_quota` = :email_quota, - `ftps` = :ftps, - `tickets` = :tickets, - `mysqls` = :mysqls, - `standardsubdomain` = '0', - `phpenabled` = :phpenabled, - `imap` = :imap, - `pop3` = :pop3, - `perlenabled` = :perlenabled, - `theme` = :theme, - `custom_notes` = :custom_notes, - `custom_notes_show` = :custom_notes_show" - ); - Database::pexecute($ins_stmt, $ins_data); - - $customerid = Database::lastInsertId(); - - $admin_update_query = "UPDATE `" . TABLE_PANEL_ADMINS . "` SET `customers_used` = `customers_used` + 1"; - - if ($mysqls != '-1') { - $admin_update_query.= ", `mysqls_used` = `mysqls_used` + 0" . (int)$mysqls; - } - - if ($emails != '-1') { - $admin_update_query.= ", `emails_used` = `emails_used` + 0" . (int)$emails; - } - - if ($email_accounts != '-1') { - $admin_update_query.= ", `email_accounts_used` = `email_accounts_used` + 0" . (int)$email_accounts; - } - - if ($email_forwarders != '-1') { - $admin_update_query.= ", `email_forwarders_used` = `email_forwarders_used` + 0" . (int)$email_forwarders; - } - - if ($email_quota != '-1') { - $admin_update_query.= ", `email_quota_used` = `email_quota_used` + 0" . (int)$email_quota; - } - - if ($subdomains != '-1') { - $admin_update_query.= ", `subdomains_used` = `subdomains_used` + 0" . (int)$subdomains; - } - - if ($ftps != '-1') { - $admin_update_query.= ", `ftps_used` = `ftps_used` + 0" . (int)$ftps; - } - - if ($tickets != '-1' - && Settings::Get('ticket.enabled') == 1 - ) { - $admin_update_query.= ", `tickets_used` = `tickets_used` + 0" . (int)$tickets; - } - - if (($diskspace / 1024) != '-1') { - $admin_update_query.= ", `diskspace_used` = `diskspace_used` + 0" . (int)$diskspace; - } - - $admin_update_query.= " WHERE `adminid` = '" . (int)$userinfo['adminid'] . "'"; - Database::query($admin_update_query); - - $upd_stmt = Database::prepare(" - UPDATE `" . TABLE_PANEL_SETTINGS . "` SET - `value` = :guid - WHERE `settinggroup` = 'system' AND `varname` = 'lastguid'" - ); - Database::pexecute($upd_stmt, array('guid' => $guid)); - - if ($accountnumber != intval(Settings::Get('system.lastaccountnumber'))) { - $upd_stmt = Database::prepare(" - UPDATE `" . TABLE_PANEL_SETTINGS . "` SET - `value` = :accno - WHERE `settinggroup` = 'system' AND `varname` = 'lastaccountnumber'" - ); - Database::pexecute($upd_stmt, array('accno' => $accountnumber)); - } - - $log->logAction(ADM_ACTION, LOG_INFO, "added user '" . $loginname . "'"); - inserttask('2', $loginname, $guid, $guid, $store_defaultindex); - - // Using filesystem - quota, insert a task which cleans the filesystem - quota - inserttask('10'); - - // Add htpasswd for the webalizer stats - if (CRYPT_STD_DES == 1) { - $saltfordescrypt = substr(md5(uniqid(microtime(), 1)), 4, 2); - $htpasswdPassword = crypt($password, $saltfordescrypt); - } else { - $htpasswdPassword = crypt($password); - } - - $ins_stmt = Database::prepare(" - INSERT INTO `" . TABLE_PANEL_HTPASSWDS . "` SET - `customerid` = :customerid, - `username` = :username, - `password` = :passwd, - `path` = :path" - ); - $ins_data = array( - 'customerid' => $customerid, - 'username' => $loginname, - 'passwd' => $htpasswdPassword - ); - - if (Settings::Get('system.awstats_enabled') == '1') { - $ins_data['path'] = makeCorrectDir($documentroot . '/awstats/'); - $log->logAction(ADM_ACTION, LOG_NOTICE, "automatically added awstats htpasswd for user '" . $loginname . "'"); - } else { - $ins_data['path'] = makeCorrectDir($documentroot . '/webalizer/'); - $log->logAction(ADM_ACTION, LOG_NOTICE, "automatically added webalizer htpasswd for user '" . $loginname . "'"); - } - Database::pexecute($ins_stmt, $ins_data); - - inserttask('1'); - $cryptPassword = makeCryptPassword($password); - // FTP-User - $ins_stmt = Database::prepare(" - INSERT INTO `" . TABLE_FTP_USERS . "` SET `customerid` = :customerid, `username` = :username, `description` = :desc, - `password` = :passwd, `homedir` = :homedir, `login_enabled` = 'y', `uid` = :guid, `gid` = :guid" - ); - $ins_data = array( - 'customerid' => $customerid, - 'username' => $loginname, - 'passwd' => $cryptPassword, - 'homedir' => $documentroot, - 'guid' => $guid, - 'desc' => "Default" - ); - Database::pexecute($ins_stmt, $ins_data); - // FTP-Group - $ins_stmt = Database::prepare(" - INSERT INTO `" . TABLE_FTP_GROUPS . "` SET `customerid` = :customerid, `groupname` = :groupname, `gid` = :guid, `members` = :members" - ); - $ins_data = array( - 'customerid' => $customerid, - 'groupname' => $loginname, - 'guid' => $guid, - 'members' => $loginname.','.Settings::Get('system.httpuser') - ); - - // also, add froxlor-local user to ftp-group (if exists!) to - // allow access to customer-directories from within the panel, which - // is necessary when pathedit = Dropdown - if ((int)Settings::Get('system.mod_fcgid_ownvhost') == 1 || (int)Settings::Get('phpfpm.enabled_ownvhost') == 1) { - if ((int)Settings::Get('system.mod_fcgid') == 1) { - $local_user = Settings::Get('system.mod_fcgid_httpuser'); - } else { - $local_user = Settings::Get('phpfpm.vhost_httpuser'); - } - // check froxlor-local user membership in ftp-group - // without this check addition may duplicate user in list if httpuser == local_user - if (strpos($ins_data['members'], $local_user) !== false) { - $ins_data['members'] .= ','.$local_user; - } - } - - Database::pexecute($ins_stmt, $ins_data); - - // FTP-Quotatallies - $ins_stmt = Database::prepare(" - INSERT INTO `" . TABLE_FTP_QUOTATALLIES . "` SET `name` = :name, `quota_type` = 'user', `bytes_in_used` = '0', - `bytes_out_used` = '0', `bytes_xfer_used` = '0', `files_in_used` = '0', `files_out_used` = '0', `files_xfer_used` = '0'" - ); - Database::pexecute($ins_stmt, array('name' => $loginname)); - $log->logAction(ADM_ACTION, LOG_NOTICE, "automatically added ftp-account for user '" . $loginname . "'"); - - $_stdsubdomain = ''; - - if ($createstdsubdomain == '1') { - - if (Settings::Get('system.stdsubdomain') !== null - && Settings::Get('system.stdsubdomain') != '' - ) { - $_stdsubdomain = $loginname . '.' . Settings::Get('system.stdsubdomain'); - } else { - $_stdsubdomain = $loginname . '.' . Settings::Get('system.hostname'); - } - - $ins_data = array( - 'domain' => $_stdsubdomain, - 'customerid' => $customerid, - 'adminid' => $userinfo['adminid'], - 'docroot' => $documentroot, - 'adddate' => date('Y-m-d') - ); - $ins_stmt = Database::prepare(" - INSERT INTO `" . TABLE_PANEL_DOMAINS . "` SET - `domain` = :domain, - `customerid` = :customerid, - `adminid` = :adminid, - `parentdomainid` = '0', - `documentroot` = :docroot, - `zonefile` = '', - `isemaildomain` = '0', - `caneditdomain` = '0', - `openbasedir` = '1', - `speciallogfile` = '0', - `specialsettings` = '', - `dkim_id` = '0', - `dkim_privkey` = '', - `dkim_pubkey` = '', - `add_date` = :adddate" - ); - Database::pexecute($ins_stmt, $ins_data); - $domainid = Database::lastInsertId(); - - // set ip <-> domain connection - $defaultips = explode(',', Settings::Get('system.defaultip')); - $ins_stmt = Database::prepare(" - INSERT INTO `" . TABLE_DOMAINTOIP . "` SET `id_domain` = :domainid, `id_ipandports` = :ipid" - ); - foreach ($defaultips as $defaultip) { - Database::pexecute($ins_stmt, array('domainid' => $domainid, 'ipid' => $defaultip)); - } - - $upd_stmt = Database::prepare(" - UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET `standardsubdomain` = :domainid WHERE `customerid` = :customerid" - ); - Database::pexecute($upd_stmt, array('domainid' => $domainid, 'customerid' => $customerid)); - $log->logAction(ADM_ACTION, LOG_NOTICE, "automatically added standardsubdomain for user '" . $loginname . "'"); - inserttask('1'); - } - - if ($sendpassword == '1') { - - $srv_hostname = Settings::Get('system.hostname'); - if (Settings::Get('system.froxlordirectlyviahostname') == '0') { - $srv_hostname .= '/froxlor'; - } - - $srv_ip_stmt = Database::prepare(" - SELECT ip, port FROM `".TABLE_PANEL_IPSANDPORTS."` - WHERE `id` = :defaultip - "); - $srv_ip = Database::pexecute_first($srv_ip_stmt, array('defaultip' => reset(explode(',', Settings::Get('system.defaultip'))))); - - $replace_arr = array( - 'FIRSTNAME' => $firstname, - 'NAME' => $name, - 'COMPANY' => $company, - 'SALUTATION' => getCorrectUserSalutation(array('firstname' => $firstname, 'name' => $name, 'company' => $company)), - 'USERNAME' => $loginname, - 'PASSWORD' => $password, - 'SERVER_HOSTNAME' => $srv_hostname, - 'SERVER_IP' => isset($srv_ip['ip']) ? $srv_ip['ip'] : '', - 'SERVER_PORT' => isset($srv_ip['port']) ? $srv_ip['port'] : '', - 'DOMAINNAME' => $_stdsubdomain - ); - - // Get mail templates from database; the ones from 'admin' are fetched for fallback - $result_stmt = Database::prepare(" - SELECT `value` FROM `" . TABLE_PANEL_TEMPLATES . "` - WHERE `adminid` = :adminid AND `language` = :deflang AND `templategroup` = 'mails' AND `varname` = 'createcustomer_subject'" - ); - $result = Database::pexecute_first($result_stmt, array('adminid' => $userinfo['adminid'], 'deflang' => $def_language)); - $mail_subject = html_entity_decode(replace_variables((($result['value'] != '') ? $result['value'] : $lng['mails']['createcustomer']['subject']), $replace_arr)); - - $result_stmt = Database::prepare(" - SELECT `value` FROM `" . TABLE_PANEL_TEMPLATES . "` - WHERE `adminid` = :adminid AND `language` = :deflang AND `templategroup` = 'mails' AND `varname` = 'createcustomer_mailbody'" - ); - $result = Database::pexecute_first($result_stmt, array('adminid' => $userinfo['adminid'], 'deflang' => $def_language)); - $mail_body = html_entity_decode(replace_variables((($result['value'] != '') ? $result['value'] : $lng['mails']['createcustomer']['mailbody']), $replace_arr)); - - $_mailerror = false; - try { - $mail->Subject = $mail_subject; - $mail->AltBody = $mail_body; - $mail->MsgHTML(str_replace("\n", "
", $mail_body)); - $mail->AddAddress($email, getCorrectUserSalutation(array('firstname' => $firstname, 'name' => $name, 'company' => $company))); - $mail->Send(); - } catch(phpmailerException $e) { - $mailerr_msg = $e->errorMessage(); - $_mailerror = true; - } catch (Exception $e) { - $mailerr_msg = $e->getMessage(); - $_mailerror = true; - } - - if ($_mailerror) { - $log->logAction(ADM_ACTION, LOG_ERR, "Error sending mail: " . $mailerr_msg); - standard_error('errorsendingmail', $email); - } - - $mail->ClearAddresses(); - $log->logAction(ADM_ACTION, LOG_NOTICE, "automatically sent password to user '" . $loginname . "'"); - } - redirectTo($filename, array('page' => $page, 's' => $s)); } - - } else { - $language_options = ''; - - while (list($language_file, $language_name) = each($languages)) { - $language_options.= makeoption($language_name, $language_file, Settings::Get('panel.standardlanguage'), true); - } - - $diskspace_ul = makecheckbox('diskspace_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); - $traffic_ul = makecheckbox('traffic_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); - $subdomains_ul = makecheckbox('subdomains_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); - $emails_ul = makecheckbox('emails_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); - $email_accounts_ul = makecheckbox('email_accounts_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); - $email_forwarders_ul = makecheckbox('email_forwarders_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); - $email_quota_ul = makecheckbox('email_quota_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); - $ftps_ul = makecheckbox('ftps_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); - $tickets_ul = makecheckbox('tickets_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); - $mysqls_ul = makecheckbox('mysqls_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); - - $gender_options = makeoption($lng['gender']['undef'], 0, true, true, true); - $gender_options .= makeoption($lng['gender']['male'], 1, null, true, true); - $gender_options .= makeoption($lng['gender']['female'], 2, null, true, true); - - $customer_add_data = include_once dirname(__FILE__).'/lib/formfields/admin/customer/formfield.customer_add.php'; - $customer_add_form = htmlform::genHTMLForm($customer_add_data); - - $title = $customer_add_data['customer_add']['title']; - $image = $customer_add_data['customer_add']['image']; - - eval("echo \"" . getTemplate("customers/customers_add") . "\";"); } - } - } elseif($action == 'edit' - && $id != 0 - ) { + // hosting plans + $hosting_plans = ""; + $plans = Database::query(" + SELECT * + FROM `" . TABLE_PANEL_PLANS . "` + ORDER BY name ASC + "); + if (Database::num_rows() > 0) { + $hosting_plans .= \Froxlor\UI\HTML::makeoption("---", 0, 0, true, true); + } + while ($row = $plans->fetch(PDO::FETCH_ASSOC)) { + $hosting_plans .= \Froxlor\UI\HTML::makeoption($row['name'], $row['id'], 0, true, true); + } - $result_data = array('id' => $id); - $result_stmt = Database::prepare(" - SELECT * FROM `" . TABLE_PANEL_CUSTOMERS . "` - WHERE `customerid` = :id" . ($userinfo['customers_see_all'] ? '' : " AND `adminid` = :adminid") - ); - if ($userinfo['customers_see_all'] == '0') { - $result_data['adminid'] = $userinfo['adminid']; + $customer_add_data = include_once dirname(__FILE__) . '/lib/formfields/admin/customer/formfield.customer_add.php'; + $customer_add_form = \Froxlor\UI\HtmlForm::genHTMLForm($customer_add_data); + + $title = $customer_add_data['customer_add']['title']; + $image = $customer_add_data['customer_add']['image']; + + eval("echo \"" . \Froxlor\UI\Template::getTemplate("customers/customers_add") . "\";"); } - $result = Database::pexecute_first($result_stmt, $result_data); + } elseif ($action == 'edit' && $id != 0) { + + try { + $json_result = Customers::getLocal($userinfo, array( + 'id' => $id + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; /* * information for moving customer */ $available_admins_stmt = Database::prepare(" - SELECT * FROM `" . TABLE_PANEL_ADMINS . "` - WHERE (`customers` = '-1' OR `customers` > `customers_used`)" - ); + SELECT * FROM `" . TABLE_PANEL_ADMINS . "` + WHERE (`customers` = '-1' OR `customers` > `customers_used`)"); Database::pexecute($available_admins_stmt); - $admin_select = makeoption("-----", 0, true, true, true); + $admin_select = \Froxlor\UI\HTML::makeoption("-----", 0, true, true, true); $admin_select_cnt = 0; while ($available_admin = $available_admins_stmt->fetch()) { - $admin_select .= makeoption($available_admin['name']." (".$available_admin['loginname'].")", $available_admin['adminid'], null, true, true); - $admin_select_cnt++; + $admin_select .= \Froxlor\UI\HTML::makeoption($available_admin['name'] . " (" . $available_admin['loginname'] . ")", $available_admin['adminid'], null, true, true); + $admin_select_cnt ++; } /* * end of moving customer stuff @@ -1061,540 +375,21 @@ if ($page == 'customers' if ($result['loginname'] != '') { - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { - - $name = validate($_POST['name'], 'name'); - $firstname = validate($_POST['firstname'], 'first name'); - $company = validate($_POST['company'], 'company'); - $street = validate($_POST['street'], 'street'); - $zipcode = validate($_POST['zipcode'], 'zipcode', '/^[0-9 \-A-Z]*$/'); - $city = validate($_POST['city'], 'city'); - $phone = validate($_POST['phone'], 'phone', '/^[0-9\- \+\(\)\/]*$/'); - $fax = validate($_POST['fax'], 'fax', '/^[0-9\- \+\(\)\/]*$/'); - $email = $idna_convert->encode(validate($_POST['email'], 'email')); - $customernumber = validate($_POST['customernumber'], 'customer number', '/^[A-Za-z0-9 \-]*$/Di'); - $def_language = validate($_POST['def_language'], 'default language'); - $password = validate($_POST['new_customer_password'], 'new password'); - $gender = intval_ressource($_POST['gender']); - - $move_to_admin = isset($_POST['move_to_admin']) ? intval_ressource($_POST['move_to_admin']) : 0; - - $custom_notes = validate(str_replace("\r\n", "\n", $_POST['custom_notes']), 'custom_notes', '/^[^\0]*$/'); - $custom_notes_show = $result['custom_notes_show']; - if (isset($_POST['custom_notes_show'])) { - $custom_notes_show = intval_ressource($_POST['custom_notes_show']); + if (isset($_POST['send']) && $_POST['send'] == 'send') { + try { + Customers::getLocal($userinfo, $_POST)->update(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } - - $diskspace = intval_ressource($_POST['diskspace']); - if (isset($_POST['diskspace_ul'])) { - $diskspace = - 1; - } - - $traffic = doubleval_ressource($_POST['traffic']); - if (isset($_POST['traffic_ul'])) { - $traffic = - 1; - } - - $subdomains = intval_ressource($_POST['subdomains']); - if (isset($_POST['subdomains_ul'])) { - $subdomains = - 1; - } - - $emails = intval_ressource($_POST['emails']); - if (isset($_POST['emails_ul'])) { - $emails = - 1; - } - - $email_accounts = intval_ressource($_POST['email_accounts']); - if (isset($_POST['email_accounts_ul'])) { - $email_accounts = - 1; - } - - $email_forwarders = intval_ressource($_POST['email_forwarders']); - if (isset($_POST['email_forwarders_ul'])) { - $email_forwarders = - 1; - } - - if (Settings::Get('system.mail_quota_enabled') == '1') { - $email_quota = validate($_POST['email_quota'], 'email_quota', '/^\d+$/', 'vmailquotawrong', array('0', '')); - if (isset($_POST['email_quota_ul'])) { - $email_quota = - 1; - } - } else { - $email_quota = - 1; - } - - $email_imap = 0; - if (isset($_POST['email_imap'])) { - $email_imap = intval_ressource($_POST['email_imap']); - } - - $email_pop3 = 0; - if (isset($_POST['email_pop3'])) { - $email_pop3 = intval_ressource($_POST['email_pop3']); - } - - $ftps = 0; - if (isset($_POST['ftps'])) { - $ftps = intval_ressource($_POST['ftps']); - } - if (isset($_POST['ftps_ul'])) { - $ftps = - 1; - } - - $tickets = (Settings::Get('ticket.enabled') == 1 ? intval_ressource($_POST['tickets']) : 0); - if (isset($_POST['tickets_ul']) - && Settings::Get('ticket.enabled') == '1' - ) { - $tickets = - 1; - } - - // gender out of range? [0,2] - if ($gender < 0 || $gender > 2) { - $gender = 0; - } - - $mysqls = 0; - if (isset($_POST['mysqls'])) { - $mysqls = intval_ressource($_POST['mysqls']); - } - if (isset($_POST['mysqls_ul'])) { - $mysqls = - 1; - } - - $createstdsubdomain = 0; - if (isset($_POST['createstdsubdomain'])) { - $createstdsubdomain = intval($_POST['createstdsubdomain']); - } - - $deactivated = 0; - if (isset($_POST['deactivated'])) { - $deactivated = intval($_POST['deactivated']); - } - - $phpenabled = 0; - if (isset($_POST['phpenabled'])) { - $phpenabled = intval($_POST['phpenabled']); - } - - $perlenabled = 0; - if (isset($_POST['perlenabled'])) { - $perlenabled = intval($_POST['perlenabled']); - } - - $diskspace = $diskspace * 1024; - $traffic = $traffic * 1024 * 1024; - - if (((($userinfo['diskspace_used'] + $diskspace - $result['diskspace']) > $userinfo['diskspace']) && ($userinfo['diskspace'] / 1024) != '-1') - || ((($userinfo['mysqls_used'] + $mysqls - $result['mysqls']) > $userinfo['mysqls']) && $userinfo['mysqls'] != '-1') - || ((($userinfo['emails_used'] + $emails - $result['emails']) > $userinfo['emails']) && $userinfo['emails'] != '-1') - || ((($userinfo['email_accounts_used'] + $email_accounts - $result['email_accounts']) > $userinfo['email_accounts']) && $userinfo['email_accounts'] != '-1') - || ((($userinfo['email_forwarders_used'] + $email_forwarders - $result['email_forwarders']) > $userinfo['email_forwarders']) && $userinfo['email_forwarders'] != '-1') - || ((($userinfo['email_quota_used'] + $email_quota - $result['email_quota']) > $userinfo['email_quota']) && $userinfo['email_quota'] != '-1' && Settings::Get('system.mail_quota_enabled') == '1') - || ((($userinfo['ftps_used'] + $ftps - $result['ftps']) > $userinfo['ftps']) && $userinfo['ftps'] != '-1') - || ((($userinfo['tickets_used'] + $tickets - $result['tickets']) > $userinfo['tickets']) && $userinfo['tickets'] != '-1') - || ((($userinfo['subdomains_used'] + $subdomains - $result['subdomains']) > $userinfo['subdomains']) && $userinfo['subdomains'] != '-1') - || (($diskspace / 1024) == '-1' && ($userinfo['diskspace'] / 1024) != '-1') - || ($mysqls == '-1' && $userinfo['mysqls'] != '-1') - || ($emails == '-1' && $userinfo['emails'] != '-1') - || ($email_accounts == '-1' && $userinfo['email_accounts'] != '-1') - || ($email_forwarders == '-1' && $userinfo['email_forwarders'] != '-1') - || ($email_quota == '-1' && $userinfo['email_quota'] != '-1' && Settings::Get('system.mail_quota_enabled') == '1') - || ($ftps == '-1' && $userinfo['ftps'] != '-1') - || ($tickets == '-1' && $userinfo['tickets'] != '-1') - || ($subdomains == '-1' && $userinfo['subdomains'] != '-1') - ) { - standard_error('youcantallocatemorethanyouhave'); - } - - // Either $name and $firstname or the $company must be inserted - if ($name == '' && $company == '') { - standard_error(array('stringisempty', 'myname')); - - } elseif($firstname == '' && $company == '') { - standard_error(array('stringisempty', 'myfirstname')); - - } elseif($email == '') { - standard_error(array('stringisempty', 'emailadd')); - - } elseif(!validateEmail($email)) { - standard_error('emailiswrong', $email); - - } else { - - if ($password != '') { - $password = validatePassword($password); - $password = makeCryptPassword($password); - } else { - $password = $result['password']; - } - - if ($createstdsubdomain != '1') { - $createstdsubdomain = '0'; - } - - if ($createstdsubdomain == '1' - && $result['standardsubdomain'] == '0' - ) { - - if (Settings::Get('system.stdsubdomain') !== null - && Settings::Get('system.stdsubdomain') != '' - ) { - $_stdsubdomain = $result['loginname'] . '.' . Settings::Get('system.stdsubdomain'); - } else { - $_stdsubdomain = $result['loginname'] . '.' . Settings::Get('system.hostname'); - } - - $ins_data = array( - 'domain' => $_stdsubdomain, - 'customerid' => $result['customerid'], - 'adminid' => $userinfo['adminid'], - 'docroot' => $result['documentroot'], - 'adddate' => date('Y-m-d') - ); - $ins_stmt = Database::prepare(" - INSERT INTO `" . TABLE_PANEL_DOMAINS . "` SET - `domain` = :domain, - `customerid` = :customerid, - `adminid` = :adminid, - `parentdomainid` = '0', - `documentroot` = :docroot, - `zonefile` = '', - `isemaildomain` = '0', - `caneditdomain` = '0', - `openbasedir` = '1', - `speciallogfile` = '0', - `specialsettings` = '', - `add_date` = :adddate" - ); - Database::pexecute($ins_stmt, $ins_data); - $domainid = Database::lastInsertId(); - - // set ip <-> domain connection - $defaultips = explode(',', Settings::Get('system.defaultip')); - $ins_stmt = Database::prepare(" - INSERT INTO `" . TABLE_DOMAINTOIP . "` SET `id_domain` = :domainid, `id_ipandports` = :ipid" - ); - foreach ($defaultips as $defaultip) { - Database::pexecute($ins_stmt, array('domainid' => $domainid, 'ipid' => $defaultip)); - } - - $upd_stmt = Database::prepare(" - UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET `standardsubdomain` = :domainid WHERE `customerid` = :customerid" - ); - Database::pexecute($upd_stmt, array('domainid' => $domainid, 'customerid' => $result['customerid'])); - $log->logAction(ADM_ACTION, LOG_NOTICE, "automatically added standardsubdomain for user '" . $result['loginname'] . "'"); - inserttask('1'); - } - - if ($createstdsubdomain == '0' - && $result['standardsubdomain'] != '0' - ) { - - $del_stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `id` = :stdsub"); - Database::pexecute($del_stmt, array('stdsub' => $result['standardsubdomain'])); - $del_stmt = Database::prepare("DELETE FROM `" . TABLE_DOMAINTOIP . "` WHERE `id_domain` = :stdsub"); - Database::pexecute($del_stmt, array('stdsub' => $result['standardsubdomain'])); - $del_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET `standardsubdomain`= '0' WHERE `customerid` = :customerid"); - Database::pexecute($del_stmt, array('customerid' => $result['customerid'])); - $log->logAction(ADM_ACTION, LOG_NOTICE, "automatically deleted standardsubdomain for user '" . $result['loginname'] . "'"); - inserttask('1'); - } - - if ($deactivated != '1') { - $deactivated = '0'; - } - - if ($phpenabled != '0') { - $phpenabled = '1'; - } - - if ($perlenabled != '0') { - $perlenabled = '1'; - } - - if ($phpenabled != $result['phpenabled'] - || $perlenabled != $result['perlenabled'] - ) { - inserttask('1'); - } - - // activate/deactivate customer services - if ($deactivated != $result['deactivated']) { - - $yesno = (($deactivated) ? 'N' : 'Y'); - $pop3 = (($deactivated) ? '0' : (int)$result['pop3']); - $imap = (($deactivated) ? '0' : (int)$result['imap']); - - $upd_stmt = Database::prepare(" - UPDATE `" . TABLE_MAIL_USERS . "` SET `postfix`= :yesno, `pop3` = :pop3, `imap` = :imap WHERE `customerid` = :customerid" - ); - Database::pexecute($upd_stmt, array('yesno' => $yesno, 'pop3' => $pop3, 'imap' => $imap, 'customerid' => $id)); - - $upd_stmt = Database::prepare(" - UPDATE `" . TABLE_FTP_USERS . "` SET `login_enabled` = :yesno WHERE `customerid` = :customerid" - ); - Database::pexecute($upd_stmt, array('yesno' => $yesno, 'customerid' => $id)); - - $upd_stmt = Database::prepare(" - UPDATE `" . TABLE_PANEL_DOMAINS . "` SET `deactivated`= :deactivated WHERE `customerid` = :customerid" - ); - Database::pexecute($upd_stmt, array('deactivated' => $deactivated, 'customerid' => $id)); - - // Retrieve customer's databases - $databases_stmt = Database::prepare("SELECT * FROM " . TABLE_PANEL_DATABASES . " WHERE customerid = :customerid ORDER BY `dbserver`"); - Database::pexecute($databases_stmt, array('customerid' => $id)); - - Database::needRoot(true); - $last_dbserver = 0; - - $dbm = new DbManager($log); - - // For each of them - while ($row_database = $databases_stmt->fetch(PDO::FETCH_ASSOC)) { - - if ($last_dbserver != $row_database['dbserver']) { - $dbm->getManager()->flushPrivileges(); - Database::needRoot(true, $row_database['dbserver']); - $last_dbserver = $row_database['dbserver']; - } - - foreach (array_unique(explode(',', Settings::Get('system.mysql_access_host'))) as $mysql_access_host) { - $mysql_access_host = trim($mysql_access_host); - - // Prevent access, if deactivated - if ($deactivated) { - // failsafe if user has been deleted manually (requires MySQL 4.1.2+) - $dbm->getManager()->disableUser($row_database['databasename'], $mysql_access_host); - } else { - // Otherwise grant access - $dbm->getManager()->enableUser($row_database['databasename'], $mysql_access_host); - } - } - } - - // At last flush the new privileges - $dbm->getManager()->flushPrivileges(); - Database::needRoot(false); - - $log->logAction(ADM_ACTION, LOG_INFO, "deactivated user '" . $result['loginname'] . "'"); - inserttask('1'); - } - - // Disable or enable POP3 Login for customers Mail Accounts - if ($email_pop3 != $result['pop3']) { - $upd_stmt = Database::prepare("UPDATE `" . TABLE_MAIL_USERS . "` SET `pop3` = :pop3 WHERE `customerid` = :customerid"); - Database::pexecute($upd_stmt, array('pop3' => $email_pop3, 'customerid' => $id)); - } - - // Disable or enable IMAP Login for customers Mail Accounts - if ($email_imap != $result['imap']) { - $upd_stmt = Database::prepare("UPDATE `" . TABLE_MAIL_USERS . "` SET `imap` = :imap WHERE `customerid` = :customerid"); - Database::pexecute($upd_stmt, array('imap' => $email_imap, 'customerid' => $id)); - } - - $upd_data = array( - 'customerid' => $id, - 'passwd' => $password, - 'name' => $name, - 'firstname' => $firstname, - 'gender' => $gender, - 'company' => $company, - 'street' => $street, - 'zipcode' => $zipcode, - 'city' => $city, - 'phone' => $phone, - 'fax' => $fax, - 'email' => $email, - 'customerno' => $customernumber, - 'lang' => $def_language, - 'diskspace' => $diskspace, - 'traffic' => $traffic, - 'subdomains' => $subdomains, - 'emails' => $emails, - 'email_accounts' => $email_accounts, - 'email_forwarders' => $email_forwarders, - 'email_quota' => $email_quota, - 'ftps' => $ftps, - 'tickets' => $tickets, - 'mysqls' => $mysqls, - 'deactivated' => $deactivated, - 'phpenabled' => $phpenabled, - 'imap' => $email_imap, - 'pop3' => $email_pop3, - 'perlenabled' => $perlenabled, - 'custom_notes' => $custom_notes, - 'custom_notes_show' => $custom_notes_show - ); - $upd_stmt = Database::prepare(" - UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET - `name` = :name, - `firstname` = :firstname, - `gender` = :gender, - `company` = :company, - `street` = :street, - `zipcode` = :zipcode, - `city` = :city, - `phone` = :phone, - `fax` = :fax, - `email` = :email, - `customernumber` = :customerno, - `def_language` = :lang, - `password` = :passwd, - `diskspace` = :diskspace, - `traffic` = :traffic, - `subdomains` = :subdomains, - `emails` = :emails, - `email_accounts` = :email_accounts, - `email_forwarders` = :email_forwarders, - `ftps` = :ftps, - `tickets` = :tickets, - `mysqls` = :mysqls, - `deactivated` = :deactivated, - `phpenabled` = :phpenabled, - `email_quota` = :email_quota, - `imap` = :imap, - `pop3` = :pop3, - `perlenabled` = :perlenabled, - `custom_notes` = :custom_notes, - `custom_notes_show` = :custom_notes_show - WHERE `customerid` = :customerid" - ); - Database::pexecute($upd_stmt, $upd_data); - - // Using filesystem - quota, insert a task which cleans the filesystem - quota - inserttask('10'); - - $admin_update_query = "UPDATE `" . TABLE_PANEL_ADMINS . "` SET `customers_used` = `customers_used` "; - - if ($mysqls != '-1' || $result['mysqls'] != '-1') { - $admin_update_query.= ", `mysqls_used` = `mysqls_used` "; - - if ($mysqls != '-1') { - $admin_update_query.= " + 0" . (int)$mysqls . " "; - } - if ($result['mysqls'] != '-1') { - $admin_update_query.= " - 0" . (int)$result['mysqls'] . " "; - } - } - - if($emails != '-1' || $result['emails'] != '-1') { - $admin_update_query.= ", `emails_used` = `emails_used` "; - - if ($emails != '-1') { - $admin_update_query.= " + 0" . (int)$emails . " "; - } - if ($result['emails'] != '-1') { - $admin_update_query.= " - 0" . (int)$result['emails'] . " "; - } - } - - if ($email_accounts != '-1' || $result['email_accounts'] != '-1') { - $admin_update_query.= ", `email_accounts_used` = `email_accounts_used` "; - - if ($email_accounts != '-1') { - $admin_update_query.= " + 0" . (int)$email_accounts . " "; - } - if ($result['email_accounts'] != '-1') { - $admin_update_query.= " - 0" . (int)$result['email_accounts'] . " "; - } - } - - if ($email_forwarders != '-1' || $result['email_forwarders'] != '-1') { - $admin_update_query.= ", `email_forwarders_used` = `email_forwarders_used` "; - - if ($email_forwarders != '-1') { - $admin_update_query.= " + 0" . (int)$email_forwarders . " "; - } - if ($result['email_forwarders'] != '-1') { - $admin_update_query.= " - 0" . (int)$result['email_forwarders'] . " "; - } - } - - if ($email_quota != '-1' || $result['email_quota'] != '-1') { - $admin_update_query.= ", `email_quota_used` = `email_quota_used` "; - - if ($email_quota != '-1') { - $admin_update_query.= " + 0" . (int)$email_quota . " "; - } - if ($result['email_quota'] != '-1') { - $admin_update_query.= " - 0" . (int)$result['email_quota'] . " "; - } - } - - if ($subdomains != '-1' || $result['subdomains'] != '-1') { - $admin_update_query.= ", `subdomains_used` = `subdomains_used` "; - - if ($subdomains != '-1') { - $admin_update_query.= " + 0" . (int)$subdomains . " "; - } - if ($result['subdomains'] != '-1') { - $admin_update_query.= " - 0" . (int)$result['subdomains'] . " "; - } - } - - if ($ftps != '-1' || $result['ftps'] != '-1') { - $admin_update_query.= ", `ftps_used` = `ftps_used` "; - - if ($ftps != '-1') { - $admin_update_query.= " + 0" . (int)$ftps . " "; - } - if ($result['ftps'] != '-1') { - $admin_update_query.= " - 0" . (int)$result['ftps'] . " "; - } - } - - if ($tickets != '-1' || $result['tickets'] != '-1') { - $admin_update_query.= ", `tickets_used` = `tickets_used` "; - - if ($tickets != '-1') { - $admin_update_query.= " + 0" . (int)$tickets . " "; - } - if ($result['tickets'] != '-1') { - $admin_update_query.= " - 0" . (int)$result['tickets'] . " "; - } - } - - if (($diskspace / 1024) != '-1' || ($result['diskspace'] / 1024) != '-1') { - $admin_update_query.= ", `diskspace_used` = `diskspace_used` "; - - if (($diskspace / 1024) != '-1') { - $admin_update_query.= " + 0" . (int)$diskspace . " "; - } - if (($result['diskspace'] / 1024) != '-1') { - $admin_update_query.= " - 0" . (int)$result['diskspace'] . " "; - } - } - - $admin_update_query.= " WHERE `adminid` = '" . (int)$result['adminid'] . "'"; - Database::query($admin_update_query); - $log->logAction(ADM_ACTION, LOG_INFO, "edited user '" . $result['loginname'] . "'"); - - /* - * move customer to another admin/reseller; #1166 - */ - if ($move_to_admin > 0 && $move_to_admin != $result['adminid']) { - $move_result = moveCustomerToAdmin($id, $move_to_admin); - if ($move_result != true) { - standard_error('moveofcustomerfailed', $move_result); - } - } - - $redirect_props = Array( - 'page' => $page, - 's' => $s - ); - - redirectTo($filename, $redirect_props); - } - + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); } else { $language_options = ''; - while (list($language_file, $language_name) = each($languages)) { - $language_options.= makeoption($language_name, $language_file, $result['def_language'], true); + foreach ($languages as $language_file => $language_name) { + $language_options .= \Froxlor\UI\HTML::makeoption($language_name, $language_file, $result['def_language'], true); } $dec_places = Settings::Get('panel.decimal_places'); @@ -1602,69 +397,98 @@ if ($page == 'customers' $result['diskspace'] = round($result['diskspace'] / 1024, $dec_places); $result['email'] = $idna_convert->decode($result['email']); - $diskspace_ul = makecheckbox('diskspace_ul', $lng['customer']['unlimited'], '-1', false, $result['diskspace'], true, true); + $diskspace_ul = \Froxlor\UI\HTML::makecheckbox('diskspace_ul', $lng['customer']['unlimited'], '-1', false, $result['diskspace'], true, true); if ($result['diskspace'] == '-1') { $result['diskspace'] = ''; } - $traffic_ul = makecheckbox('traffic_ul', $lng['customer']['unlimited'], '-1', false, $result['traffic'], true, true); + $traffic_ul = \Froxlor\UI\HTML::makecheckbox('traffic_ul', $lng['customer']['unlimited'], '-1', false, $result['traffic'], true, true); if ($result['traffic'] == '-1') { $result['traffic'] = ''; } - $subdomains_ul = makecheckbox('subdomains_ul', $lng['customer']['unlimited'], '-1', false, $result['subdomains'], true, true); + $subdomains_ul = \Froxlor\UI\HTML::makecheckbox('subdomains_ul', $lng['customer']['unlimited'], '-1', false, $result['subdomains'], true, true); if ($result['subdomains'] == '-1') { $result['subdomains'] = ''; } - $emails_ul = makecheckbox('emails_ul', $lng['customer']['unlimited'], '-1', false, $result['emails'], true, true); + $emails_ul = \Froxlor\UI\HTML::makecheckbox('emails_ul', $lng['customer']['unlimited'], '-1', false, $result['emails'], true, true); if ($result['emails'] == '-1') { $result['emails'] = ''; } - $email_accounts_ul = makecheckbox('email_accounts_ul', $lng['customer']['unlimited'], '-1', false, $result['email_accounts'], true, true); + $email_accounts_ul = \Froxlor\UI\HTML::makecheckbox('email_accounts_ul', $lng['customer']['unlimited'], '-1', false, $result['email_accounts'], true, true); if ($result['email_accounts'] == '-1') { $result['email_accounts'] = ''; } - $email_forwarders_ul = makecheckbox('email_forwarders_ul', $lng['customer']['unlimited'], '-1', false, $result['email_forwarders'], true, true); + $email_forwarders_ul = \Froxlor\UI\HTML::makecheckbox('email_forwarders_ul', $lng['customer']['unlimited'], '-1', false, $result['email_forwarders'], true, true); if ($result['email_forwarders'] == '-1') { $result['email_forwarders'] = ''; } - $email_quota_ul = makecheckbox('email_quota_ul', $lng['customer']['unlimited'], '-1', false, $result['email_quota'], true, true); + $email_quota_ul = \Froxlor\UI\HTML::makecheckbox('email_quota_ul', $lng['customer']['unlimited'], '-1', false, $result['email_quota'], true, true); if ($result['email_quota'] == '-1') { $result['email_quota'] = ''; } - $ftps_ul = makecheckbox('ftps_ul', $lng['customer']['unlimited'], '-1', false, $result['ftps'], true, true); + $ftps_ul = \Froxlor\UI\HTML::makecheckbox('ftps_ul', $lng['customer']['unlimited'], '-1', false, $result['ftps'], true, true); if ($result['ftps'] == '-1') { $result['ftps'] = ''; } - $tickets_ul = makecheckbox('tickets_ul', $lng['customer']['unlimited'], '-1', false, $result['tickets'], true, true); - if ($result['tickets'] == '-1') { - $result['tickets'] = ''; - } - - $mysqls_ul = makecheckbox('mysqls_ul', $lng['customer']['unlimited'], '-1', false, $result['mysqls'], true, true); + $mysqls_ul = \Froxlor\UI\HTML::makecheckbox('mysqls_ul', $lng['customer']['unlimited'], '-1', false, $result['mysqls'], true, true); if ($result['mysqls'] == '-1') { $result['mysqls'] = ''; } - $result = htmlentities_array($result); + $result = \Froxlor\PhpHelper::htmlentitiesArray($result); - $gender_options = makeoption($lng['gender']['undef'], 0, ($result['gender'] == '0' ? true : false), true, true); - $gender_options .= makeoption($lng['gender']['male'], 1, ($result['gender'] == '1' ? true : false), true, true); - $gender_options .= makeoption($lng['gender']['female'], 2, ($result['gender'] == '2' ? true : false), true, true); + $gender_options = \Froxlor\UI\HTML::makeoption($lng['gender']['undef'], 0, ($result['gender'] == '0' ? true : false), true, true); + $gender_options .= \Froxlor\UI\HTML::makeoption($lng['gender']['male'], 1, ($result['gender'] == '1' ? true : false), true, true); + $gender_options .= \Froxlor\UI\HTML::makeoption($lng['gender']['female'], 2, ($result['gender'] == '2' ? true : false), true, true); - $customer_edit_data = include_once dirname(__FILE__).'/lib/formfields/admin/customer/formfield.customer_edit.php'; - $customer_edit_form = htmlform::genHTMLForm($customer_edit_data); + $phpconfigs = array(); + $configs = Database::query(" + SELECT c.*, fc.description as interpreter + FROM `" . TABLE_PANEL_PHPCONFIGS . "` c + LEFT JOIN `" . TABLE_PANEL_FPMDAEMONS . "` fc ON fc.id = c.fpmsettingid + "); + while ($row = $configs->fetch(PDO::FETCH_ASSOC)) { + if ((int) Settings::Get('phpfpm.enabled') == 1) { + $phpconfigs[] = array( + 'label' => $row['description'] . " [" . $row['interpreter'] . "]
", + 'value' => $row['id'] + ); + } else { + $phpconfigs[] = array( + 'label' => $row['description'] . "
", + 'value' => $row['id'] + ); + } + } + + // hosting plans + $hosting_plans = ""; + $plans = Database::query(" + SELECT * + FROM `" . TABLE_PANEL_PLANS . "` + ORDER BY name ASC + "); + if (Database::num_rows() > 0) { + $hosting_plans .= \Froxlor\UI\HTML::makeoption("---", 0, 0, true, true); + } + while ($row = $plans->fetch(PDO::FETCH_ASSOC)) { + $hosting_plans .= \Froxlor\UI\HTML::makeoption($row['name'], $row['id'], 0, true, true); + } + + $customer_edit_data = include_once dirname(__FILE__) . '/lib/formfields/admin/customer/formfield.customer_edit.php'; + $customer_edit_form = \Froxlor\UI\HtmlForm::genHTMLForm($customer_edit_data); $title = $customer_edit_data['customer_edit']['title']; $image = $customer_edit_data['customer_edit']['image']; - eval("echo \"" . getTemplate("customers/customers_edit") . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("customers/customers_edit") . "\";"); } } } diff --git a/admin_domains.php b/admin_domains.php index 1ff3ea25..16734d20 100644 --- a/admin_domains.php +++ b/admin_domains.php @@ -16,1039 +16,309 @@ * @package Panel * */ - define('AREA', 'admin'); require './lib/init.php'; +use Froxlor\Database\Database; +use Froxlor\Settings; +use Froxlor\Api\Commands\Customers as Customers; +use Froxlor\Api\Commands\Domains as Domains; + if (isset($_POST['id'])) { $id = intval($_POST['id']); -} elseif(isset($_GET['id'])) { +} elseif (isset($_GET['id'])) { $id = intval($_GET['id']); } -if ($page == 'domains' - || $page == 'overview' -) { +if ($page == 'domains' || $page == 'overview') { // Let's see how many customers we have - $stmt = Database::prepare(" - SELECT COUNT(`customerid`) as `countcustomers` FROM `" . TABLE_PANEL_CUSTOMERS . "` " . ($userinfo['customers_see_all'] ? '' : " WHERE `adminid` = :adminid") - ); - $params = array(); - if ($userinfo['customers_see_all'] == '0') { - $params['adminid'] = $userinfo['adminid']; - } - $countcustomers = Database::pexecute_first($stmt, $params); - $countcustomers = (int)$countcustomers['countcustomers']; + $json_result = Customers::getLocal($userinfo)->listingCount(); + $countcustomers = json_decode($json_result, true)['data']; if ($action == '') { - $log->logAction(ADM_ACTION, LOG_NOTICE, "viewed admin_domains"); + $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'], 'c.loginname' => $lng['login']['username'], 'd.aliasdomain' => $lng['domains']['aliasdomain'] ); - $paging = new paging($userinfo, TABLE_PANEL_DOMAINS, $fields); - $domains = ''; - $result_stmt = Database::prepare(" - SELECT `d`.*, `c`.`loginname`, `c`.`name`, `c`.`firstname`, `c`.`company`, `c`.`standardsubdomain`, `ad`.`id` AS `aliasdomainid`, `ad`.`domain` AS `aliasdomain` - FROM `" . TABLE_PANEL_DOMAINS . "` `d` - LEFT JOIN `" . TABLE_PANEL_CUSTOMERS . "` `c` USING(`customerid`) - LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` `ad` ON `d`.`aliasdomain`=`ad`.`id` - WHERE `d`.`parentdomainid`='0' " . - ($userinfo['customers_see_all'] ? '' : " AND `d`.`adminid` = :adminid ") . - " " . $paging->getSqlWhere(true) . " " . $paging->getSqlOrderBy() . " " . $paging->getSqlLimit() - ); - $params = array(); - if ($userinfo['customers_see_all'] == '0') { - $params['adminid'] = $userinfo['adminid']; + try { + // get total count + $json_result = Domains::getLocal($userinfo)->listingCount(); + $result = json_decode($json_result, true)['data']; + // initialize pagination and filtering + $paging = new \Froxlor\UI\Pagination($userinfo, $fields, $result); + // get list + $json_result = Domains::getLocal($userinfo, $paging->getApiCommandParams())->listing(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } - Database::pexecute($result_stmt, $params); - $numrows_domains = Database::num_rows(); - $paging->setEntries($numrows_domains); + $result = json_decode($json_result, true)['data']; + + $domains = ''; $sortcode = $paging->getHtmlSortCode($lng); $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); $searchcode = $paging->getHtmlSearchCode($lng); $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); - $domain_array = array(); - while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { - - $row['domain'] = $idna_convert->decode($row['domain']); - $row['aliasdomain'] = $idna_convert->decode($row['aliasdomain']); - - $resultips_stmt = Database::prepare(" - SELECT `ips`.* FROM `".TABLE_DOMAINTOIP . "` AS `dti`, `".TABLE_PANEL_IPSANDPORTS."` AS `ips` - WHERE `dti`.`id_ipandports` = `ips`.`id` AND `dti`.`id_domain` = :domainid" - ); - Database::pexecute($resultips_stmt, array('domainid' => $row['id'])); - - $row['ipandport'] = ''; - while ($rowip = $resultips_stmt->fetch(PDO::FETCH_ASSOC)) { - - if (filter_var($rowip['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { - $row['ipandport'] .= '[' . $rowip['ip'] . ']:' . $rowip['port'] . "\n"; - } else { - $row['ipandport'] .= $rowip['ip'] . ':' . $rowip['port'] . "\n"; - } - } - $row['ipandport'] = substr($row['ipandport'], 0, -1); - $row['termination_date'] = str_replace("0000-00-00", "", $row['termination_date']); - - if($row['termination_date'] != "") - { - $cdate = strtotime($row['termination_date'] . " 23:59:59"); - $today = time(); - - if($cdate < $today) - { - $row['termination_css'] = 'domain-expired'; - } - else - { - $row['termination_css'] = 'domain-canceled'; - } - } - - if (!isset($domain_array[$row['domain']])) { - $domain_array[$row['domain']] = $row; - } else { - $domain_array[$row['domain']] = array_merge($row, $domain_array[$row['domain']]); - } - - if (isset($row['aliasdomainid']) - && $row['aliasdomainid'] != null - && isset($row['aliasdomain']) - && $row['aliasdomain'] != '' - ) { - if (!isset($domain_array[$row['aliasdomain']])) { - $domain_array[$row['aliasdomain']] = array(); - } - $domain_array[$row['aliasdomain']]['domainaliasid'] = $row['id']; - $domain_array[$row['aliasdomain']]['domainalias'] = $row['domain']; - } - } - - /** - * We need ksort/krsort here to make sure idna-domains are also sorted correctly - */ - if ($paging->sortfield == 'd.domain' - && $paging->sortorder == 'asc' - ) { - ksort($domain_array); - } elseif ($paging->sortfield == 'd.domain' - && $paging->sortorder == 'desc' - ) { - krsort($domain_array); - } - - $i = 0; $count = 0; - foreach ($domain_array as $row) { - - if (isset($row['domain']) - && $row['domain'] != '' - && $paging->checkDisplay($i) - ) { - $row['customername'] = getCorrectFullUserDetails($row); - $row = htmlentities_array($row); - // display a nice list of IP's + foreach ($result['list'] as $row) { + formatDomainEntry($row, $idna_convert); + $row['customername'] = \Froxlor\User::getCorrectFullUserDetails($row); + $row = \Froxlor\PhpHelper::htmlentitiesArray($row); + // display a nice list of IP's if it's not an alias for another domain + if (isset($row['aliasdomainid']) && $row['aliasdomainid'] != null && isset($row['aliasdomain']) && $row['aliasdomain'] != '') { + $row['ipandport'] = sprintf($lng['domains']['isaliasdomainof'], $row['aliasdomain']); + } else { $row['ipandport'] = str_replace("\n", "
", $row['ipandport']); - eval("\$domains.=\"" . getTemplate("domains/domains_domain") . "\";"); - $count++; } - $i++; + eval("\$domains.=\"" . \Froxlor\UI\Template::getTemplate("domains/domains_domain") . "\";"); + $count++; } - $domainscount = $numrows_domains; + $domainscount = $result['count'] . " / " . $paging->getEntries(); // Display the list - eval("echo \"" . getTemplate("domains/domains") . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("domains/domains") . "\";"); + } elseif ($action == 'delete' && $id != 0) { - } elseif($action == 'delete' - && $id != 0 - ) { - - $result_stmt = Database::prepare(" - SELECT `d`.* FROM `" . TABLE_PANEL_DOMAINS . "` `d`, `" . TABLE_PANEL_CUSTOMERS . "` `c` - WHERE `d`.`id` = :id AND `d`.`id` <> `c`.`standardsubdomain`" . - ($userinfo['customers_see_all'] ? '' : " AND `d`.`adminid` = :adminid") - ); - $params = array('id' => $id); - if ($userinfo['customers_see_all'] == '0') { - $params['adminid'] = $userinfo['adminid']; + try { + $json_result = Domains::getLocal($userinfo, array( + 'id' => $id, + 'no_std_subdomain' => true + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } - $result = Database::pexecute_first($result_stmt, $params); + $result = json_decode($json_result, true)['data']; $alias_check_stmt = Database::prepare(" SELECT COUNT(`id`) AS `count` FROM `" . TABLE_PANEL_DOMAINS . "` - WHERE `aliasdomain`= :id" - ); - $alias_check = Database::pexecute_first($alias_check_stmt, array('id' => $id)); + WHERE `aliasdomain`= :id"); + $alias_check = Database::pexecute_first($alias_check_stmt, array( + 'id' => $id + )); - if ($result['domain'] != '' - && $alias_check['count'] == 0 - ) { - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { - // check for deletion of main-domains which are logically subdomains, #329 - $rsd_sql = ''; - $remove_subbutmain_domains = isset($_POST['delete_userfiles']) ? 1 : 0; - if ($remove_subbutmain_domains == 1) { - $rsd_sql .= " OR `ismainbutsubto` = :id"; + if ($result['domain'] != '') { + if (isset($_POST['send']) && $_POST['send'] == 'send' && $alias_check['count'] == 0) { + + try { + Domains::getLocal($userinfo, $_POST)->delete(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } - $subresult_stmt = Database::prepare(" - SELECT `id` FROM `" . TABLE_PANEL_DOMAINS . "` - WHERE (`id` = :id OR `parentdomainid` = :id ".$rsd_sql.") AND `isemaildomain` = '1'" - ); - Database::pexecute($subresult_stmt, array('id' => $id)); - $idString = array(); - $paramString = array(); - while ($subRow = $subresult_stmt->fetch(PDO::FETCH_ASSOC)) { - $idString[] = "`domainid` = :domain_" . (int)$subRow['id']; - $paramString['domain_'.$subRow['id']] = $subRow['id']; - } - - $idString = implode(' OR ', $idString); - - if ($idString != '') { - $del_stmt = Database::prepare(" - DELETE FROM `" . TABLE_MAIL_USERS . "` WHERE " . $idString - ); - Database::pexecute($del_stmt, $paramString); - $del_stmt = Database::prepare(" - DELETE FROM `" . TABLE_MAIL_VIRTUAL . "` WHERE " . $idString - ); - Database::pexecute($del_stmt, $paramString); - $log->logAction(ADM_ACTION, LOG_NOTICE, "deleted domain/s from mail-tables"); - } - - $del_stmt = Database::prepare(" - DELETE FROM `" . TABLE_PANEL_DOMAINS . "` - WHERE `id` = :id OR `parentdomainid` = :id ".$rsd_sql - ); - Database::pexecute($del_stmt, array('id' => $id)); - $deleted_domains = $del_stmt->rowCount(); - - $upd_stmt = Database::prepare(" - UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET - `subdomains_used` = `subdomains_used` - :domaincount - WHERE `customerid` = :customerid" - ); - Database::pexecute($upd_stmt, array('domaincount' => ($deleted_domains -1), 'customerid' => $result['customerid'])); - - $upd_stmt = Database::prepare(" - UPDATE `" . TABLE_PANEL_ADMINS . "` SET - `domains_used` = `domains_used` - 1 - WHERE `adminid` = :adminid" - ); - Database::pexecute($upd_stmt, array('adminid' => $userinfo['adminid'])); - - $upd_stmt = Database::prepare(" - UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET - `standardsubdomain` = '0' - WHERE `standardsubdomain` = :id AND `customerid` = :customerid" - ); - Database::pexecute($upd_stmt, array('id' => $result['id'], 'customerid' => $result['customerid'])); - - $del_stmt = Database::prepare(" - DELETE FROM `" . TABLE_DOMAINTOIP . "` - WHERE `id_domain` = :domainid" - ); - Database::pexecute($del_stmt, array('domainid' => $id)); - - $del_stmt = Database::prepare(" - DELETE FROM `" . TABLE_PANEL_DOMAINREDIRECTS . "` - WHERE `did` = :domainid" - ); - Database::pexecute($del_stmt, array('domainid' => $id)); - - // remove certificate from domain_ssl_settings, fixes #1596 - $del_stmt = Database::prepare(" - DELETE FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` - WHERE `domainid` = :domainid" - ); - Database::pexecute($del_stmt, array('domainid' => $id)); - - $log->logAction(ADM_ACTION, LOG_INFO, "deleted domain/subdomains (#" . $result['id'] . ")"); - updateCounters(); - inserttask('1'); - - // Using nameserver, insert a task which rebuilds the server config - inserttask('4'); - - redirectTo($filename, array('page' => $page, 's' => $s)); - + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); } elseif ($alias_check['count'] > 0) { - standard_error('domains_cantdeletedomainwithaliases'); - + \Froxlor\UI\Response::standard_error('domains_cantdeletedomainwithaliases'); } else { $showcheck = false; - if (domainHasMainSubDomains($id)) { + if (\Froxlor\Domain\Domain::domainHasMainSubDomains($id)) { $showcheck = true; } - ask_yesno_withcheckbox('admin_domain_reallydelete', 'remove_subbutmain_domains', $filename, array('id' => $id, 'page' => $page, 'action' => $action), $idna_convert->decode($result['domain']), $showcheck); + \Froxlor\UI\HTML::askYesNoWithCheckbox('admin_domain_reallydelete', 'remove_subbutmain_domains', $filename, array( + 'id' => $id, + 'page' => $page, + 'action' => $action + ), $idna_convert->decode($result['domain']), $showcheck); } } - - } elseif($action == 'add') { - - if ($userinfo['domains_used'] < $userinfo['domains'] - || $userinfo['domains'] == '-1' - ) { - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { - - if ($_POST['domain'] == Settings::Get('system.hostname')) { - standard_error('admin_domain_emailsystemhostname'); - } - - $domain = $idna_convert->encode(preg_replace(array('/\:(\d)+$/', '/^https?\:\/\//'), '', validate($_POST['domain'], 'domain'))); - $subcanemaildomain = intval($_POST['subcanemaildomain']); - - $isemaildomain = 0; - if (isset($_POST['isemaildomain'])) { - $isemaildomain = intval($_POST['isemaildomain']); - } - - $email_only = 0; - if (isset($_POST['email_only'])) { - $email_only = intval($_POST['email_only']); - } - - $serveraliasoption = 0; - if (isset($_POST['selectserveralias'])) { - $serveraliasoption = intval($_POST['selectserveralias']); - } - - $speciallogfile = 0; - if (isset($_POST['speciallogfile'])) { - $speciallogfile = intval($_POST['speciallogfile']); - } - - $aliasdomain = intval($_POST['alias']); - $issubof = intval($_POST['issubof']); - $customerid = intval($_POST['customerid']); - $customer_stmt = Database::prepare(" - SELECT * FROM `" . TABLE_PANEL_CUSTOMERS . "` - WHERE `customerid` = :customerid " . - ($userinfo['customers_see_all'] ? '' : " AND `adminid` = :adminid") - ); - $params = array('customerid' => $customerid); - if ($userinfo['customers_see_all'] == '0') { - $params['adminid'] = $userinfo['adminid']; - } - $customer = Database::pexecute_first($customer_stmt, $params); - - if (empty($customer) - || $customer['customerid'] != $customerid - ) { - standard_error('customerdoesntexist'); - } - - if ($userinfo['customers_see_all'] == '1') { - - $adminid = intval($_POST['adminid']); - $admin_stmt = Database::prepare(" - SELECT * FROM `" . TABLE_PANEL_ADMINS . "` - WHERE `adminid` = :adminid AND (`domains_used` < `domains` OR `domains` = '-1')" - ); - $admin = Database::pexecute_first($admin_stmt, array('adminid' => $adminid)); - - if (empty($admin) - || $admin['adminid'] != $adminid - ) { - standard_error('admindoesntexist'); - } - - } else { - $adminid = $userinfo['adminid']; - $admin = $userinfo; - } - - // set default path if admin/reseller has "change_serversettings == false" but we still - // need to respect the documentroot_use_default_value - setting - $path_suffix = ''; - if (Settings::Get('system.documentroot_use_default_value') == 1) { - $path_suffix = '/'.$domain; - } - $documentroot = makeCorrectDir($customer['documentroot'] . $path_suffix); - - $registration_date = trim($_POST['registration_date']); - $registration_date = validate($registration_date, 'registration_date', '/^(19|20)\d\d[-](0[1-9]|1[012])[-](0[1-9]|[12][0-9]|3[01])$/', '', array('0000-00-00', '0', '')); - - $termination_date = trim($_POST['termination_date']); - $termination_date = validate($termination_date, 'termination_date', '/^(19|20)\d\d[-](0[1-9]|1[012])[-](0[1-9]|[12][0-9]|3[01])$/', '', array('0000-00-00', '0', '')); - - if ($userinfo['change_serversettings'] == '1') { - - $caneditdomain = isset($_POST['caneditdomain']) ? intval($_POST['caneditdomain']) : 0; - - $isbinddomain = '0'; - $zonefile = ''; - if (Settings::Get('system.bind_enable') == '1') { - if (isset($_POST['isbinddomain'])) { - $isbinddomain = intval($_POST['isbinddomain']); - } - $zonefile = validate($_POST['zonefile'], 'zonefile'); - } - - if (isset($_POST['dkim'])) { - $dkim = intval($_POST['dkim']); - } else { - $dkim = '1'; - } - - $specialsettings = validate(str_replace("\r\n", "\n", $_POST['specialsettings']), 'specialsettings', '/^[^\0]*$/'); - validate($_POST['documentroot'], 'documentroot'); - - // If path is empty and 'Use domain name as default value for DocumentRoot path' is enabled in settings, - // set default path to subdomain or domain name - if (isset($_POST['documentroot']) - && $_POST['documentroot'] != '' - ) { - if (substr($_POST['documentroot'], 0, 1) != '/' - && !preg_match('/^https?\:\/\//', $_POST['documentroot']) - ) { - $documentroot.= '/' . $_POST['documentroot']; - } else { - $documentroot = $_POST['documentroot']; - } - } elseif (isset($_POST['documentroot']) - && ($_POST['documentroot'] == '') - && (Settings::Get('system.documentroot_use_default_value') == 1) - ) { - $documentroot = makeCorrectDir($customer['documentroot'] . '/' . $domain); - } - - } else { - $isbinddomain = '0'; - if (Settings::Get('system.bind_enable') == '1') { - $isbinddomain = '1'; - } - $caneditdomain = '1'; - $zonefile = ''; - $dkim = '1'; - $specialsettings = ''; - } - - if ($userinfo['caneditphpsettings'] == '1' - || $userinfo['change_serversettings'] == '1' - ) { - - $openbasedir = isset($_POST['openbasedir']) ? intval($_POST['openbasedir']) : 0; - - if ((int)Settings::Get('system.mod_fcgid') == 1 - || (int)Settings::Get('phpfpm.enabled') == 1 - ) { - $phpsettingid = (int)$_POST['phpsettingid']; - $phpsettingid_check_stmt = Database::prepare(" - SELECT * FROM `" . TABLE_PANEL_PHPCONFIGS . "` - WHERE `id` = :phpsettingid" - ); - $phpsettingid_check = Database::pexecute_first($phpsettingid_check_stmt, array('phpsettingid' => $phpsettingid)); - - if (!isset($phpsettingid_check['id']) - || $phpsettingid_check['id'] == '0' - || $phpsettingid_check['id'] != $phpsettingid - ) { - standard_error('phpsettingidwrong'); - } - - if ((int)Settings::Get('system.mod_fcgid') == 1) { - $mod_fcgid_starter = validate($_POST['mod_fcgid_starter'], 'mod_fcgid_starter', '/^[0-9]*$/', '', array('-1', '')); - $mod_fcgid_maxrequests = validate($_POST['mod_fcgid_maxrequests'], 'mod_fcgid_maxrequests', '/^[0-9]*$/', '', array('-1', '')); - } else { - $mod_fcgid_starter = '-1'; - $mod_fcgid_maxrequests = '-1'; - } - - } else { - - if ((int)Settings::Get('phpfpm.enabled') == 1) { - $phpsettingid = Settings::Get('phpfpm.defaultini'); - } else { - $phpsettingid = Settings::Get('system.mod_fcgid_defaultini'); - } - $mod_fcgid_starter = '-1'; - $mod_fcgid_maxrequests = '-1'; - } - - } else { - - $openbasedir = '1'; - if ((int)Settings::Get('phpfpm.enabled') == 1) { - $phpsettingid = Settings::Get('phpfpm.defaultini'); - } else { - $phpsettingid = Settings::Get('system.mod_fcgid_defaultini'); - } - $mod_fcgid_starter = '-1'; - $mod_fcgid_maxrequests = '-1'; - } - - if ($userinfo['ip'] != "-1") { - $admin_ip_stmt = Database::prepare(" - SELECT `id`, `ip`, `port` FROM `" . TABLE_PANEL_IPSANDPORTS . "` - WHERE `id` = :id ORDER BY `ip`, `port` ASC" - ); - $admin_ip = Database::pexecute_first($admin_ip_stmt, array('id' => $userinfo['ip'])); - $additional_ip_condition = " AND `ip` = :adminip "; - $aip_param = array('adminip' => $admin_ip['ip']); - } else { - $additional_ip_condition = ''; - $aip_param = array(); - } - - $ipandports = array(); - if (isset($_POST['ipandport']) && !is_array($_POST['ipandport'])) { - $_POST['ipandport'] = unserialize($_POST['ipandport']); - } - - if (isset($_POST['ipandport']) && is_array($_POST['ipandport'])) { - foreach($_POST['ipandport'] as $ipandport) { - $ipandport = intval($ipandport); - $ipandport_check_stmt = Database::prepare(" - SELECT `id`, `ip`, `port` FROM `" . TABLE_PANEL_IPSANDPORTS . "` - WHERE `id` = :id " . $additional_ip_condition - ); - $ip_params = null; - $ip_params = array_merge(array('id' => $ipandport), $aip_param); - $ipandport_check = Database::pexecute_first($ipandport_check_stmt, $ip_params); - - if (!isset($ipandport_check['id']) - || $ipandport_check['id'] == '0' - || $ipandport_check['id'] != $ipandport - ) { - standard_error('ipportdoesntexist'); - } else { - $ipandports[] = $ipandport; - } - } - } - - if (Settings::Get('system.use_ssl') == "1" - && isset($_POST['ssl_ipandport']) - ) { - $ssl_redirect = 0; - if (isset($_POST['ssl_redirect'])) { - $ssl_redirect = (int)$_POST['ssl_redirect']; - } - - $letsencrypt = 0; - if (isset($_POST['letsencrypt'])) { - $letsencrypt = (int)$_POST['letsencrypt']; - } - - $ssl_ipandports = array(); - if (isset($_POST['ssl_ipandport']) && !is_array($_POST['ssl_ipandport'])) { - $_POST['ssl_ipandport'] = unserialize($_POST['ssl_ipandport']); - } - - // Verify SSL-Ports - if (isset($_POST['ssl_ipandport']) && is_array($_POST['ssl_ipandport'])) { - foreach ($_POST['ssl_ipandport'] as $ssl_ipandport) { - if (trim($ssl_ipandport) == "") continue; - // fix if no ssl-ip/port is checked - if (trim($ssl_ipandport) < 1) continue; - $ssl_ipandport = intval($ssl_ipandport); - $ssl_ipandport_check_stmt = Database::prepare(" - SELECT `id`, `ip`, `port` FROM `" . TABLE_PANEL_IPSANDPORTS . "` - WHERE `id` = :id " . $additional_ip_condition - ); - $ip_params = null; - $ip_params = array_merge(array('id' => $ssl_ipandport), $aip_param); - $ssl_ipandport_check = Database::pexecute_first($ssl_ipandport_check_stmt, $ip_params); - - if (!isset($ssl_ipandport_check['id']) - || $ssl_ipandport_check['id'] == '0' - || $ssl_ipandport_check['id'] != $ssl_ipandport - ) { - standard_error('ipportdoesntexist'); - } else { - $ssl_ipandports[] = $ssl_ipandport; - } - } - } else { - $ssl_redirect = 0; - $letsencrypt = 0; - // we need this for the serialize - // if ssl is disabled or no ssl-ip/port exists - $ssl_ipandports[] = -1; - } - } else { - $ssl_redirect = 0; - $letsencrypt = 0; - // we need this for the serialize - // if ssl is disabled or no ssl-ip/port exists - $ssl_ipandports[] = -1; - } - - // We can't enable let's encrypt for wildcard - domains - if ($serveraliasoption == '0' && $letsencrypt == '1') { - standard_error('nowildcardwithletsencrypt'); - } - - // Temporarily deactivate ssl_redirect until Let's Encrypt certificate was generated - if ($ssl_redirect > 0 && $letsencrypt == 1) { - $ssl_redirect = 2; - } - - if (!preg_match('/^https?\:\/\//', $documentroot)) { - if (strstr($documentroot, ":") !== false) { - standard_error('pathmaynotcontaincolon'); - } else { - $documentroot = makeCorrectDir($documentroot); - } - } - - $domain_check_stmt = Database::prepare(" - SELECT `id`, `domain` FROM `" . TABLE_PANEL_DOMAINS . "` - WHERE `domain` = :domain" - ); - $domain_check = Database::pexecute_first($domain_check_stmt, array('domain' => strtolower($domain))); - - $aliasdomain_check = array( - 'id' => 0 - ); - - if ($aliasdomain != 0) { - // Overwrite given ipandports with these of the "main" domain - $ipandports = array(); - $ssl_ipandports = array(); - $origipresult_stmt = Database::prepare(" - SELECT `id_ipandports` FROM `" . TABLE_DOMAINTOIP ."` - WHERE `id_domain` = :id" - ); - Database::pexecute($origipresult_stmt, array('id' => $aliasdomain)); - $ipdata_stmt = Database::prepare("SELECT * FROM `".TABLE_PANEL_IPSANDPORTS."` WHERE `id` = :ipid"); - while ($origip = $origipresult_stmt->fetch(PDO::FETCH_ASSOC)) { - $_origip_tmp = Database::pexecute_first($ipdata_stmt, array('ipid' => $origip['id_ipandports'])); - if ($_origip_tmp['ssl'] == 0) { - $ipandports[] = $origip['id_ipandports']; - } else { - $ssl_ipandports[] = $origip['id_ipandports']; - } - } - - if (count($ssl_ipandports) == 0) { - // we need this for the serialize - // if ssl is disabled or no ssl-ip/port exists - $ssl_ipandports[] = -1; - } - - $aliasdomain_check_stmt = Database::prepare(" - SELECT `d`.`id` FROM `" . TABLE_PANEL_DOMAINS . "` `d`, `" . TABLE_PANEL_CUSTOMERS . "` `c` - WHERE `d`.`customerid` = :customerid - AND `d`.`aliasdomain` IS NULL AND `d`.`id` <> `c`.`standardsubdomain` - AND `c`.`customerid` = :customerid - AND `d`.`id` = :aliasdomainid" - ); - $alias_params = array('customerid' => $customerid, 'aliasdomainid' => $aliasdomain); - $aliasdomain_check = Database::pexecute_first($aliasdomain_check_stmt, $alias_params); - } - - if (count($ipandports) == 0) { - standard_error('noipportgiven'); - } - - if ($openbasedir != '1') { - $openbasedir = '0'; - } - - if ($speciallogfile != '1') { - $speciallogfile = '0'; - } - - if ($isbinddomain != '1') { - $isbinddomain = '0'; - } - - if ($isemaildomain != '1') { - $isemaildomain = '0'; - } - - if ($email_only == '1') { - $isemaildomain = '1'; - } else { - $email_only = '0'; - } - - if ($subcanemaildomain != '1' - && $subcanemaildomain != '2' - && $subcanemaildomain != '3' - ) { - $subcanemaildomain = '0'; - } - - if ($dkim != '1') { - $dkim = '0'; - } - - if ($serveraliasoption != '1' && $serveraliasoption != '2') { - $serveraliasoption = '0'; - } - - if ($caneditdomain != '1') { - $caneditdomain = '0'; - } - - if ($issubof <= '0') { - $issubof = '0'; - } - - if ($aliasdomain != 0 && $letsencrypt != 0) - { - standard_error('letsencryptdoesnotworkwithaliasdomains'); - } - - if ($domain == '') { - standard_error(array('stringisempty', 'mydomain')); - } - // Check whether domain validation is enabled and if, validate the domain - elseif (Settings::Get('system.validate_domain') && !validateDomain($domain)) { - standard_error(array('stringiswrong', 'mydomain')); - } elseif($documentroot == '') { - standard_error(array('stringisempty', 'mydocumentroot')); - } elseif($customerid == 0) { - standard_error('adduserfirst'); - } elseif(strtolower($domain_check['domain']) == strtolower($domain)) { - standard_error('domainalreadyexists', $idna_convert->decode($domain)); - } elseif($aliasdomain_check['id'] != $aliasdomain) { - standard_error('domainisaliasorothercustomer'); - } else { - $params = array( - 'page' => $page, - 'action' => $action, - 'domain' => $domain, - 'customerid' => $customerid, - 'adminid' => $adminid, - 'documentroot' => $documentroot, - 'alias' => $aliasdomain, - 'isbinddomain' => $isbinddomain, - 'isemaildomain' => $isemaildomain, - 'email_only' => $email_only, - 'subcanemaildomain' => $subcanemaildomain, - 'caneditdomain' => $caneditdomain, - 'zonefile' => $zonefile, - 'dkim' => $dkim, - 'speciallogfile' => $speciallogfile, - 'selectserveralias' => $serveraliasoption, - 'ipandport' => serialize($ipandports), - 'ssl_redirect' => $ssl_redirect, - 'ssl_ipandport' => serialize($ssl_ipandports), - 'openbasedir' => $openbasedir, - 'phpsettingid' => $phpsettingid, - 'mod_fcgid_starter' => $mod_fcgid_starter, - 'mod_fcgid_maxrequests' => $mod_fcgid_maxrequests, - 'specialsettings' => $specialsettings, - 'registration_date' => $registration_date, - 'termination_date' => $termination_date, - 'issubof' => $issubof, - 'letsencrypt' => $letsencrypt - ); - - $security_questions = array( - 'reallydisablesecuritysetting' => ($openbasedir == '0' && $userinfo['change_serversettings'] == '1'), - 'reallydocrootoutofcustomerroot' => (substr($documentroot, 0, strlen($customer['documentroot'])) != $customer['documentroot'] && !preg_match('/^https?\:\/\//', $documentroot)) - ); - $question_nr = 1; - foreach ($security_questions as $question_name => $question_launch) { - if ($question_launch !== false) { - $params[$question_name] = $question_name; - - if (!isset($_POST[$question_name]) - || $_POST[$question_name] != $question_name - ) { - ask_yesno('admin_domain_' . $question_name, $filename, $params, $question_nr); - } - } - $question_nr++; - } - - $wwwserveralias = ($serveraliasoption == '1') ? '1' : '0'; - $iswildcarddomain = ($serveraliasoption == '0') ? '1' : '0'; - - $ins_data = array( - 'domain' => $domain, - 'customerid' => $customerid, - 'adminid' => $adminid, - 'documentroot' => $documentroot, - 'aliasdomain' => ($aliasdomain != 0 ? $aliasdomain : null), - 'zonefile' => $zonefile, - 'dkim' => $dkim, - 'wwwserveralias' => $wwwserveralias, - 'iswildcarddomain' => $iswildcarddomain, - 'isbinddomain' => $isbinddomain, - 'isemaildomain' => $isemaildomain, - 'email_only' => $email_only, - 'subcanemaildomain' => $subcanemaildomain, - 'caneditdomain' => $caneditdomain, - 'openbasedir' => $openbasedir, - 'speciallogfile' => $speciallogfile, - 'specialsettings' => $specialsettings, - 'ssl_redirect' => $ssl_redirect, - 'add_date' => time(), - 'registration_date' => $registration_date, - 'termination_date' => $termination_date, - 'phpsettingid' => $phpsettingid, - 'mod_fcgid_starter' => $mod_fcgid_starter, - 'mod_fcgid_maxrequests' => $mod_fcgid_maxrequests, - 'ismainbutsubto' => $issubof, - 'letsencrypt' => $letsencrypt - ); - - $ins_stmt = Database::prepare(" - INSERT INTO `" . TABLE_PANEL_DOMAINS . "` SET - `domain` = :domain, - `customerid` = :customerid, - `adminid` = :adminid, - `documentroot` = :documentroot, - `aliasdomain` = :aliasdomain, - `zonefile` = :zonefile, - `dkim` = :dkim, - `dkim_id` = '0', - `dkim_privkey` = '', - `dkim_pubkey` = '', - `wwwserveralias` = :wwwserveralias, - `iswildcarddomain` = :iswildcarddomain, - `isbinddomain` = :isbinddomain, - `isemaildomain` = :isemaildomain, - `email_only` = :email_only, - `subcanemaildomain` = :subcanemaildomain, - `caneditdomain` = :caneditdomain, - `openbasedir` = :openbasedir, - `speciallogfile` = :speciallogfile, - `specialsettings` = :specialsettings, - `ssl_redirect` = :ssl_redirect, - `add_date` = :add_date, - `registration_date` = :registration_date, - `termination_date` = :termination_date, - `phpsettingid` = :phpsettingid, - `mod_fcgid_starter` = :mod_fcgid_starter, - `mod_fcgid_maxrequests` = :mod_fcgid_maxrequests, - `ismainbutsubto` = :ismainbutsubto, - `letsencrypt` = :letsencrypt - "); - Database::pexecute($ins_stmt, $ins_data); - $domainid = Database::lastInsertId(); - - $upd_stmt = Database::prepare(" - UPDATE `" . TABLE_PANEL_ADMINS . "` SET `domains_used` = `domains_used` + 1 - WHERE `adminid` = :adminid" - ); - Database::pexecute($upd_stmt, array('adminid' => $adminid)); - - $ins_stmt = Database::prepare(" - INSERT INTO `" . TABLE_DOMAINTOIP . "` SET - `id_domain` = :domainid, - `id_ipandports` = :ipandportsid - "); - - foreach ($ipandports as $ipportid) { - $ins_data = array( - 'domainid' => $domainid, - 'ipandportsid' => $ipportid - ); - Database::pexecute($ins_stmt, $ins_data); - } - - foreach ($ssl_ipandports as $ssl_ipportid) { - if ($ssl_ipportid > 0) { - $ins_data = array( - 'domainid' => $domainid, - 'ipandportsid' => $ssl_ipportid - ); - Database::pexecute($ins_stmt, $ins_data); - } - } - $log->logAction(ADM_ACTION, LOG_INFO, "added domain '" . $domain . "'"); - inserttask('1'); - - // Using nameserver, insert a task which rebuilds the server config - inserttask('4'); - - redirectTo($filename, array('page' => $page, 's' => $s)); - } - - } else { - - $customers = makeoption($lng['panel']['please_choose'], 0, 0, true); - $result_customers_stmt = Database::prepare(" + } elseif ($action == 'add') { + + if (isset($_POST['send']) && $_POST['send'] == 'send') { + try { + Domains::getLocal($userinfo, $_POST)->add(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); + } 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 COALESCE(NULLIF(`name`,''), `company`) ASC" - ); - $params = array(); - if ($userinfo['customers_see_all'] == '0') { - $params['adminid'] = $userinfo['adminid']; - } - Database::pexecute($result_customers_stmt, $params); + FROM `" . TABLE_PANEL_CUSTOMERS . "` " . ($userinfo['customers_see_all'] ? '' : " WHERE `adminid` = '" . (int) $userinfo['adminid'] . "' ") . " ORDER BY COALESCE(NULLIF(`name`,''), `company`) 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.= makeoption(getCorrectFullUserDetails($row_customer) . ' (' . $row_customer['loginname'] . ')', $row_customer['customerid']); - } + 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']); + } - $admins = ''; - if ($userinfo['customers_see_all'] == '1') { + $admins = ''; + if ($userinfo['customers_see_all'] == '1') { - $result_admins_stmt = Database::query(" + $result_admins_stmt = Database::query(" SELECT `adminid`, `loginname`, `name` FROM `" . TABLE_PANEL_ADMINS . "` - WHERE `domains_used` < `domains` OR `domains` = '-1' ORDER BY `name` ASC" - ); + WHERE `domains_used` < `domains` OR `domains` = '-1' ORDER BY `name` ASC"); - while ($row_admin = $result_admins_stmt->fetch(PDO::FETCH_ASSOC)) { - $admins.= makeoption(getCorrectFullUserDetails($row_admin) . ' (' . $row_admin['loginname'] . ')', $row_admin['adminid'], $userinfo['adminid']); - } + while ($row_admin = $result_admins_stmt->fetch(PDO::FETCH_ASSOC)) { + $admins .= \Froxlor\UI\HTML::makeoption(\Froxlor\User::getCorrectFullUserDetails($row_admin) . ' (' . $row_admin['loginname'] . ')', $row_admin['adminid'], $userinfo['adminid']); } + } - if ($userinfo['ip'] == "-1") { - $result_ipsandports_stmt = Database::query(" + if ($userinfo['ip'] == "-1") { + $result_ipsandports_stmt = Database::query(" SELECT `id`, `ip`, `port` FROM `" . TABLE_PANEL_IPSANDPORTS . "` WHERE `ssl`='0' ORDER BY `ip`, `port` ASC "); - $result_ssl_ipsandports_stmt = Database::query(" + $result_ssl_ipsandports_stmt = Database::query(" SELECT `id`, `ip`, `port` FROM `" . TABLE_PANEL_IPSANDPORTS . "` WHERE `ssl`='1' ORDER BY `ip`, `port` ASC "); - } else { - $admin_ip_stmt = Database::prepare(" + } else { + $admin_ip_stmt = Database::prepare(" SELECT `id`, `ip`, `port` FROM `" . TABLE_PANEL_IPSANDPORTS . "` WHERE `id` = :ipid ORDER BY `ip`, `port` ASC "); - $admin_ip = Database::pexecute_first($admin_ip_stmt, array('ipid' => $userinfo['ip'])); + $admin_ip = Database::pexecute_first($admin_ip_stmt, array( + 'ipid' => $userinfo['ip'] + )); - $result_ipsandports_stmt = Database::prepare(" + $result_ipsandports_stmt = Database::prepare(" SELECT `id`, `ip`, `port` FROM `" . TABLE_PANEL_IPSANDPORTS . "` WHERE `ssl`='0' AND `ip` = :ipid ORDER BY `ip`, `port` ASC "); - Database::pexecute($result_ipsandports_stmt, array('ipid' => $admin_ip['ip'])); + Database::pexecute($result_ipsandports_stmt, array( + 'ipid' => $admin_ip['ip'] + )); - $result_ssl_ipsandports_stmt = Database::prepare(" + $result_ssl_ipsandports_stmt = Database::prepare(" SELECT `id`, `ip`, `port` FROM `" . TABLE_PANEL_IPSANDPORTS . "` WHERE `ssl`='1' AND `ip` = :ipid ORDER BY `ip`, `port` ASC "); - Database::pexecute($result_ssl_ipsandports_stmt, array('ipid' => $admin_ip['ip'])); + Database::pexecute($result_ssl_ipsandports_stmt, array( + 'ipid' => $admin_ip['ip'] + )); + } + + // Build array holding all IPs and Ports available to this admin + $ipsandports = array(); + while ($row_ipandport = $result_ipsandports_stmt->fetch(PDO::FETCH_ASSOC)) { + + if (filter_var($row_ipandport['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { + $row_ipandport['ip'] = '[' . $row_ipandport['ip'] . ']'; } - // Build array holding all IPs and Ports available to this admin - $ipsandports = array(); - while ($row_ipandport = $result_ipsandports_stmt->fetch(PDO::FETCH_ASSOC)) { + $ipsandports[] = array( + 'label' => $row_ipandport['ip'] . ':' . $row_ipandport['port'] . '
', + 'value' => $row_ipandport['id'] + ); + } - if (filter_var($row_ipandport['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { - $row_ipandport['ip'] = '[' . $row_ipandport['ip'] . ']'; - } + $ssl_ipsandports = array(); + while ($row_ssl_ipandport = $result_ssl_ipsandports_stmt->fetch(PDO::FETCH_ASSOC)) { - $ipsandports[] = array('label' => $row_ipandport['ip'] . ':' . $row_ipandport['port'] . '
', 'value' => $row_ipandport['id']); + if (filter_var($row_ssl_ipandport['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { + $row_ssl_ipandport['ip'] = '[' . $row_ssl_ipandport['ip'] . ']'; } - $ssl_ipsandports = array(); - while ($row_ssl_ipandport = $result_ssl_ipsandports_stmt->fetch(PDO::FETCH_ASSOC)) { + $ssl_ipsandports[] = array( + 'label' => $row_ssl_ipandport['ip'] . ':' . $row_ssl_ipandport['port'] . '
', + 'value' => $row_ssl_ipandport['id'] + ); + } - if (filter_var($row_ssl_ipandport['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { - $row_ssl_ipandport['ip'] = '[' . $row_ssl_ipandport['ip'] . ']'; - } - - $ssl_ipsandports[] = array('label' => $row_ssl_ipandport['ip'] . ':' . $row_ssl_ipandport['port'] . '
', 'value' => $row_ssl_ipandport['id']); - } - - $standardsubdomains = array(); - $result_standardsubdomains_stmt = Database::query(" + $standardsubdomains = array(); + $result_standardsubdomains_stmt = Database::query(" SELECT `id` FROM `" . TABLE_PANEL_DOMAINS . "` `d`, `" . TABLE_PANEL_CUSTOMERS . "` `c` WHERE `d`.`id` = `c`.`standardsubdomain` "); - while ($row_standardsubdomain = $result_standardsubdomains_stmt->fetch(PDO::FETCH_ASSOC)) { - $standardsubdomains[] = $row_standardsubdomain['id']; - } - - if (count($standardsubdomains) > 0) { - $standardsubdomains = " AND `d`.`id` NOT IN (" . join(',', $standardsubdomains) . ") "; - } else { - $standardsubdomains = ''; - } - - $domains = makeoption($lng['domains']['noaliasdomain'], 0, NULL, true); - $result_domains_stmt = Database::prepare(" - SELECT `d`.`id`, `d`.`domain`, `c`.`loginname` FROM `" . TABLE_PANEL_DOMAINS . "` `d`, `" . TABLE_PANEL_CUSTOMERS . "` `c` - WHERE `d`.`aliasdomain` IS NULL AND `d`.`parentdomainid` = 0" . $standardsubdomains . - ($userinfo['customers_see_all'] ? '' : " AND `d`.`adminid` = :adminid") . " - AND `d`.`customerid`=`c`.`customerid` ORDER BY `loginname`, `domain` ASC - "); - $params = array(); - if ($userinfo['customers_see_all'] == '0') { - $params['adminid'] = $userinfo['adminid']; - } - Database::pexecute($result_domains_stmt, $params); - - while ($row_domain = $result_domains_stmt->fetch(PDO::FETCH_ASSOC)) { - $domains.= makeoption($idna_convert->decode($row_domain['domain']) . ' (' . $row_domain['loginname'] . ')', $row_domain['id']); - } - - $subtodomains = makeoption($lng['domains']['nosubtomaindomain'], 0, NULL, true); - $result_domains_stmt = Database::prepare(" - SELECT `d`.`id`, `d`.`domain`, `c`.`loginname` FROM `" . TABLE_PANEL_DOMAINS . "` `d`, `" . TABLE_PANEL_CUSTOMERS . "` `c` - WHERE `d`.`aliasdomain` IS NULL AND `d`.`parentdomainid` = 0 AND `d`.`ismainbutsubto` = 0 " . $standardsubdomains . - ($userinfo['customers_see_all'] ? '' : " AND `d`.`adminid` = :adminid") . " - AND `d`.`customerid`=`c`.`customerid` ORDER BY `loginname`, `domain` ASC - "); - // params from above still valid - Database::pexecute($result_domains_stmt, $params); - - while ($row_domain = $result_domains_stmt->fetch(PDO::FETCH_ASSOC)) { - $subtodomains.= makeoption($idna_convert->decode($row_domain['domain']) . ' (' . $row_domain['loginname'] . ')', $row_domain['id']); - } - - $phpconfigs = ''; - $configs = Database::query("SELECT * FROM `" . TABLE_PANEL_PHPCONFIGS . "`"); - - while ($row = $configs->fetch(PDO::FETCH_ASSOC)) { - if ((int)Settings::Get('phpfpm.enabled') == 1) { - $phpconfigs.= makeoption($row['description'], $row['id'], Settings::Get('phpfpm.defaultini'), true, true); - } else { - $phpconfigs.= makeoption($row['description'], $row['id'], Settings::Get('system.mod_fcgid_defaultini'), true, true); - } - } - - // create serveralias options - $serveraliasoptions = ""; - $serveraliasoptions .= makeoption($lng['domains']['serveraliasoption_wildcard'], '0', '0', true, true); - $serveraliasoptions .= makeoption($lng['domains']['serveraliasoption_www'], '1', '0', true, true); - $serveraliasoptions .= makeoption($lng['domains']['serveraliasoption_none'], '2', '0', true, true); - - $subcanemaildomain = makeoption($lng['admin']['subcanemaildomain']['never'], '0', '0', true, true); - $subcanemaildomain.= makeoption($lng['admin']['subcanemaildomain']['choosableno'], '1', '0', true, true); - $subcanemaildomain.= makeoption($lng['admin']['subcanemaildomain']['choosableyes'], '2', '0', true, true); - $subcanemaildomain.= makeoption($lng['admin']['subcanemaildomain']['always'], '3', '0', true, true); - - $add_date = date('Y-m-d'); - - $domain_add_data = include_once dirname(__FILE__).'/lib/formfields/admin/domains/formfield.domains_add.php'; - $domain_add_form = htmlform::genHTMLForm($domain_add_data); - - $title = $domain_add_data['domain_add']['title']; - $image = $domain_add_data['domain_add']['image']; - - eval("echo \"" . getTemplate("domains/domains_add") . "\";"); + while ($row_standardsubdomain = $result_standardsubdomains_stmt->fetch(PDO::FETCH_ASSOC)) { + $standardsubdomains[] = $row_standardsubdomain['id']; } - } - } elseif($action == 'edit' - && $id != 0 - ) { + if (count($standardsubdomains) > 0) { + $standardsubdomains = " AND `d`.`id` NOT IN (" . join(',', $standardsubdomains) . ") "; + } else { + $standardsubdomains = ''; + } - $result_stmt = Database::prepare(" - SELECT `d`.*, `c`.`customerid` FROM `" . TABLE_PANEL_DOMAINS . "` `d` LEFT JOIN `" . TABLE_PANEL_CUSTOMERS . "` `c` USING(`customerid`) - WHERE `d`.`parentdomainid` = '0' AND `d`.`id` = :id" . - ($userinfo['customers_see_all'] ? '' : " AND `d`.`adminid` = :adminid") - ); - $params = array('id' => $id); - if ($userinfo['customers_see_all'] == '0') { - $params['adminid'] = $userinfo['adminid']; + $domains = \Froxlor\UI\HTML::makeoption($lng['domains']['noaliasdomain'], 0, NULL, true); + $result_domains_stmt = Database::prepare(" + SELECT `d`.`id`, `d`.`domain`, `c`.`loginname` FROM `" . TABLE_PANEL_DOMAINS . "` `d`, `" . TABLE_PANEL_CUSTOMERS . "` `c` + WHERE `d`.`aliasdomain` IS NULL AND `d`.`parentdomainid` = 0" . $standardsubdomains . ($userinfo['customers_see_all'] ? '' : " AND `d`.`adminid` = :adminid") . " + AND `d`.`customerid`=`c`.`customerid` ORDER BY `loginname`, `domain` ASC + "); + $params = array(); + if ($userinfo['customers_see_all'] == '0') { + $params['adminid'] = $userinfo['adminid']; + } + Database::pexecute($result_domains_stmt, $params); + + while ($row_domain = $result_domains_stmt->fetch(PDO::FETCH_ASSOC)) { + $domains .= \Froxlor\UI\HTML::makeoption($idna_convert->decode($row_domain['domain']) . ' (' . $row_domain['loginname'] . ')', $row_domain['id']); + } + + $subtodomains = \Froxlor\UI\HTML::makeoption($lng['domains']['nosubtomaindomain'], 0, NULL, true); + $result_domains_stmt = Database::prepare(" + SELECT `d`.`id`, `d`.`domain`, `c`.`loginname` FROM `" . TABLE_PANEL_DOMAINS . "` `d`, `" . TABLE_PANEL_CUSTOMERS . "` `c` + WHERE `d`.`aliasdomain` IS NULL AND `d`.`parentdomainid` = 0 AND `d`.`ismainbutsubto` = 0 " . $standardsubdomains . ($userinfo['customers_see_all'] ? '' : " AND `d`.`adminid` = :adminid") . " + AND `d`.`customerid`=`c`.`customerid` ORDER BY `loginname`, `domain` ASC + "); + // params from above still valid + Database::pexecute($result_domains_stmt, $params); + + while ($row_domain = $result_domains_stmt->fetch(PDO::FETCH_ASSOC)) { + $subtodomains .= \Froxlor\UI\HTML::makeoption($idna_convert->decode($row_domain['domain']) . ' (' . $row_domain['loginname'] . ')', $row_domain['id']); + } + + $phpconfigs = ''; + $configs = Database::query(" + SELECT c.*, fc.description as interpreter + FROM `" . TABLE_PANEL_PHPCONFIGS . "` c + LEFT JOIN `" . TABLE_PANEL_FPMDAEMONS . "` fc ON fc.id = c.fpmsettingid + "); + + while ($row = $configs->fetch(PDO::FETCH_ASSOC)) { + if ((int) Settings::Get('phpfpm.enabled') == 1) { + $phpconfigs .= \Froxlor\UI\HTML::makeoption($row['description'] . " [" . $row['interpreter'] . "]", $row['id'], Settings::Get('phpfpm.defaultini'), true, true); + } else { + $phpconfigs .= \Froxlor\UI\HTML::makeoption($row['description'], $row['id'], Settings::Get('system.mod_fcgid_defaultini'), true, true); + } + } + + // 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); + + $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); + $subcanemaildomain .= \Froxlor\UI\HTML::makeoption($lng['admin']['subcanemaildomain']['choosableyes'], '2', '0', true, true); + $subcanemaildomain .= \Froxlor\UI\HTML::makeoption($lng['admin']['subcanemaildomain']['always'], '3', '0', true, true); + + $add_date = date('Y-m-d'); + + $domain_add_data = include_once dirname(__FILE__) . '/lib/formfields/admin/domains/formfield.domains_add.php'; + $domain_add_form = \Froxlor\UI\HtmlForm::genHTMLForm($domain_add_data); + + $title = $domain_add_data['domain_add']['title']; + $image = $domain_add_data['domain_add']['image']; + + eval("echo \"" . \Froxlor\UI\Template::getTemplate("domains/domains_add") . "\";"); } - $result = Database::pexecute_first($result_stmt, $params); + } elseif ($action == 'edit' && $id != 0) { + + try { + $json_result = Domains::getLocal($userinfo, array( + 'id' => $id + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; if ($result['domain'] != '') { @@ -1056,21 +326,28 @@ if ($page == 'domains' SELECT COUNT(`id`) AS count FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `parentdomainid` = :resultid "); - $subdomains = Database::pexecute_first($subdomains_stmt, array('resultid' => $result['id'])); + $subdomains = Database::pexecute_first($subdomains_stmt, array( + 'resultid' => $result['id'] + )); $subdomains = $subdomains['count']; $alias_check_stmt = Database::prepare(" SELECT COUNT(`id`) AS count FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `aliasdomain` = :resultid "); - $alias_check = Database::pexecute_first($alias_check_stmt, array('resultid' => $result['id'])); + $alias_check = Database::pexecute_first($alias_check_stmt, array( + 'resultid' => $result['id'] + )); $alias_check = $alias_check['count']; $domain_emails_result_stmt = Database::prepare(" SELECT `email`, `email_full`, `destination`, `popaccountid` AS `number_email_forwarders` FROM `" . TABLE_MAIL_VIRTUAL . "` WHERE `customerid` = :customerid AND `domainid` = :id "); - Database::pexecute($domain_emails_result_stmt, array('customerid' => $result['customerid'], 'id' => $result['id'])); + Database::pexecute($domain_emails_result_stmt, array( + 'customerid' => $result['customerid'], + 'id' => $result['id'] + )); $emails = Database::num_rows(); $email_forwarders = 0; @@ -1080,12 +357,12 @@ if ($page == 'domains' if ($domain_emails_row['destination'] != '') { - $domain_emails_row['destination'] = explode(' ', makeCorrectDestination($domain_emails_row['destination'])); - $email_forwarders+= count($domain_emails_row['destination']); + $domain_emails_row['destination'] = explode(' ', \Froxlor\FileDir::makeCorrectDestination($domain_emails_row['destination'])); + $email_forwarders += count($domain_emails_row['destination']); if (in_array($domain_emails_row['email_full'], $domain_emails_row['destination'])) { - $email_forwarders-= 1; - $email_accounts++; + $email_forwarders -= 1; + $email_accounts ++; } } } @@ -1093,730 +370,31 @@ if ($page == 'domains' $ipsresult_stmt = Database::prepare(" SELECT `id_ipandports` FROM `" . TABLE_DOMAINTOIP . "` WHERE `id_domain` = :id "); - Database::pexecute($ipsresult_stmt, array('id' => $result['id'])); + Database::pexecute($ipsresult_stmt, array( + 'id' => $result['id'] + )); $usedips = array(); while ($ipsresultrow = $ipsresult_stmt->fetch(PDO::FETCH_ASSOC)) { $usedips[] = $ipsresultrow['id_ipandports']; } - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { - - $customer_stmt = Database::prepare(" - SELECT * FROM " . TABLE_PANEL_CUSTOMERS . " WHERE `customerid` = :customerid - "); - $customer = Database::pexecute_first($customer_stmt, array('customerid' => $result['customerid'])); - - $customerid = -1; - if (isset($_POST['customerid'])) { - $customerid = intval($_POST['customerid']); - } - - if ($customerid > 0 - && $customerid != $result['customerid'] - && Settings::Get('panel.allow_domain_change_customer') == '1' - ) { - - $customer_stmt = Database::prepare(" - SELECT * FROM `" . TABLE_PANEL_CUSTOMERS . "` - WHERE `customerid` = :customerid - AND (`subdomains_used` + :subdomains <= `subdomains` OR `subdomains` = '-1' ) - AND (`emails_used` + :emails <= `emails` OR `emails` = '-1' ) - AND (`email_forwarders_used` + :forwarders <= `email_forwarders` OR `email_forwarders` = '-1' ) - AND (`email_accounts_used` + :accounts <= `email_accounts` OR `email_accounts` = '-1' ) " . - ($userinfo['customers_see_all'] ? '' : " AND `adminid` = :adminid") - ); - - $params = array( - 'customerid' => $customerid, - 'subdomains' => $subdomains, - 'emails' => $emails, - 'forwarders' => $email_forwarders, - 'accounts' => $email_accounts - ); - if ($userinfo['customers_see_all'] == '0') { - $params['adminid'] = $userinfo['adminid']; + if (isset($_POST['send']) && $_POST['send'] == 'send') { + try { + // remove ssl ip/ports if set is empty + if (!isset($_POST['ssl_ipandport']) || empty($_POST['ssl_ipandport'])) { + $_POST['remove_ssl_ipandport'] = true; } - - $customer = Database::pexecute_first($customer_stmt, $params); - if (empty($customer) - || $customer['customerid'] != $customerid - ) { - standard_error('customerdoesntexist'); - } - } else { - $customerid = $result['customerid']; + Domains::getLocal($userinfo, $_POST)->update(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } - - $customer_stmt = Database::prepare(" - SELECT * FROM " . TABLE_PANEL_ADMINS . " WHERE `adminid` = :adminid - "); - $admin = Database::pexecute_first($customer_stmt, array('adminid' => $result['adminid'])); - - if ($userinfo['customers_see_all'] == '1') { - - $adminid = -1; - if (isset($_POST['adminid'])) { - $adminid = intval($_POST['adminid']); - } - - if ($adminid > 0 - && $adminid != $result['adminid'] - && Settings::Get('panel.allow_domain_change_admin') == '1' - ) { - - $admin_stmt = Database::prepare(" - SELECT * FROM `" . TABLE_PANEL_ADMINS . "` - WHERE `adminid` = :adminid AND ( `domains_used` < `domains` OR `domains` = '-1' ) - "); - $admin = Database::pexecute_first($admin_stmt, array('adminid' => $adminid)); - - if (empty($admin) - || $admin['adminid'] != $adminid - ) { - standard_error('admindoesntexist'); - } - } else { - $adminid = $result['adminid']; - } - } else { - $adminid = $result['adminid']; - } - - $aliasdomain = intval($_POST['alias']); - $issubof = intval($_POST['issubof']); - $subcanemaildomain = intval($_POST['subcanemaildomain']); - $caneditdomain = isset($_POST['caneditdomain']) ? intval($_POST['caneditdomain']) : 0; - $registration_date = trim($_POST['registration_date']); - $registration_date = validate($registration_date, 'registration_date', '/^(19|20)\d\d[-](0[1-9]|1[012])[-](0[1-9]|[12][0-9]|3[01])$/', '', array('0000-00-00', '0', '')); - $termination_date = trim($_POST['termination_date']); - $termination_date = validate($termination_date, 'termination_date', '/^(19|20)\d\d[-](0[1-9]|1[012])[-](0[1-9]|[12][0-9]|3[01])$/', '', array('0000-00-00', '0', '')); - - $isemaildomain = 0; - if (isset($_POST['isemaildomain'])) { - $isemaildomain = intval($_POST['isemaildomain']); - } - - $email_only = 0; - if (isset($_POST['email_only'])) { - $email_only = intval($_POST['email_only']); - } - - $serveraliasoption = '2'; - if ($result['iswildcarddomain'] == '1') { - $serveraliasoption = '0'; - } elseif ($result['wwwserveralias'] == '1') { - $serveraliasoption = '1'; - } - if (isset($_POST['selectserveralias'])) { - $serveraliasoption = intval($_POST['selectserveralias']); - } - - $speciallogfile = 0; - if(isset($_POST['speciallogfile'])) - $speciallogfile = intval($_POST['speciallogfile']); - - - if ($userinfo['change_serversettings'] == '1') { - $isbinddomain = $result['isbinddomain']; - $zonefile = $result['zonefile']; - if (Settings::Get('system.bind_enable') == '1') { - if (isset($_POST['isbinddomain'])) { - $isbinddomain = (int)$_POST['isbinddomain']; - } else { - $isbinddomain = 0; - } - $zonefile = validate($_POST['zonefile'], 'zonefile'); - } - - if (Settings::Get('dkim.use_dkim') == '1') { - $dkim = isset($_POST['dkim']) ? 1 : 0; - } else { - $dkim = $result['dkim']; - } - - $specialsettings = validate(str_replace("\r\n", "\n", $_POST['specialsettings']), 'specialsettings', '/^[^\0]*$/'); - $ssfs = (isset($_POST['specialsettingsforsubdomains']) && intval($_POST['specialsettingsforsubdomains']) == 1) ? 1 : 0; - $documentroot = validate($_POST['documentroot'], 'documentroot'); - - if ($documentroot == '') { - // If path is empty and 'Use domain name as default value for DocumentRoot path' is enabled in settings, - // set default path to subdomain or domain name - if (Settings::Get('system.documentroot_use_default_value') == 1) { - $documentroot = makeCorrectDir($customer['documentroot'] . '/' . $result['domain']); - } else { - $documentroot = $customer['documentroot']; - } - } - - if (!preg_match('/^https?\:\/\//', $documentroot) - && strstr($documentroot, ":") !== false - ) { - standard_error('pathmaynotcontaincolon'); - } - - } else { - $isbinddomain = $result['isbinddomain']; - $zonefile = $result['zonefile']; - $dkim = $result['dkim']; - $specialsettings = $result['specialsettings']; - $ssfs = (empty($specialsettings) ? 0 : 1); - $documentroot = $result['documentroot']; - } - - $speciallogverified = (isset($_POST['speciallogverified']) ? (int)$_POST['speciallogverified'] : 0); - - if ($userinfo['caneditphpsettings'] == '1' - || $userinfo['change_serversettings'] == '1' - ) { - - $openbasedir = isset($_POST['openbasedir']) ? intval($_POST['openbasedir']) : 0; - - if ((int)Settings::Get('system.mod_fcgid') == 1 - || (int)Settings::Get('phpfpm.enabled') == 1 - ) { - $phpsettingid = (int)$_POST['phpsettingid']; - $phpsettingid_check_stmt = Database::prepare(" - SELECT * FROM `" . TABLE_PANEL_PHPCONFIGS . "` WHERE `id` = :phpid - "); - $phpsettingid_check = Database::pexecute_first($phpsettingid_check_stmt, array('phpid' => $phpsettingid)); - - if (!isset($phpsettingid_check['id']) - || $phpsettingid_check['id'] == '0' - || $phpsettingid_check['id'] != $phpsettingid - ) { - standard_error('phpsettingidwrong'); - } - - if ((int)Settings::Get('system.mod_fcgid') == 1) { - $mod_fcgid_starter = validate($_POST['mod_fcgid_starter'], 'mod_fcgid_starter', '/^[0-9]*$/', '', array('-1', '')); - $mod_fcgid_maxrequests = validate($_POST['mod_fcgid_maxrequests'], 'mod_fcgid_maxrequests', '/^[0-9]*$/', '', array('-1', '')); - } else { - $mod_fcgid_starter = $result['mod_fcgid_starter']; - $mod_fcgid_maxrequests = $result['mod_fcgid_maxrequests']; - } - - } else { - $phpsettingid = $result['phpsettingid']; - $mod_fcgid_starter = $result['mod_fcgid_starter']; - $mod_fcgid_maxrequests = $result['mod_fcgid_maxrequests']; - } - - } else { - $openbasedir = $result['openbasedir']; - $phpsettingid = $result['phpsettingid']; - $mod_fcgid_starter = $result['mod_fcgid_starter']; - $mod_fcgid_maxrequests = $result['mod_fcgid_maxrequests']; - } - - $ipandports = array(); - if (isset($_POST['ipandport']) && !is_array($_POST['ipandport'])) { - $_POST['ipandport'] = unserialize($_POST['ipandport']); - } - if (isset($_POST['ipandport']) && is_array($_POST['ipandport'])) { - - $ipandport_check_stmt = Database::prepare(" - SELECT `id`, `ip`, `port` FROM `" . TABLE_PANEL_IPSANDPORTS . "` WHERE `id` = :ipandport - "); - foreach ($_POST['ipandport'] as $ipandport) { - if (trim($ipandport) == "") continue; - $ipandport = intval($ipandport); - $ipandport_check = Database::pexecute_first($ipandport_check_stmt, array('ipandport' => $ipandport)); - if (!isset($ipandport_check['id']) - || $ipandport_check['id'] == '0' - || $ipandport_check['id'] != $ipandport - ) { - standard_error('ipportdoesntexist'); - } else { - $ipandports[] = $ipandport; - } - } - } - - if (Settings::Get('system.use_ssl') == '1' - && isset($_POST['ssl_ipandport']) - ) { - $ssl = 1; // if ssl is set and != 0, it can only be 1 - $ssl_redirect = 0; - if (isset($_POST['ssl_redirect'])) { - $ssl_redirect = (int)$_POST['ssl_redirect']; - } - - $letsencrypt = 0; - if (isset($_POST['letsencrypt'])) { - $letsencrypt = (int)$_POST['letsencrypt']; - } - - $ssl_ipandports = array(); - if (isset($_POST['ssl_ipandport']) && !is_array($_POST['ssl_ipandport'])) { - $_POST['ssl_ipandport'] = unserialize($_POST['ssl_ipandport']); - } - if (isset($_POST['ssl_ipandport']) && is_array($_POST['ssl_ipandport'])) { - - $ssl_ipandport_check_stmt = Database::prepare(" - SELECT `id`, `ip`, `port` FROM `" . TABLE_PANEL_IPSANDPORTS . "` WHERE `id` = :ipandport - "); - foreach ($_POST['ssl_ipandport'] as $ssl_ipandport) { - if (trim($ssl_ipandport) == "") continue; - // fix if ip/port got de-checked and it was the last one - if (trim($ssl_ipandport) < 1) continue; - $ssl_ipandport = intval($ssl_ipandport); - $ssl_ipandport_check = Database::pexecute_first($ssl_ipandport_check_stmt, array('ipandport' => $ssl_ipandport)); - if (!isset($ssl_ipandport_check['id']) - || $ssl_ipandport_check['id'] == '0' - || $ssl_ipandport_check['id'] != $ssl_ipandport - ) { - standard_error('ipportdoesntexist'); - } else { - $ssl_ipandports[] = $ssl_ipandport; - } - } - } else { - $ssl_redirect = 0; - $letsencrypt = 0; - // we need this for the serialize - // if ssl is disabled or no ssl-ip/port exists - $ssl_ipandports[] = -1; - } - } else { - $ssl_redirect = 0; - $letsencrypt = 0; - // we need this for the serialize - // if ssl is disabled or no ssl-ip/port exists - $ssl_ipandports[] = -1; - } - - // We can't enable let's encrypt for wildcard domains - if ($serveraliasoption == '0' && $letsencrypt == '1') { - standard_error('nowildcardwithletsencrypt'); - } - - // Temporarily deactivate ssl_redirect until Let's Encrypt certificate was generated - if ($ssl_redirect > 0 && $letsencrypt == 1 && $result['letsencrypt'] != $letsencrypt) { - $ssl_redirect = 2; - } - - if (!preg_match('/^https?\:\/\//', $documentroot)) { - $documentroot = makeCorrectDir($documentroot); - } - - if ($openbasedir != '1') { - $openbasedir = '0'; - } - - if ($isbinddomain != '1') { - $isbinddomain = '0'; - } - - if ($isemaildomain != '1') { - $isemaildomain = '0'; - } - - if ($email_only == '1') { - $isemaildomain = '1'; - } else { - $email_only = '0'; - } - - if ($subcanemaildomain != '1' - && $subcanemaildomain != '2' - && $subcanemaildomain != '3' - ) { - $subcanemaildomain = '0'; - } - - if ($dkim != '1') { - $dkim = '0'; - } - - if ($caneditdomain != '1') { - $caneditdomain = '0'; - } - - $aliasdomain_check = array( - 'id' => 0 - ); - - if ($aliasdomain != 0) { - // Overwrite given ipandports with these of the "main" domain - $ipandports = array(); - $ssl_ipandports = array(); - $origipresult_stmt = Database::prepare(" - SELECT `id_ipandports` FROM `" . TABLE_DOMAINTOIP ."` WHERE `id_domain` = :aliasdomain - "); - Database::pexecute($origipresult_stmt, array('aliasdomain' => $aliasdomain)); - $ipdata_stmt = Database::prepare("SELECT * FROM `".TABLE_PANEL_IPSANDPORTS."` WHERE `id` = :ipid"); - while ($origip = $origipresult_stmt->fetch(PDO::FETCH_ASSOC)) { - $_origip_tmp = Database::pexecute_first($ipdata_stmt, array('ipid' => $origip['id_ipandports'])); - if ($_origip_tmp['ssl'] == 0) { - $ipandports[] = $origip['id_ipandports']; - } else { - $ssl_ipandports[] = $origip['id_ipandports']; - } - } - - if (count($ssl_ipandports) == 0) { - // we need this for the serialize - // if ssl is disabled or no ssl-ip/port exists - $ssl_ipandports[] = -1; - } - - $aliasdomain_check_stmt = Database::prepare(" - SELECT `d`.`id` FROM `" . TABLE_PANEL_DOMAINS . "` `d`, `" . TABLE_PANEL_CUSTOMERS . "` `c` - WHERE `d`.`customerid` = :customerid - AND `d`.`aliasdomain` IS NULL AND `d`.`id` <> `c`.`standardsubdomain` - AND `c`.`customerid` = :customerid - AND `d`.`id` = :aliasdomain - "); - $aliasdomain_check = Database::pexecute_first($aliasdomain_check_stmt, array('customerid' => $customerid, 'aliasdomain' => $aliasdomain)); - } - - if (count($ipandports) == 0) { - standard_error('noipportgiven'); - } - - if ($aliasdomain_check['id'] != $aliasdomain) { - standard_error('domainisaliasorothercustomer'); - } - - if ($issubof <= '0') { - $issubof = '0'; - } - - if ($aliasdomain != 0 && $letsencrypt != 0) - { - standard_error('letsencryptdoesnotworkwithaliasdomains'); - } - - if ($serveraliasoption != '1' && $serveraliasoption != '2') { - $serveraliasoption = '0'; - } - - $params = array( - 'id' => $id, + \Froxlor\UI\Response::redirectTo($filename, array( 'page' => $page, - 'action' => $action, - 'customerid' => $customerid, - 'adminid' => $adminid, - 'documentroot' => $documentroot, - 'alias' => $aliasdomain, - 'isbinddomain' => $isbinddomain, - 'isemaildomain' => $isemaildomain, - 'email_only' => $email_only, - 'subcanemaildomain' => $subcanemaildomain, - 'caneditdomain' => $caneditdomain, - 'zonefile' => $zonefile, - 'dkim' => $dkim, - 'selectserveralias' => $serveraliasoption, - 'ssl_redirect' => $ssl_redirect, - 'openbasedir' => $openbasedir, - 'phpsettingid' => $phpsettingid, - 'mod_fcgid_starter' => $mod_fcgid_starter, - 'mod_fcgid_maxrequests' => $mod_fcgid_maxrequests, - 'specialsettings' => $specialsettings, - 'specialsettingsforsubdomains' => $ssfs, - 'registration_date' => $registration_date, - 'termination_date' => $termination_date, - 'issubof' => $issubof, - 'speciallogfile' => $speciallogfile, - 'speciallogverified' => $speciallogverified, - 'ipandport' => serialize($ipandports), - 'ssl_ipandport' => serialize($ssl_ipandports), - 'letsencrypt' => $letsencrypt - ); - - $security_questions = array( - 'reallydisablesecuritysetting' => ($openbasedir == '0' && $userinfo['change_serversettings'] == '1'), - 'reallydocrootoutofcustomerroot' => (substr($documentroot, 0, strlen($customer['documentroot'])) != $customer['documentroot'] && !preg_match('/^https?\:\/\//', $documentroot)) - ); - foreach ($security_questions as $question_name => $question_launch) { - if ($question_launch !== false) { - $params[$question_name] = $question_name; - if (!isset($_POST[$question_name]) - || $_POST[$question_name] != $question_name - ) { - ask_yesno('admin_domain_' . $question_name, $filename, $params); - } - } - } - - $wwwserveralias = ($serveraliasoption == '1') ? '1' : '0'; - $iswildcarddomain = ($serveraliasoption == '0') ? '1' : '0'; - - if ($documentroot != $result['documentroot'] - || $ssl_redirect != $result['ssl_redirect'] - || $wwwserveralias != $result['wwwserveralias'] - || $iswildcarddomain != $result['iswildcarddomain'] - || $openbasedir != $result['openbasedir'] - || $phpsettingid != $result['phpsettingid'] - || $mod_fcgid_starter != $result['mod_fcgid_starter'] - || $mod_fcgid_maxrequests != $result['mod_fcgid_maxrequests'] - || $specialsettings != $result['specialsettings'] - || $aliasdomain != $result['aliasdomain'] - || $issubof != $result['ismainbutsubto'] - || $email_only != $result['email_only'] - || ($speciallogfile != $result['speciallogfile'] && $speciallogverified == '1') - || $letsencrypt != $result['letsencrypt'] - ) { - inserttask('1'); - } - - if ($speciallogfile != $result['speciallogfile'] && $speciallogverified != '1') { - $speciallogfile = $result['speciallogfile']; - } - - if ($isbinddomain != $result['isbinddomain'] - || $zonefile != $result['zonefile'] - || $dkim != $result['dkim'] - ) { - inserttask('4'); - } - - if ($isemaildomain == '0' - && $result['isemaildomain'] == '1' - ) { - $del_stmt = Database::prepare(" - DELETE FROM `" . TABLE_MAIL_USERS . "` WHERE `domainid` = :id - "); - Database::pexecute($del_stmt, array('id' => $id)); - - $del_stmt = Database::prepare(" - DELETE FROM `" . TABLE_MAIL_VIRTUAL . "` WHERE `domainid` = :id - "); - Database::pexecute($del_stmt, array('id' => $id)); - $log->logAction(ADM_ACTION, LOG_NOTICE, "deleted domain #" . $id . " from mail-tables"); - } - - $updatechildren = ''; - - if ($subcanemaildomain == '0' - && $result['subcanemaildomain'] != '0' - ) { - $updatechildren = ", `isemaildomain` = '0' "; - - } elseif($subcanemaildomain == '3' - && $result['subcanemaildomain'] != '3' - ) { - $updatechildren = ", `isemaildomain` = '1' "; - } - - if ($customerid != $result['customerid'] - && Settings::Get('panel.allow_domain_change_customer') == '1' - ) { - $upd_data = array('customerid' => $customerid, 'domainid' => $result['id']); - $upd_stmt = Database::prepare(" - UPDATE `" . TABLE_MAIL_USERS . "` SET `customerid` = :customerid WHERE `domainid` = :domainid - "); - Database::pexecute($upd_stmt, $upd_data); - $upd_stmt = Database::prepare(" - UPDATE `" . TABLE_MAIL_VIRTUAL . "` SET `customerid` = :customerid WHERE `domainid` = :domainid - "); - Database::pexecute($upd_stmt, $upd_data); - $upd_data = array('subdomains' => $subdomains, 'emails' => $emails, 'forwarders' => $email_forwarders, 'accounts' => $email_accounts); - $upd_data['customerid'] = $customerid; - $upd_stmt = Database::prepare(" - UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET - `subdomains_used` = `subdomains_used` + :subdomains, - `emails_used` = `emails_used` + :emails, - `email_forwarders_used` = `email_forwarders_used` + :forwarders, - `email_accounts_used` = `email_accounts_used` + :accounts - WHERE `customerid` = :customerid - "); - Database::pexecute($upd_stmt, $upd_data); - - $upd_data['customerid'] = $result['customerid']; - $upd_stmt = Database::prepare(" - UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET - `subdomains_used` = `subdomains_used` - :subdomains, - `emails_used` = `emails_used` - :emails, - `email_forwarders_used` = `email_forwarders_used` - :forwarders, - `email_accounts_used` = `email_accounts_used` - :accounts - WHERE `customerid` = :customerid - "); - Database::pexecute($upd_stmt, $upd_data); - } - - if ($adminid != $result['adminid'] - && Settings::Get('panel.allow_domain_change_admin') == '1' - ) { - $upd_stmt = Database::prepare(" - UPDATE `" . TABLE_PANEL_ADMINS . "` SET `domains_used` = `domains_used` + 1 WHERE `adminid` = :adminid - "); - Database::pexecute($upd_stmt, array('adminid' => $adminid)); - - $upd_stmt = Database::prepare(" - UPDATE `" . TABLE_PANEL_ADMINS . "` SET `domains_used` = `domains_used` - 1 WHERE `adminid` = :adminid - "); - Database::pexecute($upd_stmt, array('adminid' => $result['adminid'])); - } - - $_update_data = array(); - - $ssfs = isset($_POST['specialsettingsforsubdomains']) ? 1 : 0; - if ($ssfs == 1) { - $_update_data['specialsettings'] = $specialsettings; - $upd_specialsettings = ", `specialsettings` = :specialsettings "; - } else { - $upd_specialsettings = ''; - unset($_update_data['specialsettings']); - $upd_stmt = Database::prepare(" - UPDATE `" . TABLE_PANEL_DOMAINS . "` SET `specialsettings`='' WHERE `parentdomainid` = :id - "); - Database::pexecute($upd_stmt, array('id' => $id)); - $log->logAction(ADM_ACTION, LOG_INFO, "removed specialsettings on all subdomains of domain #" . $id); - } - - $wwwserveralias = ($serveraliasoption == '1') ? '1' : '0'; - $iswildcarddomain = ($serveraliasoption == '0') ? '1' : '0'; - - $update_data = array(); - $update_data['customerid'] = $customerid; - $update_data['adminid'] = $adminid; - $update_data['documentroot'] = $documentroot; - $update_data['ssl_redirect'] = $ssl_redirect; - $update_data['aliasdomain'] = ($aliasdomain != 0 && $alias_check == 0) ? $aliasdomain : null; - $update_data['isbinddomain'] = $isbinddomain; - $update_data['isemaildomain'] = $isemaildomain; - $update_data['email_only'] = $email_only; - $update_data['subcanemaildomain'] = $subcanemaildomain; - $update_data['dkim'] = $dkim; - $update_data['caneditdomain'] = $caneditdomain; - $update_data['zonefile'] = $zonefile; - $update_data['wwwserveralias'] = $wwwserveralias; - $update_data['iswildcarddomain'] = $iswildcarddomain; - $update_data['openbasedir'] = $openbasedir; - $update_data['speciallogfile'] = $speciallogfile; - $update_data['phpsettingid'] = $phpsettingid; - $update_data['mod_fcgid_starter'] = $mod_fcgid_starter; - $update_data['mod_fcgid_maxrequests'] = $mod_fcgid_maxrequests; - $update_data['specialsettings'] = $specialsettings; - $update_data['registration_date'] = $registration_date; - $update_data['termination_date'] = $termination_date; - $update_data['ismainbutsubto'] = $issubof; - $update_data['letsencrypt'] = $letsencrypt; - $update_data['id'] = $id; - - $update_stmt = Database::prepare(" - UPDATE `" . TABLE_PANEL_DOMAINS . "` SET - `customerid` = :customerid, - `adminid` = :adminid, - `documentroot` = :documentroot, - `ssl_redirect` = :ssl_redirect, - `aliasdomain` = :aliasdomain, - `isbinddomain` = :isbinddomain, - `isemaildomain` = :isemaildomain, - `email_only` = :email_only, - `subcanemaildomain` = :subcanemaildomain, - `dkim` = :dkim, - `caneditdomain` = :caneditdomain, - `zonefile` = :zonefile, - `wwwserveralias` = :wwwserveralias, - `iswildcarddomain` = :iswildcarddomain, - `openbasedir` = :openbasedir, - `speciallogfile` = :speciallogfile, - `phpsettingid` = :phpsettingid, - `mod_fcgid_starter` = :mod_fcgid_starter, - `mod_fcgid_maxrequests` = :mod_fcgid_maxrequests, - `specialsettings` = :specialsettings, - `registration_date` = :registration_date, - `termination_date` = :termination_date, - `ismainbutsubto` = :ismainbutsubto, - `letsencrypt` = :letsencrypt - WHERE `id` = :id - "); - Database::pexecute($update_stmt, $update_data); - - $_update_data['customerid'] = $customerid; - $_update_data['adminid'] = $adminid; - $_update_data['openbasedir'] = $openbasedir; - $_update_data['phpsettingid'] = $phpsettingid; - $_update_data['mod_fcgid_starter'] = $mod_fcgid_starter; - $_update_data['mod_fcgid_maxrequests'] = $mod_fcgid_maxrequests; - $_update_data['parentdomainid'] = $id; - - // if we have no more ssl-ip's for this domain, - // all its subdomains must have "ssl-redirect = 0" - // and disable let's encrypt - $update_sslredirect = ''; - if (count($ssl_ipandports) == 1 && $ssl_ipandports[0] == -1) { - $update_sslredirect = ", `ssl_redirect` = '0', `letsencrypt` = '0' "; - } - - $_update_stmt = Database::prepare(" - UPDATE `" . TABLE_PANEL_DOMAINS . "` SET - `customerid` = :customerid, - `adminid` = :adminid, - `openbasedir` = :openbasedir, - `phpsettingid` = :phpsettingid, - `mod_fcgid_starter` = :mod_fcgid_starter, - `mod_fcgid_maxrequests` = :mod_fcgid_maxrequests - " . $upd_specialsettings . $updatechildren . $update_sslredirect . " - WHERE `parentdomainid` = :parentdomainid - "); - Database::pexecute($_update_stmt, $_update_data); - - // FIXME check how many we got and if the amount of assigned IP's - // has changed so we can insert a config-rebuild task if only - // the ip's of this domain were changed - // -> for now, always insert a rebuild-task - inserttask('1'); - - // Cleanup domain <-> ip mapping - $del_stmt = Database::prepare(" - DELETE FROM `" . TABLE_DOMAINTOIP . "` WHERE `id_domain` = :id - "); - Database::pexecute($del_stmt, array('id' => $id)); - - $ins_stmt = Database::prepare(" - INSERT INTO `" . TABLE_DOMAINTOIP . "` SET `id_domain` = :domainid, `id_ipandports` = :ipportid - "); - - foreach ($ipandports as $ipportid) { - Database::pexecute($ins_stmt, array('domainid' => $id, 'ipportid' => $ipportid)); - } - foreach ($ssl_ipandports as $ssl_ipportid) { - if ($ssl_ipportid > 0) { - Database::pexecute($ins_stmt, array('domainid' => $id, 'ipportid' => $ssl_ipportid)); - } - } - - // Cleanup domain <-> ip mapping for subdomains - $domainidsresult_stmt = Database::prepare(" - SELECT `id` FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `parentdomainid` = :id - "); - Database::pexecute($domainidsresult_stmt, array('id' => $id)); - - while ($row = $domainidsresult_stmt->fetch(PDO::FETCH_ASSOC)) { - - $del_stmt = Database::prepare(" - DELETE FROM `" . TABLE_DOMAINTOIP . "` WHERE `id_domain` = :rowid - "); - Database::pexecute($del_stmt, array('rowid' => $row['id'])); - - $ins_stmt = Database::prepare(" - INSERT INTO `" . TABLE_DOMAINTOIP . "` SET - `id_domain` = :rowid, - `id_ipandports` = :ipportid - "); - - foreach ($ipandports as $ipportid) { - Database::pexecute($ins_stmt, array('rowid' => $row['id'], 'ipportid' => $ipportid)); - } - foreach ($ssl_ipandports as $ssl_ipportid) { - if ($ssl_ipportid > 0) { - Database::pexecute($ins_stmt, array('rowid' => $row['id'], 'ipportid' => $ssl_ipportid)); - } - } - } - - $log->logAction(ADM_ACTION, LOG_INFO, "edited domain #" . $id); - redirectTo($filename, array('page' => $page, 's' => $s)); - + 's' => $s + )); } else { - if (Settings::Get('panel.allow_domain_change_customer') == '1') { $customers = ''; $result_customers_stmt = Database::prepare(" @@ -1824,8 +402,7 @@ if ($page == 'domains' WHERE ( (`subdomains_used` + :subdomains <= `subdomains` OR `subdomains` = '-1' ) AND (`emails_used` + :emails <= `emails` OR `emails` = '-1' ) AND (`email_forwarders_used` + :forwarders <= `email_forwarders` OR `email_forwarders` = '-1' ) - AND (`email_accounts_used` + :accounts <= `email_accounts` OR `email_accounts` = '-1' ) " . - ($userinfo['customers_see_all'] ? '' : " AND `adminid` = :adminid ") . ") + AND (`email_accounts_used` + :accounts <= `email_accounts` OR `email_accounts` = '-1' ) " . ($userinfo['customers_see_all'] ? '' : " AND `adminid` = :adminid ") . ") OR `customerid` = :customerid ORDER BY `name` ASC "); $params = array( @@ -1841,16 +418,17 @@ if ($page == 'domains' Database::pexecute($result_customers_stmt, $params); while ($row_customer = $result_customers_stmt->fetch(PDO::FETCH_ASSOC)) { - $customers.= makeoption(getCorrectFullUserDetails($row_customer) . ' (' . $row_customer['loginname'] . ')', $row_customer['customerid'], $result['customerid']); + $customers .= \Froxlor\UI\HTML::makeoption(\Froxlor\User::getCorrectFullUserDetails($row_customer) . ' (' . $row_customer['loginname'] . ')', $row_customer['customerid'], $result['customerid']); } - } else { $customer_stmt = Database::prepare(" SELECT `customerid`, `loginname`, `name`, `firstname`, `company` FROM `" . TABLE_PANEL_CUSTOMERS . "` WHERE `customerid` = :customerid "); - $customer = Database::pexecute_first($customer_stmt, array('customerid' => $result['customerid'])); - $result['customername'] = getCorrectFullUserDetails($customer) . ' (' . $customer['loginname'] . ')'; + $customer = Database::pexecute_first($customer_stmt, array( + 'customerid' => $result['customerid'] + )); + $result['customername'] = \Froxlor\User::getCorrectFullUserDetails($customer) . ' (' . $customer['loginname'] . ')'; } if ($userinfo['customers_see_all'] == '1') { @@ -1861,22 +439,26 @@ if ($page == 'domains' SELECT `adminid`, `loginname`, `name` FROM `" . TABLE_PANEL_ADMINS . "` WHERE (`domains_used` < `domains` OR `domains` = '-1') OR `adminid` = :adminid ORDER BY `name` ASC "); - Database::pexecute($result_admins_stmt, array('adminid' => $result['adminid'])); + Database::pexecute($result_admins_stmt, array( + 'adminid' => $result['adminid'] + )); while ($row_admin = $result_admins_stmt->fetch(PDO::FETCH_ASSOC)) { - $admins.= makeoption(getCorrectFullUserDetails($row_admin) . ' (' . $row_admin['loginname'] . ')', $row_admin['adminid'], $result['adminid']); + $admins .= \Froxlor\UI\HTML::makeoption(\Froxlor\User::getCorrectFullUserDetails($row_admin) . ' (' . $row_admin['loginname'] . ')', $row_admin['adminid'], $result['adminid']); } } else { $admin_stmt = Database::prepare(" SELECT `adminid`, `loginname`, `name` FROM `" . TABLE_PANEL_ADMINS . "` WHERE `adminid` = :adminid "); - $admin = Database::pexecute_first($admin_stmt, array('adminid' => $result['adminid'])); - $result['adminname'] = getCorrectFullUserDetails($admin) . ' (' . $admin['loginname'] . ')'; + $admin = Database::pexecute_first($admin_stmt, array( + 'adminid' => $result['adminid'] + )); + $result['adminname'] = \Froxlor\User::getCorrectFullUserDetails($admin) . ' (' . $admin['loginname'] . ')'; } } $result['domain'] = $idna_convert->decode($result['domain']); - $domains = makeoption($lng['domains']['noaliasdomain'], 0, null, true); + $domains = \Froxlor\UI\HTML::makeoption($lng['domains']['noaliasdomain'], 0, null, true); $result_domains_stmt = Database::prepare(" SELECT `d`.`id`, `d`.`domain` FROM `" . TABLE_PANEL_DOMAINS . "` `d`, `" . TABLE_PANEL_CUSTOMERS . "` `c` @@ -1884,28 +466,32 @@ if ($page == 'domains' AND `c`.`standardsubdomain`<>`d`.`id` AND `d`.`customerid` = :customerid AND `c`.`customerid`=`d`.`customerid` ORDER BY `d`.`domain` ASC "); - Database::pexecute($result_domains_stmt, array('id' => $result['id'], 'customerid' => $result['customerid'])); + Database::pexecute($result_domains_stmt, array( + 'id' => $result['id'], + 'customerid' => $result['customerid'] + )); while ($row_domain = $result_domains_stmt->fetch(PDO::FETCH_ASSOC)) { - $domains.= makeoption($idna_convert->decode($row_domain['domain']), $row_domain['id'], $result['aliasdomain']); + $domains .= \Froxlor\UI\HTML::makeoption($idna_convert->decode($row_domain['domain']), $row_domain['id'], $result['aliasdomain']); } - $subtodomains = makeoption($lng['domains']['nosubtomaindomain'], 0, null, true); + $subtodomains = \Froxlor\UI\HTML::makeoption($lng['domains']['nosubtomaindomain'], 0, null, true); $result_domains_stmt = Database::prepare(" SELECT `d`.`id`, `d`.`domain` FROM `" . TABLE_PANEL_DOMAINS . "` `d`, `" . TABLE_PANEL_CUSTOMERS . "` `c` WHERE `d`.`aliasdomain` IS NULL AND `d`.`parentdomainid` = '0' AND `d`.`id` <> :id - AND `c`.`standardsubdomain`<>`d`.`id` AND `c`.`customerid`=`d`.`customerid`". - ($userinfo['customers_see_all'] ? '' : " AND `d`.`adminid` = :adminid") . " + AND `c`.`standardsubdomain`<>`d`.`id` AND `c`.`customerid`=`d`.`customerid`" . ($userinfo['customers_see_all'] ? '' : " AND `d`.`adminid` = :adminid") . " ORDER BY `d`.`domain` ASC "); - $params = array('id' => $result['id']); + $params = array( + 'id' => $result['id'] + ); if ($userinfo['customers_see_all'] == '0') { $params['adminid'] = $userinfo['adminid']; } Database::pexecute($result_domains_stmt, $params); while ($row_domain = $result_domains_stmt->fetch(PDO::FETCH_ASSOC)) { - $subtodomains.= makeoption($idna_convert->decode($row_domain['domain']), $row_domain['id'], $result['ismainbutsubto']); + $subtodomains .= \Froxlor\UI\HTML::makeoption($idna_convert->decode($row_domain['domain']), $row_domain['id'], $result['ismainbutsubto']); } if ($userinfo['ip'] == "-1") { @@ -1919,17 +505,23 @@ if ($page == 'domains' $admin_ip_stmt = Database::prepare(" SELECT `id`, `ip`, `port` FROM `" . TABLE_PANEL_IPSANDPORTS . "` WHERE `id` = :ipid ORDER BY `ip`, `port` ASC "); - $admin_ip = Database::pexecute_first($admin_ip_stmt, array('ipid' => $userinfo['ip'])); + $admin_ip = Database::pexecute_first($admin_ip_stmt, array( + 'ipid' => $userinfo['ip'] + )); $result_ipsandports_stmt = Database::prepare(" SELECT `id`, `ip`, `port` FROM `" . TABLE_PANEL_IPSANDPORTS . "` WHERE `ssl`='0' AND `ip` = :ipid ORDER BY `ip`, `port` ASC "); - Database::pexecute($result_ipsandports_stmt, array('ipid' => $admin_ip['ip'])); + Database::pexecute($result_ipsandports_stmt, array( + 'ipid' => $admin_ip['ip'] + )); $result_ssl_ipsandports_stmt = Database::prepare(" SELECT `id`, `ip`, `port` FROM `" . TABLE_PANEL_IPSANDPORTS . "` WHERE `ssl`='1' AND `ip` = :ipid ORDER BY `ip`, `port` ASC "); - Database::pexecute($result_ssl_ipsandports_stmt, array('ipid' => $admin_ip['ip'])); + Database::pexecute($result_ssl_ipsandports_stmt, array( + 'ipid' => $admin_ip['ip'] + )); } $ipsandports = array(); @@ -1937,7 +529,10 @@ if ($page == 'domains' if (filter_var($row_ipandport['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { $row_ipandport['ip'] = '[' . $row_ipandport['ip'] . ']'; } - $ipsandports[] = array('label' => $row_ipandport['ip'] . ':' . $row_ipandport['port'] . '
', 'value' => $row_ipandport['id']); + $ipsandports[] = array( + 'label' => $row_ipandport['ip'] . ':' . $row_ipandport['port'] . '
', + 'value' => $row_ipandport['id'] + ); } $ssl_ipsandports = array(); @@ -1945,7 +540,10 @@ if ($page == 'domains' if (filter_var($row_ssl_ipandport['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { $row_ssl_ipandport['ip'] = '[' . $row_ssl_ipandport['ip'] . ']'; } - $ssl_ipsandports[] = array('label' => $row_ssl_ipandport['ip'] . ':' . $row_ssl_ipandport['port'] . '
', 'value' => $row_ssl_ipandport['id']); + $ssl_ipsandports[] = array( + 'label' => $row_ssl_ipandport['ip'] . ':' . $row_ssl_ipandport['port'] . '
', + 'value' => $row_ssl_ipandport['id'] + ); } // create serveralias options @@ -1961,92 +559,139 @@ if ($page == 'domains' // Fudge the result for ssl_redirect to hide the Let's Encrypt steps $result['temporary_ssl_redirect'] = $result['ssl_redirect']; $result['ssl_redirect'] = ($result['ssl_redirect'] == 0 ? 0 : 1); - - $serveraliasoptions .= makeoption($lng['domains']['serveraliasoption_wildcard'], '0', $_value, true, true); - $serveraliasoptions .= makeoption($lng['domains']['serveraliasoption_www'], '1', $_value, true, true); - $serveraliasoptions .= makeoption($lng['domains']['serveraliasoption_none'], '2', $_value, true, true); - $subcanemaildomain = makeoption($lng['admin']['subcanemaildomain']['never'], '0', $result['subcanemaildomain'], true, true); - $subcanemaildomain.= makeoption($lng['admin']['subcanemaildomain']['choosableno'], '1', $result['subcanemaildomain'], true, true); - $subcanemaildomain.= makeoption($lng['admin']['subcanemaildomain']['choosableyes'], '2', $result['subcanemaildomain'], true, true); - $subcanemaildomain.= makeoption($lng['admin']['subcanemaildomain']['always'], '3', $result['subcanemaildomain'], true, true); + $serveraliasoptions .= \Froxlor\UI\HTML::makeoption($lng['domains']['serveraliasoption_wildcard'], '0', $_value, true, true); + $serveraliasoptions .= \Froxlor\UI\HTML::makeoption($lng['domains']['serveraliasoption_www'], '1', $_value, true, true); + $serveraliasoptions .= \Froxlor\UI\HTML::makeoption($lng['domains']['serveraliasoption_none'], '2', $_value, true, true); + + $subcanemaildomain = \Froxlor\UI\HTML::makeoption($lng['admin']['subcanemaildomain']['never'], '0', $result['subcanemaildomain'], true, true); + $subcanemaildomain .= \Froxlor\UI\HTML::makeoption($lng['admin']['subcanemaildomain']['choosableno'], '1', $result['subcanemaildomain'], true, true); + $subcanemaildomain .= \Froxlor\UI\HTML::makeoption($lng['admin']['subcanemaildomain']['choosableyes'], '2', $result['subcanemaildomain'], true, true); + $subcanemaildomain .= \Froxlor\UI\HTML::makeoption($lng['admin']['subcanemaildomain']['always'], '3', $result['subcanemaildomain'], true, true); $speciallogfile = ($result['speciallogfile'] == 1 ? $lng['panel']['yes'] : $lng['panel']['no']); $result['add_date'] = date('Y-m-d', $result['add_date']); $phpconfigs = ''; - $phpconfigs_result_stmt = Database::query("SELECT * FROM `" . TABLE_PANEL_PHPCONFIGS . "`"); - - while ($phpconfigs_row = $phpconfigs_result_stmt->fetch(PDO::FETCH_ASSOC)) { - $phpconfigs.= makeoption($phpconfigs_row['description'], $phpconfigs_row['id'], $result['phpsettingid'], true, true); + $phpconfigs_result_stmt = Database::query(" + SELECT c.*, fc.description as interpreter + FROM `" . TABLE_PANEL_PHPCONFIGS . "` c + LEFT JOIN `" . TABLE_PANEL_FPMDAEMONS . "` fc ON fc.id = c.fpmsettingid + "); + $c_allowed_configs = \Froxlor\Customer\Customer::getCustomerDetail($result['customerid'], 'allowed_phpconfigs'); + if (! empty($c_allowed_configs)) { + $c_allowed_configs = json_decode($c_allowed_configs, true); + } else { + $c_allowed_configs = array(); } - $result = htmlentities_array($result); + while ($phpconfigs_row = $phpconfigs_result_stmt->fetch(PDO::FETCH_ASSOC)) { + $disabled = ! empty($c_allowed_configs) && ! in_array($phpconfigs_row['id'], $c_allowed_configs); + if ((int) Settings::Get('phpfpm.enabled') == 1) { + $phpconfigs .= \Froxlor\UI\HTML::makeoption($phpconfigs_row['description'] . " [" . $phpconfigs_row['interpreter'] . "]", $phpconfigs_row['id'], $result['phpsettingid'], true, true, null, $disabled); + } else { + $phpconfigs .= \Froxlor\UI\HTML::makeoption($phpconfigs_row['description'], $phpconfigs_row['id'], $result['phpsettingid'], true, true, null, $disabled); + } + } - $domain_edit_data = include_once dirname(__FILE__).'/lib/formfields/admin/domains/formfield.domains_edit.php'; - $domain_edit_form = htmlform::genHTMLForm($domain_edit_data); + $result = \Froxlor\PhpHelper::htmlentitiesArray($result); + + $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); $title = $domain_edit_data['domain_edit']['title']; $image = $domain_edit_data['domain_edit']['image']; $speciallogwarning = sprintf($lng['admin']['speciallogwarning'], $lng['admin']['delete_statistics']); - eval("echo \"" . getTemplate("domains/domains_edit") . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("domains/domains_edit") . "\";"); } } - } elseif($action == 'import') { + } elseif ($action == 'jqGetCustomerPHPConfigs') { - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { + $customerid = intval($_POST['customerid']); + $allowed_phpconfigs = \Froxlor\Customer\Customer::getCustomerDetail($customerid, 'allowed_phpconfigs'); + echo ! empty($allowed_phpconfigs) ? $allowed_phpconfigs : json_encode(array()); + exit(); + } elseif ($action == 'import') { - $customerid = intval($_POST['customerid']); - $separator = validate($_POST['separator'], 'separator'); - $offset = (int)validate($_POST['offset'], 'offset', "/[0-9]/i"); + if (isset($_POST['send']) && $_POST['send'] == 'send') { + + $separator = \Froxlor\Validate\Validate::validate($_POST['separator'], 'separator'); + $offset = (int) \Froxlor\Validate\Validate::validate($_POST['offset'], 'offset', "/[0-9]/i"); $file_name = $_FILES['file']['tmp_name']; $result = array(); try { - $bulk = new DomainBulkAction($file_name, $customerid); + $bulk = new \Froxlor\Bulk\DomainBulkAction($file_name, $userinfo); $result = $bulk->doImport($separator, $offset); } catch (Exception $e) { - standard_error('domain_import_error', $e->getMessage()); + \Froxlor\UI\Response::standard_error('domain_import_error', $e->getMessage()); } - // @FIXME find a way to display $result['notice'] here somehow, - // as it might be important if you've reached your maximum allocation of domains + if (! empty($bulk->getErrors())) { + \Froxlor\UI\Response::dynamic_error(implode("
", $bulk->getErrors())); + } // update customer/admin counters - updateCounters(false); + \Froxlor\User::updateCounters(false); + \Froxlor\System\Cronjob::inserttask('1'); + \Froxlor\System\Cronjob::inserttask('4'); - $result_str = $result['imported'] . ' / ' . $result['all']; - standard_success('domain_import_successfully', $result_str, array('filename' => $filename, 'action' => '', 'page' => 'domains')); + $result_str = $result['imported'] . ' / ' . $result['all'] . (! empty($result['note']) ? ' (' . $result['note'] . ')' : ''); + \Froxlor\UI\Response::standard_success('domain_import_successfully', $result_str, array( + 'filename' => $filename, + 'action' => '', + 'page' => 'domains' + )); } else { - $customers = 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.= makeoption(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 = htmlform::genHTMLForm($domain_import_data); + $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); $title = $domain_import_data['domain_import']['title']; $image = $domain_import_data['domain_import']['image']; - eval("echo \"" . getTemplate("domains/domains_import") . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("domains/domains_import") . "\";"); + } + } +} elseif ($page == 'domaindnseditor' && Settings::Get('system.dnsenabled') == '1') { + + require_once __DIR__ . '/dns_editor.php'; +} elseif ($page == 'sslcertificates') { + + require_once __DIR__ . '/ssl_certificates.php'; +} elseif ($page == 'logfiles') { + + require_once __DIR__ . '/logfiles_viewer.php'; +} + +function formatDomainEntry(&$row, &$idna_convert) +{ + $row['domain'] = $idna_convert->decode($row['domain']); + $row['aliasdomain'] = $idna_convert->decode($row['aliasdomain']); + + $row['ipandport'] = ''; + foreach ($row['ipsandports'] as $rowip) { + if (filter_var($rowip['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { + $row['ipandport'] .= '[' . $rowip['ip'] . ']:' . $rowip['port'] . "\n"; + } else { + $row['ipandport'] .= $rowip['ip'] . ':' . $rowip['port'] . "\n"; + } + } + $row['ipandport'] = substr($row['ipandport'], 0, - 1); + $row['termination_date'] = str_replace("0000-00-00", "", $row['termination_date']); + + $row['termination_css'] = ""; + if ($row['termination_date'] != "") { + $cdate = strtotime($row['termination_date'] . " 23:59:59"); + $today = time(); + + if ($cdate < $today) { + $row['termination_css'] = 'domain-expired'; + } else { + $row['termination_css'] = 'domain-canceled'; } } } diff --git a/admin_index.php b/admin_index.php index baa1a2aa..3415d14f 100644 --- a/admin_index.php +++ b/admin_index.php @@ -16,42 +16,47 @@ * @package Panel * */ - define('AREA', 'admin'); require './lib/init.php'; -if ($action == 'logout') { +use Froxlor\Database\Database; +use Froxlor\Settings; +use Froxlor\Api\Commands\Froxlor as Froxlor; +use Froxlor\Api\Commands\Admins as Admins; - $log->logAction(ADM_ACTION, LOG_NOTICE, "logged out"); +if ($action == 'logout') { - $params = array('adminid' => (int)$userinfo['adminid']); + $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "logged out"); + + $params = array( + 'adminid' => (int) $userinfo['adminid'] + ); if (Settings::Get('session.allow_multiple_login') == '1') { $stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_SESSIONS . "` WHERE `userid` = :adminid AND `adminsession` = '1' - AND `hash` = :hash" - ); + AND `hash` = :hash"); $params['hash'] = $s; } else { $stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_SESSIONS . "` WHERE `userid` = :adminid - AND `adminsession` = '1'" - ); + AND `adminsession` = '1'"); } Database::pexecute($stmt, $params); - redirectTo('index.php'); + \Froxlor\UI\Response::redirectTo('index.php'); } if (isset($_POST['id'])) { $id = intval($_POST['id']); -} elseif(isset($_GET['id'])) { +} elseif (isset($_GET['id'])) { $id = intval($_GET['id']); } if ($page == 'overview') { - $log->logAction(ADM_ACTION, LOG_NOTICE, "viewed admin_index"); + + $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "viewed admin_index"); $overview_stmt = Database::prepare("SELECT COUNT(*) AS `number_customers`, SUM(`diskspace_used`) AS `diskspace_used`, SUM(`mysqls_used`) AS `mysqls_used`, @@ -60,11 +65,12 @@ if ($page == 'overview') { SUM(`email_forwarders_used`) AS `email_forwarders_used`, SUM(`email_quota_used`) AS `email_quota_used`, SUM(`ftps_used`) AS `ftps_used`, - SUM(`tickets_used`) AS `tickets_used`, 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, array( + 'adminid' => $userinfo['adminid'] + )); $dec_places = Settings::Get('panel.decimal_places'); $overview['traffic_used'] = round($overview['traffic_used'] / (1024 * 1024), $dec_places); @@ -72,9 +78,10 @@ if ($page == 'overview') { $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'])); + WHERE `parentdomainid`='0'" . ($userinfo['customers_see_all'] ? '' : " AND `adminid` = :adminid")); + $number_domains = Database::pexecute_first($number_domains_stmt, array( + 'adminid' => $userinfo['adminid'] + )); $overview['number_domains'] = $number_domains['number_domains']; @@ -82,52 +89,23 @@ if ($page == 'overview') { $mysqlserverversion = Database::getAttribute(PDO::ATTR_SERVER_VERSION); $webserverinterface = strtoupper(@php_sapi_name()); - if ((isset($_GET['lookfornewversion']) && $_GET['lookfornewversion'] == 'yes') - || (isset($lookfornewversion) && $lookfornewversion == 'yes') - ) { - $update_check_uri = 'http://version.froxlor.org/Froxlor/legacy/' . $version; - - if (ini_get('allow_url_fopen')) { - $latestversion = @file($update_check_uri); - - if (isset($latestversion[0])) { - $latestversion = explode('|', $latestversion[0]); - - if (is_array($latestversion) - && count($latestversion) >= 1 - ) { - $_version = $latestversion[0]; - $_message = isset($latestversion[1]) ? $latestversion[1] : ''; - $_link = isset($latestversion[2]) ? $latestversion[2] : htmlspecialchars($filename . '?s=' . urlencode($s) . '&page=' . urlencode($page) . '&lookfornewversion=yes'); - - // add the branding so debian guys are not gettings confused - // about their version-number - $lookfornewversion_lable = $_version.$branding; - $lookfornewversion_link = $_link; - $lookfornewversion_addinfo = $_message; - - // not numeric -> error-message - if (!preg_match('/^((\d+\\.)(\d+\\.)(\d+\\.)?(\d+)?(\-(svn|dev|rc)(\d+))?)$/', $_version)) { - // check for customized version to not output - // "There is a newer version of froxlor" besides the error-message - $isnewerversion = 2; - } elseif (version_compare2($version, $_version) == -1) { - $isnewerversion = 1; - } else { - $isnewerversion = 0; - } - } else { - redirectTo($update_check_uri.'/pretty', NULL, false); - } - } else { - redirectTo($update_check_uri.'/pretty', NULL, false); - } - } else { - redirectTo($update_check_uri.'/pretty', NULL, false); + if ((isset($_GET['lookfornewversion']) && $_GET['lookfornewversion'] == 'yes') || (isset($lookfornewversion) && $lookfornewversion == 'yes')) { + try { + $json_result = Froxlor::getLocal($userinfo)->checkUpdate(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } + $result = json_decode($json_result, true)['data']; + + $lookfornewversion_lable = $result['version']; + $lookfornewversion_link = $result['link']; + $lookfornewversion_message = $result['message']; + $lookfornewversion_addinfo = $result['additional_info']; + $isnewerversion = $result['isnewerversion']; } else { $lookfornewversion_lable = $lng['admin']['lookfornewversion']['clickhere']; $lookfornewversion_link = htmlspecialchars($filename . '?s=' . urlencode($s) . '&page=' . urlencode($page) . '&lookfornewversion=yes'); + $lookfornewversion_message = ''; $lookfornewversion_addinfo = ''; $isnewerversion = 0; } @@ -137,12 +115,21 @@ if ($page == 'overview') { $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 = str_replace_array('-1', $lng['customer']['unlimited'], $userinfo, 'customers domains diskspace traffic mysqls emails email_accounts email_forwarders email_quota ftps tickets subdomains'); + $userinfo = \Froxlor\PhpHelper::strReplaceArray('-1', $lng['customer']['unlimited'], $userinfo, 'customers domains diskspace traffic mysqls emails email_accounts email_forwarders email_quota ftps subdomains'); $userinfo['custom_notes'] = ($userinfo['custom_notes'] != '') ? nl2br($userinfo['custom_notes']) : ''; - $cron_last_runs = getCronjobsLastRun(); - $outstanding_tasks = getOutstandingTasks(); + $cron_last_runs = \Froxlor\System\Cronjob::getCronjobsLastRun(); + $outstanding_tasks = \Froxlor\System\Cronjob::getOutstandingTasks(); + + $system_hostname = gethostname(); + $meminfo = explode("\n", @file_get_contents("/proc/meminfo")); + $memory = ""; + for ($i = 0; $i < sizeof($meminfo); ++ $i) { + if (substr($meminfo[$i], 0, 3) === "Mem") { + $memory .= $meminfo[$i] . PHP_EOL; + } + } if (function_exists('sys_getloadavg')) { $loadArray = sys_getloadavg(); @@ -150,7 +137,7 @@ if ($page == 'overview') { } else { $load = @file_get_contents('/proc/loadavg'); - if (!$load) { + if (! $load) { $load = $lng['admin']['noloadavailable']; } } @@ -168,10 +155,7 @@ if ($page == 'overview') { // First: With exec (let's hope it's enabled for the Froxlor - vHost) $uptime_array = explode(" ", @file_get_contents("/proc/uptime")); - if (is_array($uptime_array) - && isset($uptime_array[0]) - && is_numeric($uptime_array[0]) - ) { + if (is_array($uptime_array) && isset($uptime_array[0]) && is_numeric($uptime_array[0])) { // Some calculatioon to get a nicly formatted display $seconds = round($uptime_array[0], 0); $minutes = $seconds / 60; @@ -189,79 +173,82 @@ if ($page == 'overview') { $uptime = ''; } - eval("echo \"" . getTemplate("index/index") . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("index/index") . "\";"); +} elseif ($page == 'change_password') { -} elseif($page == 'change_password') { + if (isset($_POST['send']) && $_POST['send'] == 'send') { + $old_password = \Froxlor\Validate\Validate::validate($_POST['old_password'], 'old password'); - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { - $old_password = validate($_POST['old_password'], 'old password'); - - if (!validatePasswordLogin($userinfo,$old_password,TABLE_PANEL_ADMINS,'adminid')) { - standard_error('oldpasswordnotcorrect'); + if (! \Froxlor\System\Crypt::validatePasswordLogin($userinfo, $old_password, TABLE_PANEL_ADMINS, 'adminid')) { + \Froxlor\UI\Response::standard_error('oldpasswordnotcorrect'); } - $new_password = validate($_POST['new_password'], 'new password'); - $new_password_confirm = validate($_POST['new_password_confirm'], 'new password confirm'); + $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'); if ($old_password == '') { - standard_error(array('stringisempty', 'oldpassword')); - } elseif($new_password == '') { - standard_error(array('stringisempty', 'newpassword')); - } elseif($new_password_confirm == '') { - standard_error(array('stringisempty', 'newpasswordconfirm')); - } elseif($new_password != $new_password_confirm) { - standard_error('newpasswordconfirmerror'); - } else { - $chgpwd_stmt = Database::prepare(" - UPDATE `" . TABLE_PANEL_ADMINS . "` - SET `password`= :newpasswd - WHERE `adminid`= :adminid" - ); - Database::pexecute($chgpwd_stmt, array( - 'newpasswd' => makeCryptPassword($new_password), - 'adminid' => (int)$userinfo['adminid'] + \Froxlor\UI\Response::standard_error(array( + 'stringisempty', + 'oldpassword' + )); + } elseif ($new_password == '') { + \Froxlor\UI\Response::standard_error(array( + 'stringisempty', + 'newpassword' + )); + } elseif ($new_password_confirm == '') { + \Froxlor\UI\Response::standard_error(array( + 'stringisempty', + 'newpasswordconfirm' + )); + } elseif ($new_password != $new_password_confirm) { + \Froxlor\UI\Response::standard_error('newpasswordconfirmerror'); + } else { + try { + Admins::getLocal($userinfo, array( + 'id' => $userinfo['adminid'], + 'admin_password' => $new_password + ))->update(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, 'changed password'); + \Froxlor\UI\Response::redirectTo($filename, Array( + 's' => $s )); - $log->logAction(ADM_ACTION, LOG_NOTICE, 'changed password'); - redirectTo($filename, Array('s' => $s)); } } else { - eval("echo \"" . getTemplate("index/change_password") . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("index/change_password") . "\";"); } +} elseif ($page == 'change_language') { -} elseif($page == 'change_language') { - - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { - $def_language = validate($_POST['def_language'], 'default language'); + if (isset($_POST['send']) && $_POST['send'] == 'send') { + $def_language = \Froxlor\Validate\Validate::validate($_POST['def_language'], 'default language'); if (isset($languages[$def_language])) { - $lng_stmt = Database::prepare(" - UPDATE `" . TABLE_PANEL_ADMINS . "` - SET `def_language`= :deflng - WHERE `adminid`= :adminid" - ); - Database::pexecute($lng_stmt, array( - 'deflng' => $def_language, - 'adminid' => (int)$userinfo['adminid'] - )); + try { + Admins::getLocal($userinfo, array( + 'id' => $userinfo['adminid'], + 'def_language' => $def_language + ))->update(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + // also update current session $lng_stmt = Database::prepare(" UPDATE `" . TABLE_PANEL_SESSIONS . "` SET `language`= :lng - WHERE `hash`= :hash" - ); + WHERE `hash`= :hash"); Database::pexecute($lng_stmt, array( 'lng' => $def_language, 'hash' => $s )); } - - $log->logAction(ADM_ACTION, LOG_NOTICE, "changed his/her default language to '" . $def_language . "'"); - redirectTo($filename, array('s' => $s)); - + $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "changed his/her default language to '" . $def_language . "'"); + \Froxlor\UI\Response::redirectTo($filename, array( + 's' => $s + )); } else { $language_options = ''; @@ -271,43 +258,39 @@ if ($page == 'overview') { $default_lang = $userinfo['def_language']; } - while (list($language_file, $language_name) = each($languages)) { - $language_options.= makeoption($language_name, $language_file, $default_lang, true); + foreach ($languages as $language_file => $language_name) { + $language_options .= \Froxlor\UI\HTML::makeoption($language_name, $language_file, $default_lang, true); } - eval("echo \"" . getTemplate("index/change_language") . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("index/change_language") . "\";"); } - } elseif ($page == 'change_theme') { - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { - $theme = validate($_POST['theme'], 'theme'); - - $theme_stmt = Database::prepare(" - UPDATE `" . TABLE_PANEL_ADMINS . "` - SET `theme`= :theme - WHERE `adminid`= :adminid" - ); - Database::pexecute($theme_stmt, array( - 'theme' => $theme, - 'adminid' => (int)$userinfo['adminid'] - )); + if (isset($_POST['send']) && $_POST['send'] == 'send') { + $theme = \Froxlor\Validate\Validate::validate($_POST['theme'], 'theme'); + try { + Admins::getLocal($userinfo, array( + 'id' => $userinfo['adminid'], + 'theme' => $theme + ))->update(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + // also update current session $theme_stmt = Database::prepare(" UPDATE `" . TABLE_PANEL_SESSIONS . "` SET `theme`= :theme - WHERE `hash`= :hash" - ); + WHERE `hash`= :hash"); Database::pexecute($theme_stmt, array( 'theme' => $theme, 'hash' => $s )); - $log->logAction(ADM_ACTION, LOG_NOTICE, "changed his/her theme to '" . $theme . "'"); - redirectTo($filename, array('s' => $s)); - + $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "changed his/her theme to '" . $theme . "'"); + \Froxlor\UI\Response::redirectTo($filename, array( + 's' => $s + )); } else { $theme_options = ''; @@ -317,27 +300,22 @@ if ($page == 'overview') { $default_theme = $userinfo['theme']; } - $themes_avail = getThemes(); + $themes_avail = \Froxlor\UI\Template::getThemes(); foreach ($themes_avail as $t => $d) { - $theme_options.= makeoption($d, $t, $default_theme, true); + $theme_options .= \Froxlor\UI\HTML::makeoption($d, $t, $default_theme, true); } - eval("echo \"" . getTemplate("index/change_theme") . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("index/change_theme") . "\";"); } - -} elseif ($page == 'send_error_report' - && Settings::Get('system.allow_error_report_admin') == '1' -) { +} elseif ($page == 'send_error_report' && Settings::Get('system.allow_error_report_admin') == '1') { // only show this if we really have an exception to report - if (isset($_GET['errorid']) - && $_GET['errorid'] != '' - ) { + if (isset($_GET['errorid']) && $_GET['errorid'] != '') { $errid = $_GET['errorid']; // read error file - $err_dir = makeCorrectDir(FROXLOR_INSTALL_DIR."/logs/"); - $err_file = makeCorrectFile($err_dir."/".$errid."_sql-error.log"); + $err_dir = \Froxlor\FileDir::makeCorrectDir(\Froxlor\Froxlor::getInstallDir() . "/logs/"); + $err_file = \Froxlor\FileDir::makeCorrectFile($err_dir . "/" . $errid . "_sql-error.log"); if (file_exists($err_file)) { @@ -347,27 +325,26 @@ if ($page == 'overview') { $_error = array( 'code' => str_replace("\n", "", substr($error[1], 5)), 'message' => str_replace("\n", "", substr($error[2], 4)), - 'file' => str_replace("\n", "", substr($error[3], 5 + strlen(FROXLOR_INSTALL_DIR))), + 'file' => str_replace("\n", "", substr($error[3], 5 + strlen(\Froxlor\Froxlor::getInstallDir()))), 'line' => str_replace("\n", "", substr($error[4], 5)), - 'trace' => str_replace(FROXLOR_INSTALL_DIR, "", substr($error[5], 6)) + 'trace' => str_replace(\Froxlor\Froxlor::getInstallDir(), "", substr($error[5], 6)) ); // build mail-content $mail_body = "Dear froxlor-team,\n\n"; $mail_body .= "the following error has been reported by a user:\n\n"; $mail_body .= "-------------------------------------------------------------\n"; - $mail_body .= $_error['code'].' '.$_error['message']."\n\n"; - $mail_body .= "File: ".$_error['file'].':'.$_error['line']."\n\n"; - $mail_body .= "Trace:\n".trim($_error['trace'])."\n\n"; + $mail_body .= $_error['code'] . ' ' . $_error['message'] . "\n\n"; + $mail_body .= "File: " . $_error['file'] . ':' . $_error['line'] . "\n\n"; + $mail_body .= "Trace:\n" . trim($_error['trace']) . "\n\n"; $mail_body .= "-------------------------------------------------------------\n\n"; - $mail_body .= "Froxlor-version: ".$version."\n\n"; + $mail_body .= "Froxlor-version: " . $version . "\n"; + $mail_body .= "DB-version: " . $dbversion . "\n\n"; $mail_body .= "End of report"; $mail_html = nl2br($mail_body); // send actual report to dev-team - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { + if (isset($_POST['send']) && $_POST['send'] == 'send') { // send mail and say thanks $_mailerror = false; try { @@ -376,7 +353,7 @@ if ($page == 'overview') { $mail->MsgHTML($mail_html); $mail->AddAddress('error-reports@froxlor.org', 'Froxlor Developer Team'); $mail->Send(); - } catch(phpmailerException $e) { + } catch (\PHPMailer\PHPMailer\Exception $e) { $mailerr_msg = $e->errorMessage(); $_mailerror = true; } catch (Exception $e) { @@ -386,21 +363,30 @@ if ($page == 'overview') { if ($_mailerror) { // error when reporting an error...LOLFUQ - standard_error('send_report_error', $mailerr_msg); + \Froxlor\UI\Response::standard_error('send_report_error', $mailerr_msg); } // finally remove error from fs @unlink($err_file); - redirectTo($filename, array('s' => $s)); + \Froxlor\UI\Response::redirectTo($filename, array( + 's' => $s + )); } // show a nice summary of the error-report // before actually sending anything - eval("echo \"" . getTemplate("index/send_error_report") . "\";"); - + eval("echo \"" . \Froxlor\UI\Template::getTemplate("index/send_error_report") . "\";"); } else { - redirectTo($filename, array('s' => $s)); + \Froxlor\UI\Response::redirectTo($filename, array( + 's' => $s + )); } } else { - redirectTo($filename, array('s' => $s)); + \Froxlor\UI\Response::redirectTo($filename, array( + 's' => $s + )); } +} elseif ($page == 'apikeys' && Settings::Get('api.enabled') == 1) { + require_once __DIR__ . '/api_keys.php'; +} elseif ($page == '2fa' && Settings::Get('2fa.enabled') == 1) { + require_once __DIR__ . '/2fa.php'; } diff --git a/admin_ipsandports.php b/admin_ipsandports.php index f03f6635..84006fb0 100644 --- a/admin_ipsandports.php +++ b/admin_ipsandports.php @@ -16,422 +16,158 @@ * @package Panel * */ - define('AREA', 'admin'); require './lib/init.php'; +use Froxlor\Settings; +use Froxlor\Api\Commands\IpsAndPorts; + if (isset($_POST['id'])) { $id = intval($_POST['id']); -} elseif(isset($_GET['id'])) { +} elseif (isset($_GET['id'])) { $id = intval($_GET['id']); } -if ($page == 'ipsandports' - || $page == 'overview' -) { +if ($page == 'ipsandports' || $page == 'overview') { // Do not display attributes that are not used by the current webserver $websrv = Settings::Get('system.webserver'); $is_nginx = ($websrv == 'nginx'); $is_apache = ($websrv == 'apache2'); + $is_apache24 = $is_apache && (Settings::Get('system.apache24') === '1'); if ($action == '') { - $log->logAction(ADM_ACTION, LOG_NOTICE, "viewed admin_ipsandports"); + $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "viewed admin_ipsandports"); $fields = array( 'ip' => $lng['admin']['ipsandports']['ip'], 'port' => $lng['admin']['ipsandports']['port'] ); - $paging = new paging($userinfo, TABLE_PANEL_IPSANDPORTS, $fields); + try { + // get total count + $json_result = IpsAndPorts::getLocal($userinfo)->listingCount(); + $result = json_decode($json_result, true)['data']; + // initialize pagination and filtering + $paging = new \Froxlor\UI\Pagination($userinfo, $fields, $result); + // get list + $json_result = IpsAndPorts::getLocal($userinfo, $paging->getApiCommandParams())->listing(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; + $ipsandports = ''; - $result_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_IPSANDPORTS . "` " . $paging->getSqlWhere(false) . " " . $paging->getSqlOrderBy() . " " . $paging->getSqlLimit()); - Database::pexecute($result_stmt); - $paging->setEntries(Database::num_rows()); $sortcode = $paging->getHtmlSortCode($lng); $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); $searchcode = $paging->getHtmlSearchCode($lng); $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); - $i = 0; $count = 0; - while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { - - if ($paging->checkDisplay($i)) { - $row = htmlentities_array($row); - if (filter_var($row['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { - $row['ip'] = '[' . $row['ip'] . ']'; - } - eval("\$ipsandports.=\"" . getTemplate("ipsandports/ipsandports_ipandport") . "\";"); - $count++; + foreach ($result['list'] as $row) { + $row = \Froxlor\PhpHelper::htmlentitiesArray($row); + if (filter_var($row['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { + $row['ip'] = '[' . $row['ip'] . ']'; } - $i++; + eval("\$ipsandports.=\"" . \Froxlor\UI\Template::getTemplate("ipsandports/ipsandports_ipandport") . "\";"); + $count ++; } + eval("echo \"" . \Froxlor\UI\Template::getTemplate("ipsandports/ipsandports") . "\";"); + } elseif ($action == 'delete' && $id != 0) { + try { + $json_result = IpsAndPorts::getLocal($userinfo, array( + 'id' => $id + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; - eval("echo \"" . getTemplate("ipsandports/ipsandports") . "\";"); + if (isset($result['id']) && $result['id'] == $id) { + if (isset($_POST['send']) && $_POST['send'] == 'send') { - } elseif($action == 'delete' - && $id != 0 - ) { - $result_stmt = Database::prepare("SELECT `id`, `ip`, `port` FROM `" . TABLE_PANEL_IPSANDPORTS . "` WHERE `id` = :id"); - $result = Database::pexecute_first($result_stmt, array('id' => $id)); - - if (isset($result['id']) - && $result['id'] == $id - ) { - $result_checkdomain_stmt = Database::prepare(" - SELECT `id_domain` as `id` FROM `" . TABLE_DOMAINTOIP . "` WHERE `id_ipandports` = :id" - ); - $result_checkdomain = Database::pexecute_first($result_checkdomain_stmt, array('id' => $id)); - - if ($result_checkdomain['id'] == '') { - if (!in_array($result['id'], explode(',', Settings::Get('system.defaultip')))) { - - $result_sameipotherport_stmt = Database::prepare(" - SELECT `id` FROM `" . TABLE_PANEL_IPSANDPORTS . "` - WHERE `ip` = :ip AND `id` <> :id" - ); - $result_sameipotherport = Database::pexecute_first($result_sameipotherport_stmt, array('id' => $id, 'ip' => $result['ip'])); - - if (($result['ip'] != Settings::Get('system.ipaddress')) - || ($result['ip'] == Settings::Get('system.ipaddress') - && $result_sameipotherport['id'] != '') - ) { - $result_stmt = Database::prepare(" - SELECT `ip`, `port` FROM `" . TABLE_PANEL_IPSANDPORTS . "` - WHERE `id` = :id" - ); - $result = Database::pexecute_first($result_stmt, array('id' => $id)); - - if ($result['ip'] != '') { - - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { - $del_stmt = Database::prepare(" - DELETE FROM `" . TABLE_PANEL_IPSANDPORTS . "` - WHERE `id` = :id" - ); - Database::pexecute($del_stmt, array('id' => $id)); - - // also, remove connections to domains (multi-stack) - $del_stmt = Database::prepare(" - DELETE FROM `".TABLE_DOMAINTOIP."` WHERE `id_ipandports` = :id" - ); - Database::pexecute($del_stmt, array('id' => $id)); - - $log->logAction(ADM_ACTION, LOG_WARNING, "deleted IP/port '" . $result['ip'] . ":" . $result['port'] . "'"); - inserttask('1'); - // Using nameserver, insert a task which rebuilds the server config - inserttask('4'); - - redirectTo($filename, array('page' => $page, 's' => $s)); - - } else { - ask_yesno('admin_ip_reallydelete', $filename, array('id' => $id, 'page' => $page, 'action' => $action), $result['ip'] . ':' . $result['port']); - } - } - } else { - standard_error('cantdeletesystemip'); - } - } else { - standard_error('cantdeletedefaultip'); + try { + IpsAndPorts::getLocal($userinfo, array( + 'id' => $id + ))->delete(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } + + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); } else { - standard_error('ipstillhasdomains'); + \Froxlor\UI\HTML::askYesNo('admin_ip_reallydelete', $filename, array( + 'id' => $id, + 'page' => $page, + 'action' => $action + ), $result['ip'] . ':' . $result['port']); } } - - } elseif($action == 'add') { - - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { - - $ip = validate_ip($_POST['ip']); - $port = validate($_POST['port'], 'port', '/^(([1-9])|([1-9][0-9])|([1-9][0-9][0-9])|([1-9][0-9][0-9][0-9])|([1-5][0-9][0-9][0-9][0-9])|(6[0-4][0-9][0-9][0-9])|(65[0-4][0-9][0-9])|(655[0-2][0-9])|(6553[0-5]))$/Di', array('stringisempty', 'myport')); - $listen_statement = isset($_POST['listen_statement']) ? 1 : 0; - $namevirtualhost_statement = isset($_POST['namevirtualhost_statement']) ? 1 : 0; - $vhostcontainer = isset($_POST['vhostcontainer']) ? 1 : 0; - $specialsettings = validate(str_replace("\r\n", "\n", $_POST['specialsettings']), 'specialsettings', '/^[^\0]*$/'); - $vhostcontainer_servername_statement = isset($_POST['vhostcontainer_servername_statement']) ? 1 : 0; - $default_vhostconf_domain = validate(str_replace("\r\n", "\n", $_POST['default_vhostconf_domain']), 'default_vhostconf_domain', '/^[^\0]*$/'); - $docroot = validate($_POST['docroot'], 'docroot'); - - if ((int)Settings::Get('system.use_ssl') == 1) { - $ssl = isset($_POST['ssl']) ? intval($_POST['ssl']) : 0; - $ssl_cert_file = validate($_POST['ssl_cert_file'], 'ssl_cert_file'); - $ssl_key_file = validate($_POST['ssl_key_file'], 'ssl_key_file'); - $ssl_ca_file = validate($_POST['ssl_ca_file'], 'ssl_ca_file'); - $ssl_cert_chainfile = validate($_POST['ssl_cert_chainfile'], 'ssl_cert_chainfile'); - } else { - $ssl = 0; - $ssl_cert_file = ''; - $ssl_key_file = ''; - $ssl_ca_file = ''; - $ssl_cert_chainfile = ''; + } elseif ($action == 'add') { + if (isset($_POST['send']) && $_POST['send'] == 'send') { + try { + IpsAndPorts::getLocal($userinfo, $_POST)->add(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } - - if ($listen_statement != '1') { - $listen_statement = '0'; - } - - if ($namevirtualhost_statement != '1') { - $namevirtualhost_statement = '0'; - } - - if ($vhostcontainer != '1') { - $vhostcontainer = '0'; - } - - if ($vhostcontainer_servername_statement != '1') { - $vhostcontainer_servername_statement = '0'; - } - - if ($ssl != '1') { - $ssl = '0'; - } - - if ($ssl_cert_file != '') { - $ssl_cert_file = makeCorrectFile($ssl_cert_file); - } - - if ($ssl_key_file != '') { - $ssl_key_file = makeCorrectFile($ssl_key_file); - } - - if ($ssl_ca_file != '') { - $ssl_ca_file = makeCorrectFile($ssl_ca_file); - } - - if ($ssl_cert_chainfile != '') { - $ssl_cert_chainfile = makeCorrectFile($ssl_cert_chainfile); - } - - if (strlen(trim($docroot)) > 0) { - $docroot = makeCorrectDir($docroot); - } else { - $docroot = ''; - } - - $result_checkfordouble_stmt = Database::prepare(" - SELECT `id` FROM `" . TABLE_PANEL_IPSANDPORTS . "` - WHERE `ip` = :ip AND `port` = :port" - ); - $result_checkfordouble = Database::pexecute_first($result_checkfordouble_stmt, array('ip' => $ip, 'port' => $port)); - - if ($result_checkfordouble['id'] != '') { - standard_error('myipnotdouble'); - } else { - $ins_stmt = Database::prepare(" - INSERT INTO `" . TABLE_PANEL_IPSANDPORTS . "` - SET - `ip` = :ip, `port` = :port, `listen_statement` = :ls, - `namevirtualhost_statement` = :nvhs, `vhostcontainer` = :vhc, - `vhostcontainer_servername_statement` = :vhcss, - `specialsettings` = :ss, `ssl` = :ssl, - `ssl_cert_file` = :ssl_cert, `ssl_key_file` = :ssl_key, - `ssl_ca_file` = :ssl_ca, `ssl_cert_chainfile` = :ssl_chain, - `default_vhostconf_domain` = :dvhd, `docroot` = :docroot; - "); - $ins_data = array( - 'ip' => $ip, - 'port' => $port, - 'ls' => $listen_statement, - 'nvhs' => $namevirtualhost_statement, - 'vhc' => $vhostcontainer, - 'vhcss' => $vhostcontainer_servername_statement, - 'ss' => $specialsettings, - 'ssl' => $ssl, - 'ssl_cert' => $ssl_cert_file, - 'ssl_key' => $ssl_key_file, - 'ssl_ca' => $ssl_ca_file, - 'ssl_chain' => $ssl_cert_chainfile, - 'dvhd' => $default_vhostconf_domain, - 'docroot' => $docroot - ); - Database::pexecute($ins_stmt, $ins_data); - - if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { - $ip = '[' . $ip . ']'; - } - - $log->logAction(ADM_ACTION, LOG_WARNING, "added IP/port '" . $ip . ":" . $port . "'"); - inserttask('1'); - // Using nameserver, insert a task which rebuilds the server config - inserttask('4'); - redirectTo($filename, Array('page' => $page, 's' => $s)); - } - + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); } else { - $ipsandports_add_data = include_once dirname(__FILE__).'/lib/formfields/admin/ipsandports/formfield.ipsandports_add.php'; - $ipsandports_add_form = htmlform::genHTMLForm($ipsandports_add_data); + $ipsandports_add_data = include_once dirname(__FILE__) . '/lib/formfields/admin/ipsandports/formfield.ipsandports_add.php'; + $ipsandports_add_form = \Froxlor\UI\HtmlForm::genHTMLForm($ipsandports_add_data); $title = $ipsandports_add_data['ipsandports_add']['title']; $image = $ipsandports_add_data['ipsandports_add']['image']; - eval("echo \"" . getTemplate("ipsandports/ipsandports_add") . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("ipsandports/ipsandports_add") . "\";"); } - - } elseif($action == 'edit' - && $id != 0 - ) { - $result_stmt = Database::prepare(" - SELECT * FROM `" . TABLE_PANEL_IPSANDPORTS . "` WHERE `id` = :id" - ); - $result = Database::pexecute_first($result_stmt, array('id' => $id)); + } elseif ($action == 'edit' && $id != 0) { + try { + $json_result = IpsAndPorts::getLocal($userinfo, array( + 'id' => $id + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; if ($result['ip'] != '') { - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { - - $ip = validate_ip($_POST['ip']); - $port = validate($_POST['port'], 'port', '/^(([1-9])|([1-9][0-9])|([1-9][0-9][0-9])|([1-9][0-9][0-9][0-9])|([1-5][0-9][0-9][0-9][0-9])|(6[0-4][0-9][0-9][0-9])|(65[0-4][0-9][0-9])|(655[0-2][0-9])|(6553[0-5]))$/Di', array('stringisempty', 'myport')); - $listen_statement = isset($_POST['listen_statement']) ? 1 : 0; - $namevirtualhost_statement = isset($_POST['namevirtualhost_statement']) ? 1 : 0; - $vhostcontainer = isset($_POST['vhostcontainer']) ? 1 : 0; - $specialsettings = validate(str_replace("\r\n", "\n", $_POST['specialsettings']), 'specialsettings', '/^[^\0]*$/'); - $vhostcontainer_servername_statement = isset($_POST['vhostcontainer_servername_statement']) ? 1 : 0; - $default_vhostconf_domain = validate(str_replace("\r\n", "\n", $_POST['default_vhostconf_domain']), 'default_vhostconf_domain', '/^[^\0]*$/'); - $docroot = validate($_POST['docroot'], 'docroot'); - - $result_checkfordouble_stmt = Database::prepare(" - SELECT `id` FROM `" . TABLE_PANEL_IPSANDPORTS . "` - WHERE `ip` = :ip AND `port` = :port" - ); - $result_checkfordouble = Database::pexecute_first($result_checkfordouble_stmt, array('ip' => $ip, 'port' => $port)); - - $result_sameipotherport_stmt = Database::prepare(" - SELECT `id` FROM `" . TABLE_PANEL_IPSANDPORTS . "` - WHERE `ip` = :ip AND `id` <> :id" - ); - $result_sameipotherport = Database::pexecute_first($result_sameipotherport_stmt, array('ip' => $ip, 'id' => $id)); - - if ((int)Settings::Get('system.use_ssl') == 1 - && isset($_POST['ssl']) - && $_POST['ssl'] != 0 - ) { - $ssl = 1; - $ssl_cert_file = validate($_POST['ssl_cert_file'], 'ssl_cert_file'); - $ssl_key_file = validate($_POST['ssl_key_file'], 'ssl_key_file'); - $ssl_ca_file = validate($_POST['ssl_ca_file'], 'ssl_ca_file'); - $ssl_cert_chainfile = validate($_POST['ssl_cert_chainfile'], 'ssl_cert_chainfile'); - } else { - $ssl = 0; - $ssl_cert_file = ''; - $ssl_key_file = ''; - $ssl_ca_file = ''; - $ssl_cert_chainfile = ''; + if (isset($_POST['send']) && $_POST['send'] == 'send') { + try { + IpsAndPorts::getLocal($userinfo, $_POST)->update(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } - - if ($listen_statement != '1') { - $listen_statement = '0'; - } - - if ($namevirtualhost_statement != '1') { - $namevirtualhost_statement = '0'; - } - - if ($vhostcontainer != '1') { - $vhostcontainer = '0'; - } - - if ($vhostcontainer_servername_statement != '1') { - $vhostcontainer_servername_statement = '0'; - } - - if ($ssl != '1') { - $ssl = '0'; - } - - if ($ssl_cert_file != '') { - $ssl_cert_file = makeCorrectFile($ssl_cert_file); - } - - if ($ssl_key_file != '') { - $ssl_key_file = makeCorrectFile($ssl_key_file); - } - - if ($ssl_ca_file != '') { - $ssl_ca_file = makeCorrectFile($ssl_ca_file); - } - - if ($ssl_cert_chainfile != '') { - $ssl_cert_chainfile = makeCorrectFile($ssl_cert_chainfile); - } - - if (strlen(trim($docroot)) > 0) { - $docroot = makeCorrectDir($docroot); - } else { - $docroot = ''; - } - - if ($result['ip'] != $ip - && $result['ip'] == Settings::Get('system.ipaddress') - && $result_sameipotherport['id'] == '' - ) { - standard_error('cantchangesystemip'); - - } elseif($result_checkfordouble['id'] != '' - && $result_checkfordouble['id'] != $id - ) { - standard_error('myipnotdouble'); - - } else { - - $upd_stmt = Database::prepare(" - UPDATE `" . TABLE_PANEL_IPSANDPORTS . "` - SET - `ip` = :ip, `port` = :port, `listen_statement` = :ls, - `namevirtualhost_statement` = :nvhs, `vhostcontainer` = :vhc, - `vhostcontainer_servername_statement` = :vhcss, - `specialsettings` = :ss, `ssl` = :ssl, - `ssl_cert_file` = :ssl_cert, `ssl_key_file` = :ssl_key, - `ssl_ca_file` = :ssl_ca, `ssl_cert_chainfile` = :ssl_chain, - `default_vhostconf_domain` = :dvhd, `docroot` = :docroot - WHERE `id` = :id; - "); - $upd_data = array( - 'ip' => $ip, - 'port' => $port, - 'ls' => $listen_statement, - 'nvhs' => $namevirtualhost_statement, - 'vhc' => $vhostcontainer, - 'vhcss' => $vhostcontainer_servername_statement, - 'ss' => $specialsettings, - 'ssl' => $ssl, - 'ssl_cert' => $ssl_cert_file, - 'ssl_key' => $ssl_key_file, - 'ssl_ca' => $ssl_ca_file, - 'ssl_chain' => $ssl_cert_chainfile, - 'dvhd' => $default_vhostconf_domain, - 'docroot' => $docroot, - 'id' => $id - ); - Database::pexecute($upd_stmt, $upd_data); - - $log->logAction(ADM_ACTION, LOG_WARNING, "changed IP/port from '" . $result['ip'] . ":" . $result['port'] . "' to '" . $ip . ":" . $port . "'"); - inserttask('1'); - - // Using nameserver, insert a task which rebuilds the server config - inserttask('4'); - - redirectTo($filename, Array('page' => $page, 's' => $s)); - } - + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); } else { - $result = htmlentities_array($result); + $result = \Froxlor\PhpHelper::htmlentitiesArray($result); - $ipsandports_edit_data = include_once dirname(__FILE__).'/lib/formfields/admin/ipsandports/formfield.ipsandports_edit.php'; - $ipsandports_edit_form = htmlform::genHTMLForm($ipsandports_edit_data); + $ipsandports_edit_data = include_once dirname(__FILE__) . '/lib/formfields/admin/ipsandports/formfield.ipsandports_edit.php'; + $ipsandports_edit_form = \Froxlor\UI\HtmlForm::genHTMLForm($ipsandports_edit_data); $title = $ipsandports_edit_data['ipsandports_edit']['title']; $image = $ipsandports_edit_data['ipsandports_edit']['image']; - eval("echo \"" . getTemplate("ipsandports/ipsandports_edit") . "\";"); + 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_logger.php b/admin_logger.php index a409c021..0bdf683f 100644 --- a/admin_logger.php +++ b/admin_logger.php @@ -16,13 +16,12 @@ * @package Panel * */ - define('AREA', 'admin'); require './lib/init.php'; -if ($page == 'log' - && $userinfo['change_serversettings'] == '1' -) { +use Froxlor\Api\Commands\SysLog; + +if ($page == 'log' && $userinfo['change_serversettings'] == '1') { if ($action == '') { $fields = array( 'date' => $lng['logger']['date'], @@ -30,103 +29,104 @@ if ($page == 'log' 'user' => $lng['logger']['user'], 'text' => $lng['logger']['action'] ); - $paging = new paging($userinfo, TABLE_PANEL_LOG, $fields, null, null, 0, 'desc'); - $result_stmt = Database::query(' - SELECT * FROM `' . TABLE_PANEL_LOG . '` ' . $paging->getSqlWhere(false) . ' ' . $paging->getSqlOrderBy() . ' ' . $paging->getSqlLimit() - ); - $logs_count = Database::num_rows(); - $paging->setEntries($logs_count); + try { + // get total count + $json_result = SysLog::getLocal($userinfo)->listingCount(); + $result = json_decode($json_result, true)['data']; + // initialize pagination and filtering + $paging = new \Froxlor\UI\Pagination($userinfo, $fields, $result); + // get list + $json_result = SysLog::getLocal($userinfo, $paging->getApiCommandParams())->listing(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; $sortcode = $paging->getHtmlSortCode($lng); $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); $searchcode = $paging->getHtmlSearchCode($lng); $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); $clog = array(); - while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { - - if (!isset($clog[$row['action']]) - || !is_array($clog[$row['action']]) - ) { + foreach ($result['list'] as $row) { + if (! isset($clog[$row['action']]) || ! is_array($clog[$row['action']])) { $clog[$row['action']] = array(); } $clog[$row['action']][$row['logid']] = $row; } - if ($paging->sortfield == 'date' - && $paging->sortorder == 'desc' - ) { + if ($paging->sortfield == 'date' && $paging->sortorder == 'desc') { krsort($clog); } else { ksort($clog); } - $i = 0; $count = 0; $log_count = 0; $log = ''; foreach ($clog as $action => $logrows) { $_action = 0; foreach ($logrows as $row) { - if ($paging->checkDisplay($i)) { - $row = htmlentities_array($row); - $row['date'] = date("d.m.y H:i:s", $row['date']); + // if ($paging->checkDisplay($i)) { + $row = \Froxlor\PhpHelper::htmlentitiesArray($row); + $row['date'] = date("d.m.y H:i:s", $row['date']); - if ($_action != $action) { - switch ($action) { - case USR_ACTION: - $_action = $lng['admin']['customer']; - break; - case RES_ACTION: - $_action = $lng['logger']['reseller']; - break; - case ADM_ACTION: - $_action = $lng['logger']['admin']; - break; - case CRON_ACTION: - $_action = $lng['logger']['cron']; - break; - case LOGIN_ACTION: - $_action = $lng['logger']['login']; - break; - case LOG_ERROR: - $_action = $lng['logger']['intern']; - break; - default: - $_action = $lng['logger']['unknown']; - break; - } - - $row['action'] = $_action; - eval("\$log.=\"" . getTemplate('logger/logger_action') . "\";"); + if ($_action != $action) { + switch ($action) { + case \Froxlor\FroxlorLogger::USR_ACTION: + $_action = $lng['admin']['customer']; + break; + case \Froxlor\FroxlorLogger::RES_ACTION: + $_action = $lng['logger']['reseller']; + break; + case \Froxlor\FroxlorLogger::ADM_ACTION: + $_action = $lng['logger']['admin']; + break; + case \Froxlor\FroxlorLogger::CRON_ACTION: + $_action = $lng['logger']['cron']; + break; + case \Froxlor\FroxlorLogger::LOGIN_ACTION: + $_action = $lng['logger']['login']; + break; + case \Froxlor\FroxlorLogger::LOG_ERROR: + $_action = $lng['logger']['intern']; + break; + default: + $_action = $lng['logger']['unknown']; + break; } - $log_count++; - $row['type'] = getLogLevelDesc($row['type']); - eval("\$log.=\"" . getTemplate('logger/logger_log') . "\";"); - $count++; - $_action = $action; + $row['action'] = $_action; + eval("\$log.=\"" . \Froxlor\UI\Template::getTemplate('logger/logger_action') . "\";"); } - $i++; + + $log_count ++; + $row['type'] = \Froxlor\FroxlorLogger::getInstanceOf()->getLogLevelDesc($row['type']); + eval("\$log.=\"" . \Froxlor\UI\Template::getTemplate('logger/logger_log') . "\";"); + $count ++; + $_action = $action; } - $i++; } - eval("echo \"" . getTemplate('logger/logger') . "\";"); - + eval("echo \"" . \Froxlor\UI\Template::getTemplate('logger/logger') . "\";"); } elseif ($action == 'truncate') { - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { - $truncatedate = time() - (60 * 10); - $trunc_stmt = Database::prepare(" - DELETE FROM `" . TABLE_PANEL_LOG . "` WHERE `date` < :trunc" - ); - Database::pexecute($trunc_stmt, array('trunc' => $truncatedate)); - $log->logAction(ADM_ACTION, LOG_WARNING, 'truncated the system-log (mysql)'); - redirectTo($filename, array('page' => $page, 's' => $s)); + if (isset($_POST['send']) && $_POST['send'] == 'send') { + try { + SysLog::getLocal($userinfo, array( + 'min_to_keep' => 10 + ))->delete(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); } else { - ask_yesno('logger_reallytruncate', $filename, array('page' => $page, 'action' => $action), TABLE_PANEL_LOG); + \Froxlor\UI\HTML::askYesNo('logger_reallytruncate', $filename, array( + 'page' => $page, + 'action' => $action + ), TABLE_PANEL_LOG); } } } diff --git a/admin_message.php b/admin_message.php index bd7213cf..6f06156b 100644 --- a/admin_message.php +++ b/admin_message.php @@ -16,10 +16,11 @@ * @package Panel * */ - define('AREA', 'admin'); require './lib/init.php'; +use Froxlor\Database\Database; + if (isset($_POST['id'])) { $id = intval($_POST['id']); } elseif (isset($_GET['id'])) { @@ -28,36 +29,33 @@ if (isset($_POST['id'])) { if ($page == 'message') { if ($action == '') { - $log->logAction(ADM_ACTION, LOG_NOTICE, 'viewed panel_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' - ) { - $log->logAction(ADM_ACTION, LOG_NOTICE, 'sending messages to admins'); + if (isset($_POST['send']) && $_POST['send'] == 'send') { + if ($_POST['receipient'] == 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) { if ($userinfo['customers_see_all'] == '1') { - $log->logAction(ADM_ACTION, LOG_NOTICE, 'sending messages to ALL customers'); + $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 . "`"); } else { - $log->logAction(ADM_ACTION, LOG_NOTICE, 'sending messages to customers'); + $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, 'sending messages to customers'); $result = Database::prepare(' SELECT `firstname`, `name`, `company`, `email` FROM `' . TABLE_PANEL_CUSTOMERS . "` - WHERE `adminid` = :adminid" - ); - Database::pexecute($result, array('adminid' => $userinfo['adminid'])); + WHERE `adminid` = :adminid"); + Database::pexecute($result, array( + 'adminid' => $userinfo['adminid'] + )); } } else { - standard_error('noreceipientsgiven'); + \Froxlor\UI\Response::standard_error('noreceipientsgiven'); } $subject = $_POST['subject']; $message = wordwrap($_POST['message'], 70); - if (!empty($message)) { + if (! empty($message)) { $mailcounter = 0; $mail->Body = $message; $mail->Subject = $subject; @@ -66,28 +64,37 @@ if ($page == 'message') { $row['firstname'] = isset($row['firstname']) ? $row['firstname'] : ''; $row['company'] = isset($row['company']) ? $row['company'] : ''; - $mail->AddAddress($row['email'], getCorrectUserSalutation(array('firstname' => $row['firstname'], 'name' => $row['name'], 'company' => $row['company']))); + $mail->AddAddress($row['email'], \Froxlor\User::getCorrectUserSalutation(array( + 'firstname' => $row['firstname'], + 'name' => $row['name'], + 'company' => $row['company'] + ))); $mail->From = $userinfo['email']; $mail->FromName = (isset($userinfo['firstname']) ? $userinfo['firstname'] . ' ' : '') . $userinfo['name']; - if (!$mail->Send()) { + if (! $mail->Send()) { if ($mail->ErrorInfo != '') { $mailerr_msg = $mail->ErrorInfo; } else { $mailerr_msg = $row['email']; } - $log->logAction(ADM_ACTION, LOG_ERR, 'Error sending mail: ' . $mailerr_msg); - standard_error('errorsendingmail', $row['email']); + $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_ERR, 'Error sending mail: ' . $mailerr_msg); + \Froxlor\UI\Response::standard_error('errorsendingmail', $row['email']); } - $mailcounter++; + $mailcounter ++; $mail->ClearAddresses(); } - redirectTo($filename, array('page' => $page, 's' => $s, 'action' => 'showsuccess', 'sentitems' => $mailcounter)); + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s, + 'action' => 'showsuccess', + 'sentitems' => $mailcounter + )); } else { - standard_error('nomessagetosend'); + \Froxlor\UI\Response::standard_error('nomessagetosend'); } } } @@ -95,14 +102,13 @@ if ($page == 'message') { if ($action == 'showsuccess') { $success = 1; - $sentitems = isset($_GET['sentitems']) ? (int)$_GET['sentitems'] : 0; + $sentitems = isset($_GET['sentitems']) ? (int) $_GET['sentitems'] : 0; if ($sentitems == 0) { $successmessage = $lng['message']['noreceipients']; } else { $successmessage = str_replace('%s', $sentitems, $lng['message']['success']); } - } else { $success = 0; $sentitems = 0; @@ -113,9 +119,9 @@ if ($page == 'message') { $receipients = ''; if ($userinfo['customers_see_all'] == '1') { - $receipients.= makeoption($lng['panel']['reseller'], 0); + $receipients .= \Froxlor\UI\HTML::makeoption($lng['panel']['reseller'], 0); } - $receipients .= makeoption($lng['panel']['customer'], 1); - eval("echo \"" . getTemplate('message/message') . "\";"); + $receipients .= \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 7f79d9ec..b6afbb51 100644 --- a/admin_opcacheinfo.php +++ b/admin_opcacheinfo.php @@ -17,142 +17,140 @@ * Based on https://github.com/amnuts/opcache-gui * */ - define('AREA', 'admin'); require './lib/init.php'; - -if ($action == 'reset' && - function_exists('opcache_reset') && - $userinfo['change_serversettings'] == '1' -) { - opcache_reset(); - $log->logAction(ADM_ACTION, LOG_INFO, "reseted OPcache"); - header('Location: ' . $linker->getLink(array('section' => 'opcacheinfo', 'page' => 'showinfo'))); - exit(); +if ($action == 'reset' && function_exists('opcache_reset') && $userinfo['change_serversettings'] == '1') { + opcache_reset(); + $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "reseted OPcache"); + header('Location: ' . $linker->getLink(array( + 'section' => 'opcacheinfo', + 'page' => 'showinfo' + ))); + exit(); } -if (!function_exists('opcache_get_configuration') -) { - standard_error($lng['error']['no_opcacheinfo']); +if (! function_exists('opcache_get_configuration')) { + \Froxlor\UI\Response::standard_error($lng['error']['no_opcacheinfo']); } -if ($page == 'showinfo' -) { - - $opcache_info = opcache_get_configuration(); - $opcache_status = opcache_get_status(false); - $time = time(); - $log->logAction(ADM_ACTION, LOG_NOTICE, "viewed OPcache info"); - - $runtimelines = ''; - if (isset($opcache_info['directives']) && is_array($opcache_info['directives'])) { - foreach ($opcache_info['directives'] as $name => $value) { - $linkname= str_replace('_', '-', $name); - if ($name=='opcache.optimization_level' && is_integer($value)) { - $value='0x'.dechex($value); - } - if ($name=='opcache.memory_consumption' && is_integer($value) && $value%(1024*1024)==0) { - $value=$value/(1024*1024); - } - if ($value===null || $value==='') { - $value=$lng['opcacheinfo']['novalue']; - } - if ($value===true) { - $value=$lng['opcacheinfo']['true']; - } - if ($value===false) { - $value=$lng['opcacheinfo']['false']; - } - if (is_integer($value)) { - $value=number_format($value,0,'.',' '); - } - $name=str_replace('_', ' ', $name); - eval("\$runtimelines.=\"" . getTemplate("settings/opcacheinfo/runtime_line") . "\";"); - } - } - - $cachehits=@$opcache_status['opcache_statistics']['hits'] ?: 0; - $cachemiss=@$opcache_status['opcache_statistics']['misses'] ?: 0; - $blacklistmiss=@$opcache_status['opcache_statistics']['blacklist_misses'] ?: 0; - $cachetotal=$cachehits+$cachemiss+$blacklistmiss; - - $general=array( - 'version' => (isset($opcache_info['version']['opcache_product_name']) ? $opcache_info['version']['opcache_product_name'].' ' : '').$opcache_info['version']['version'], - 'phpversion' => phpversion(), - 'start_time' => @$opcache_status['opcache_statistics']['start_time'] ? date('Y-m-d H:i:s',$opcache_status['opcache_statistics']['start_time']) : '', - 'last_restart_time' => @$opcache_status['opcache_statistics']['last_restart_time'] ? date('Y-m-d H:i:s',$opcache_status['opcache_statistics']['last_restart_time']) : $lng['opcacheinfo']['never'], - 'oom_restarts' => number_format(@$opcache_status['opcache_statistics']['oom_restarts'] ?: 0,0,'.',' '), - 'hash_restarts' => number_format(@$opcache_status['opcache_statistics']['hash_restarts'] ?: 0,0,'.',' '), - 'manual_restarts' => number_format(@$opcache_status['opcache_statistics']['manual_restarts'] ?: 0,0,'.',' '), - 'status' => (@$opcache_status['restart_in_progress'] ? $lng['opcacheinfo']['restartinprogress'] : - (@$opcache_status['restart_pending'] ? $lng['opcacheinfo']['restartpending'] : - (@$opcache_status['cache_full'] ? $lng['opcacheinfo']['cachefull'] : - (@$opcache_status['opcache_enabled'] ? $lng['opcacheinfo']['enabled'] : $lng['opcacheinfo']['novalue'])))), - 'cachedscripts' => number_format(@$opcache_status['opcache_statistics']['num_cached_scripts'] ?: 0,0,'.',' '), - 'cachehits' => number_format($cachehits,0,'.',' ') . ($cachetotal>0 ? sprintf(" (%.1f %%)", $cachehits/($cachetotal)*100) : ''), - 'cachemiss' => number_format($cachemiss,0,'.',' ') . ($cachetotal>0 ? sprintf(" (%.1f %%)", $cachemiss/($cachetotal)*100) : ''), - 'blacklistmiss' => number_format($blacklistmiss,0,'.',' ') . ($cachetotal>0 ? sprintf(" (%.1f %%)", $blacklistmiss/($cachetotal)*100) : ''), - ); - - $usedmem=@$opcache_status['memory_usage']['used_memory'] ?: 0; - $usedmemstr=bsize($usedmem); - $freemem=@$opcache_status['memory_usage']['free_memory'] ?: 0; - $freememstr=bsize($freemem); - $totalmem=$usedmem+$freemem; - $wastedmem=@$opcache_status['memory_usage']['wasted_memory'] ?: 0; - $wastedmemstr=bsize($wastedmem); - if ($totalmem) { - $memory=array( - 'total' => bsize($totalmem), - 'used' => $usedmemstr . ($totalmem>0 ? sprintf(" (%.1f %%)", $usedmem/($totalmem)*100) : ''), - 'free' => $freememstr . ($totalmem>0 ? sprintf(" (%.1f %%)", $freemem/($totalmem)*100) : ''), - 'wasted' => $wastedmemstr . ($totalmem>0 ? sprintf(" (%.1f %%)", $wastedmem/($totalmem)*100) : ''), - ); - } - - if (isset($opcache_status['interned_strings_usage'])) { - $usedstring=@$opcache_status['interned_strings_usage']['used_memory'] ?: 0; - $usedstringstr=bsize($usedstring); - $freestring=@$opcache_status['interned_strings_usage']['free_memory'] ?: 0; - $freestringstr=bsize($freestring); - $totalstring=$usedstring+$freestring; - $stringbuffer=array( - 'total' => bsize($totalstring), - 'used' => $usedstringstr . ($totalstring>0 ? sprintf(" (%.1f %%)", $usedstring/$totalstring*100) : ''), - 'free' => $freestringstr . ($totalstring>0 ? sprintf(" (%.1f %%)", $freestring/$totalstring*100) : ''), - 'strcount' => number_format(@$opcache_status['interned_strings_usage']['number_of_strings'] ?: 0,0,'.',' '), - ); - } +if ($page == 'showinfo') { - $usedkey=@$opcache_status['opcache_statistics']['num_cached_keys'] ?: 0; - $usedkeystr=number_format($usedkey,0,'.',' '); - $totalkey=@$opcache_status['opcache_statistics']['max_cached_keys'] ?: 0; - $wastedkey=$usedkey - (@$opcache_status['opcache_statistics']['num_cached_scripts'] ?: 0); - if (isset($opcache_status['opcache_statistics'])) { - $keystat=array( - 'total' => number_format($totalkey,0,'.',' '), - 'used' => $usedkeystr . ($totalkey>0 ? sprintf(" (%.1f %%)", $usedkey/($totalkey)*100) : ''), - 'wasted' => number_format($wastedkey,0,'.',' ') . ($totalkey>0 ? sprintf(" (%.1f %%)", $wastedkey/($totalkey)*100) : ''), - ); - } - - $blacklistlines = ''; - if (isset($opcache_info['blacklist']) && is_array($opcache_info['blacklist'])) { - foreach ($opcache_info['blacklist'] as $value) { - eval("\$blacklistlines.=\"" . getTemplate("settings/opcacheinfo/blacklist_line") . "\";"); - } - } - - eval("echo \"" . getTemplate("settings/opcacheinfo/showinfo") . "\";"); - + $opcache_info = opcache_get_configuration(); + $opcache_status = opcache_get_status(false); + $time = time(); + $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "viewed OPcache info"); + + $runtimelines = ''; + if (isset($opcache_info['directives']) && is_array($opcache_info['directives'])) { + foreach ($opcache_info['directives'] as $name => $value) { + $linkname = str_replace('_', '-', $name); + if ($name == 'opcache.optimization_level' && is_integer($value)) { + $value = '0x' . dechex($value); + } + if ($name == 'opcache.memory_consumption' && is_integer($value) && $value % (1024 * 1024) == 0) { + $value = $value / (1024 * 1024); + } + if ($value === null || $value === '') { + $value = $lng['opcacheinfo']['novalue']; + } + if ($value === true) { + $value = $lng['opcacheinfo']['true']; + } + if ($value === false) { + $value = $lng['opcacheinfo']['false']; + } + if (is_integer($value)) { + $value = number_format($value, 0, '.', ' '); + } + $name = str_replace('_', ' ', $name); + eval("\$runtimelines.=\"" . \Froxlor\UI\Template::getTemplate("settings/opcacheinfo/runtime_line") . "\";"); + } + } + + $cachehits = @$opcache_status['opcache_statistics']['hits'] ?: 0; + $cachemiss = @$opcache_status['opcache_statistics']['misses'] ?: 0; + $blacklistmiss = @$opcache_status['opcache_statistics']['blacklist_misses'] ?: 0; + $cachetotal = $cachehits + $cachemiss + $blacklistmiss; + + $general = array( + 'version' => (isset($opcache_info['version']['opcache_product_name']) ? $opcache_info['version']['opcache_product_name'] . ' ' : '') . $opcache_info['version']['version'], + 'phpversion' => phpversion(), + 'start_time' => @$opcache_status['opcache_statistics']['start_time'] ? date('Y-m-d H:i:s', $opcache_status['opcache_statistics']['start_time']) : '', + 'last_restart_time' => @$opcache_status['opcache_statistics']['last_restart_time'] ? date('Y-m-d H:i:s', $opcache_status['opcache_statistics']['last_restart_time']) : $lng['opcacheinfo']['never'], + 'oom_restarts' => number_format(@$opcache_status['opcache_statistics']['oom_restarts'] ?: 0, 0, '.', ' '), + 'hash_restarts' => number_format(@$opcache_status['opcache_statistics']['hash_restarts'] ?: 0, 0, '.', ' '), + 'manual_restarts' => number_format(@$opcache_status['opcache_statistics']['manual_restarts'] ?: 0, 0, '.', ' '), + 'status' => (@$opcache_status['restart_in_progress'] ? $lng['opcacheinfo']['restartinprogress'] : (@$opcache_status['restart_pending'] ? $lng['opcacheinfo']['restartpending'] : (@$opcache_status['cache_full'] ? $lng['opcacheinfo']['cachefull'] : (@$opcache_status['opcache_enabled'] ? $lng['opcacheinfo']['enabled'] : $lng['opcacheinfo']['novalue'])))), + 'cachedscripts' => number_format(@$opcache_status['opcache_statistics']['num_cached_scripts'] ?: 0, 0, '.', ' '), + 'cachehits' => number_format($cachehits, 0, '.', ' ') . ($cachetotal > 0 ? sprintf(" (%.1f %%)", $cachehits / ($cachetotal) * 100) : ''), + 'cachemiss' => number_format($cachemiss, 0, '.', ' ') . ($cachetotal > 0 ? sprintf(" (%.1f %%)", $cachemiss / ($cachetotal) * 100) : ''), + 'blacklistmiss' => number_format($blacklistmiss, 0, '.', ' ') . ($cachetotal > 0 ? sprintf(" (%.1f %%)", $blacklistmiss / ($cachetotal) * 100) : '') + ); + + $usedmem = @$opcache_status['memory_usage']['used_memory'] ?: 0; + $usedmemstr = bsize($usedmem); + $freemem = @$opcache_status['memory_usage']['free_memory'] ?: 0; + $freememstr = bsize($freemem); + $totalmem = $usedmem + $freemem; + $wastedmem = @$opcache_status['memory_usage']['wasted_memory'] ?: 0; + $wastedmemstr = bsize($wastedmem); + if ($totalmem) { + $memory = array( + 'total' => bsize($totalmem), + 'used' => $usedmemstr . ($totalmem > 0 ? sprintf(" (%.1f %%)", $usedmem / ($totalmem) * 100) : ''), + 'free' => $freememstr . ($totalmem > 0 ? sprintf(" (%.1f %%)", $freemem / ($totalmem) * 100) : ''), + 'wasted' => $wastedmemstr . ($totalmem > 0 ? sprintf(" (%.1f %%)", $wastedmem / ($totalmem) * 100) : '') + ); + } + + if (isset($opcache_status['interned_strings_usage'])) { + $usedstring = @$opcache_status['interned_strings_usage']['used_memory'] ?: 0; + $usedstringstr = bsize($usedstring); + $freestring = @$opcache_status['interned_strings_usage']['free_memory'] ?: 0; + $freestringstr = bsize($freestring); + $totalstring = $usedstring + $freestring; + $stringbuffer = array( + 'total' => bsize($totalstring), + 'used' => $usedstringstr . ($totalstring > 0 ? sprintf(" (%.1f %%)", $usedstring / $totalstring * 100) : ''), + 'free' => $freestringstr . ($totalstring > 0 ? sprintf(" (%.1f %%)", $freestring / $totalstring * 100) : ''), + 'strcount' => number_format(@$opcache_status['interned_strings_usage']['number_of_strings'] ?: 0, 0, '.', ' ') + ); + } + + $usedkey = @$opcache_status['opcache_statistics']['num_cached_keys'] ?: 0; + $usedkeystr = number_format($usedkey, 0, '.', ' '); + $totalkey = @$opcache_status['opcache_statistics']['max_cached_keys'] ?: 0; + $wastedkey = $usedkey - (@$opcache_status['opcache_statistics']['num_cached_scripts'] ?: 0); + if (isset($opcache_status['opcache_statistics'])) { + $keystat = array( + 'total' => number_format($totalkey, 0, '.', ' '), + 'used' => $usedkeystr . ($totalkey > 0 ? sprintf(" (%.1f %%)", $usedkey / ($totalkey) * 100) : ''), + 'wasted' => number_format($wastedkey, 0, '.', ' ') . ($totalkey > 0 ? sprintf(" (%.1f %%)", $wastedkey / ($totalkey) * 100) : '') + ); + } + + $blacklistlines = ''; + if (isset($opcache_info['blacklist']) && is_array($opcache_info['blacklist'])) { + foreach ($opcache_info['blacklist'] as $value) { + eval("\$blacklistlines.=\"" . \Froxlor\UI\Template::getTemplate("settings/opcacheinfo/blacklist_line") . "\";"); + } + } + + eval("echo \"" . \Froxlor\UI\Template::getTemplate("settings/opcacheinfo/showinfo") . "\";"); } -function bsize($s) { - foreach (array('', 'K', 'M', 'G') as $i => $k) { - if ($s < 1024) - break; - $s/=1024; - } - return sprintf("%5.1f %sBytes", $s, $k); +function bsize($s) +{ + foreach (array( + '', + 'K', + 'M', + 'G' + ) as $i => $k) { + if ($s < 1024) + break; + $s /= 1024; + } + return sprintf("%5.1f %sBytes", $s, $k); } diff --git a/admin_phpsettings.php b/admin_phpsettings.php index 4f7f9824..df09de82 100644 --- a/admin_phpsettings.php +++ b/admin_phpsettings.php @@ -16,10 +16,13 @@ * @package Panel * */ - define('AREA', 'admin'); require './lib/init.php'; +use Froxlor\Database\Database; +use Froxlor\Api\Commands\PhpSettings as PhpSettings; +use Froxlor\Api\Commands\FpmDaemons as FpmDaemons; + if (isset($_POST['id'])) { $id = intval($_POST['id']); } elseif (isset($_GET['id'])) { @@ -30,315 +33,310 @@ if ($page == 'overview') { if ($action == '') { + try { + $json_result = PhpSettings::getLocal($userinfo, array( + 'with_subdomains' => true + ))->listing(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; + $tablecontent = ''; $count = 0; - $result = Database::query("SELECT * FROM `" . TABLE_PANEL_PHPCONFIGS . "`"); - - while ($row = $result->fetch(PDO::FETCH_ASSOC)) { - - $domainresult = false; - $query_params = array('id' => $row['id']); - - $query = "SELECT * FROM `".TABLE_PANEL_DOMAINS."` - WHERE `phpsettingid` = :id - AND `parentdomainid` = '0'"; - - if ((int)$userinfo['domains_see_all'] == 0) { - $query .= " AND `adminid` = :adminid"; - $query_params['adminid'] = $userinfo['adminid']; - } - - if ((int)Settings::Get('panel.phpconfigs_hidestdsubdomain') == 1) { - $ssdids_res = Database::query(" - SELECT DISTINCT `standardsubdomain` FROM `".TABLE_PANEL_CUSTOMERS."` - WHERE `standardsubdomain` > 0 ORDER BY `standardsubdomain` ASC;" - ); - $ssdids = array(); - while ($ssd = $ssdids_res->fetch(PDO::FETCH_ASSOC)) { - $ssdids[] = $ssd['standardsubdomain']; + if (isset($result['count']) && $result['count'] > 0) { + foreach ($result['list'] as $row) { + if (isset($row['is_default']) && $row['is_default'] == true) { + $row['description'] = "" . $row['description'] . ""; } - if (count($ssdids) > 0) { - $query .= " AND `id` NOT IN (".implode(', ', $ssdids).")"; + $domains = ""; + $subdomains_count = count($row['subdomains']); + foreach ($row['domains'] as $configdomain) { + $domains .= $idna_convert->decode($configdomain) . "
"; } - } - - $domainresult_stmt = Database::prepare($query); - Database::pexecute($domainresult_stmt, $query_params); - - $domains = ''; - if (Database::num_rows() > 0) { - while ($row2 = $domainresult_stmt->fetch(PDO::FETCH_ASSOC)) { - $domains.= $row2['domain'] . '
'; + $count ++; + if ($subdomains_count == 0 && empty($domains)) { + $domains = $lng['admin']['phpsettings']['notused']; } + eval("\$tablecontent.=\"" . \Froxlor\UI\Template::getTemplate("phpconfig/overview_overview") . "\";"); } - - // check whether we use that config as froxor-vhost config - if (Settings::Get('system.mod_fcgid_defaultini_ownvhost') == $row['id'] - || Settings::Get('phpfpm.vhost_defaultini') == $row['id'] - ) { - $domains .= Settings::Get('system.hostname'); - } - - if ($domains == '') { - $domains = $lng['admin']['phpsettings']['notused']; - } - - // check whether this is our default config - if ((Settings::Get('system.mod_fcgid') == '1' - && Settings::Get('system.mod_fcgid_defaultini') == $row['id']) - || (Settings::Get('phpfpm.enabled') == '1' - && Settings::Get('phpfpm.defaultini') == $row['id']) - ) { - $row['description'] = ''.$row['description'].''; - } - - $count ++; - eval("\$tablecontent.=\"" . getTemplate("phpconfig/overview_overview") . "\";"); } - $log->logAction(ADM_ACTION, LOG_INFO, "php.ini setting overview has been viewed by '" . $userinfo['loginname'] . "'"); - eval("echo \"" . getTemplate("phpconfig/overview") . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("phpconfig/overview") . "\";"); } if ($action == 'add') { - if ((int)$userinfo['change_serversettings'] == 1) { + if ((int) $userinfo['change_serversettings'] == 1) { - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { - $description = validate($_POST['description'], 'description'); - $phpsettings = validate(str_replace("\r\n", "\n", $_POST['phpsettings']), 'phpsettings', '/^[^\0]*$/'); - - if (Settings::Get('system.mod_fcgid') == 1) { - $binary = makeCorrectFile(validate($_POST['binary'], 'binary')); - $file_extensions = validate($_POST['file_extensions'], 'file_extensions', '/^[a-zA-Z0-9\s]*$/'); - $mod_fcgid_starter = validate($_POST['mod_fcgid_starter'], 'mod_fcgid_starter', '/^[0-9]*$/', '', array('-1', '')); - $mod_fcgid_maxrequests = validate($_POST['mod_fcgid_maxrequests'], 'mod_fcgid_maxrequests', '/^[0-9]*$/', '', array('-1', '')); - $mod_fcgid_umask = validate($_POST['mod_fcgid_umask'], 'mod_fcgid_umask', '/^[0-9]*$/'); - // disable fpm stuff - $fpm_enableslowlog = 0; - $fpm_reqtermtimeout = 0; - $fpm_reqslowtimeout = 0; + if (isset($_POST['send']) && $_POST['send'] == 'send') { + try { + PhpSettings::getLocal($userinfo, $_POST)->add(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } - elseif (Settings::Get('phpfpm.enabled') == 1) { - $fpm_enableslowlog = isset($_POST['phpfpm_enable_slowlog']) ? (int)$_POST['phpfpm_enable_slowlog'] : 0; - $fpm_reqtermtimeout = validate($_POST['phpfpm_reqtermtimeout'], 'phpfpm_reqtermtimeout', '/^([0-9]+)(|s|m|h|d)$/'); - $fpm_reqslowtimeout = validate($_POST['phpfpm_reqslowtimeout'], 'phpfpm_reqslowtimeout', '/^([0-9]+)(|s|m|h|d)$/'); - // disable fcgid stuff - $binary = '/usr/bin/php-cgi'; - $file_extensions = 'php'; - $mod_fcgid_starter = 0; - $mod_fcgid_maxrequests = 0; - $mod_fcgid_umask = "022"; - } - - if (strlen($description) == 0 - || strlen($description) > 50 - ) { - standard_error('descriptioninvalid'); - } - - $ins_stmt = Database::prepare(" - INSERT INTO `" . TABLE_PANEL_PHPCONFIGS . "` SET - `description` = :desc, - `binary` = :binary, - `file_extensions` = :fext, - `mod_fcgid_starter` = :starter, - `mod_fcgid_maxrequests` = :mreq, - `mod_fcgid_umask` = :umask, - `fpm_slowlog` = :fpmslow, - `fpm_reqterm` = :fpmreqterm, - `fpm_reqslow` = :fpmreqslow, - `phpsettings` = :phpsettings" - ); - $ins_data = array( - 'desc' => $description, - 'binary' => $binary, - 'fext' => $file_extensions, - 'starter' => $mod_fcgid_starter, - 'mreq' => $mod_fcgid_maxrequests, - 'umask' => $mod_fcgid_umask, - 'fpmslow' => $fpm_enableslowlog, - 'fpmreqterm' => $fpm_reqtermtimeout, - 'fpmreqslow' => $fpm_reqslowtimeout, - 'phpsettings' => $phpsettings - ); - Database::pexecute($ins_stmt, $ins_data); - - inserttask('1'); - $log->logAction(ADM_ACTION, LOG_INFO, "php.ini setting with description '" . $description . "' has been created by '" . $userinfo['loginname'] . "'"); - redirectTo($filename, array('page' => $page, 's' => $s)); - + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); } else { - $result_stmt = Database::query("SELECT * FROM `" . TABLE_PANEL_PHPCONFIGS . "` WHERE `id` = 1"); - $result = $result_stmt->fetch(PDO::FETCH_ASSOC); + if (file_exists(\Froxlor\Froxlor::getInstallDir() . '/templates/misc/php/default.ini.php')) { + require_once \Froxlor\Froxlor::getInstallDir() . '/templates/misc/php/default.ini.php'; + $result = [ + 'phpsettings' => DEFAULT_PHPINI + ]; + } else { + // use first php-config as fallback + $result_stmt = Database::query("SELECT * FROM `" . TABLE_PANEL_PHPCONFIGS . "` WHERE `id` = 1"); + $result = $result_stmt->fetch(PDO::FETCH_ASSOC); + } - $phpconfig_add_data = include_once dirname(__FILE__).'/lib/formfields/admin/phpconfig/formfield.phpconfig_add.php'; - $phpconfig_add_form = htmlform::genHTMLForm($phpconfig_add_data); + $fpmconfigs = ''; + $configs = Database::query("SELECT * FROM `" . TABLE_PANEL_FPMDAEMONS . "` ORDER BY `description` ASC"); + while ($row = $configs->fetch(PDO::FETCH_ASSOC)) { + $fpmconfigs .= \Froxlor\UI\HTML::makeoption($row['description'], $row['id'], 1, true, true); + } + + $pm_select = \Froxlor\UI\HTML::makeoption('static', 'static', 'dynamic', true, true); + $pm_select .= \Froxlor\UI\HTML::makeoption('dynamic', 'dynamic', 'dynamic', true, true); + $pm_select .= \Froxlor\UI\HTML::makeoption('ondemand', 'ondemand', 'dynamic', true, true); + + $phpconfig_add_data = include_once dirname(__FILE__) . '/lib/formfields/admin/phpconfig/formfield.phpconfig_add.php'; + $phpconfig_add_form = \Froxlor\UI\HtmlForm::genHTMLForm($phpconfig_add_data); $title = $phpconfig_add_data['phpconfig_add']['title']; $image = $phpconfig_add_data['phpconfig_add']['image']; - eval("echo \"" . getTemplate("phpconfig/overview_add") . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("phpconfig/overview_add") . "\";"); } - } else { - standard_error('nopermissionsorinvalidid'); + \Froxlor\UI\Response::standard_error('nopermissionsorinvalidid'); } } if ($action == 'delete') { - $result_stmt = Database::prepare(" - SELECT * FROM `" . TABLE_PANEL_PHPCONFIGS . "` WHERE `id` = :id" - ); - $result = Database::pexecute_first($result_stmt, array('id' => $id)); - - if ((Settings::Get('system.mod_fcgid') == '1' - && Settings::Get('system.mod_fcgid_defaultini_ownvhost') == $id) - || (Settings::Get('phpfpm.enabled') == '1' - && Settings::Get('phpfpm.vhost_defaultini') == $id) - ) { - standard_error('cannotdeletehostnamephpconfig'); + try { + $json_result = PhpSettings::getLocal($userinfo, array( + 'id' => $id + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } + $result = json_decode($json_result, true)['data']; - if ((Settings::Get('system.mod_fcgid') == '1' - && Settings::Get('system.mod_fcgid_defaultini') == $id) - || (Settings::Get('phpfpm.enabled') == '1' - && Settings::Get('phpfpm.defaultini') == $id) - ) { - standard_error('cannotdeletedefaultphpconfig'); - } - - if ($result['id'] != 0 - && $result['id'] == $id - && (int)$userinfo['change_serversettings'] == 1 - && $id != 1 // cannot delete the default php.config - ) { - - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { - // set php-config to default for all domains using the - // config that is to be deleted - $upd_stmt = Database::prepare(" - UPDATE `" . TABLE_PANEL_DOMAINS . "` SET - `phpsettingid` = '1' WHERE `phpsettingid` = :id" - ); - Database::pexecute($upd_stmt, array('id' => $id)); - - $del_stmt = Database::prepare(" - DELETE FROM `" . TABLE_PANEL_PHPCONFIGS . "` WHERE `id` = :id" - ); - Database::pexecute($del_stmt, array('id' => $id)); - - inserttask('1'); - $log->logAction(ADM_ACTION, LOG_INFO, "php.ini setting with id #" . (int)$id . " has been deleted by '" . $userinfo['loginname'] . "'"); - redirectTo($filename, array('page' => $page, 's' => $s)); + if ($result['id'] != 0 && $result['id'] == $id && (int) $userinfo['change_serversettings'] == 1 && $id != 1) // cannot delete the default php.config + { + if (isset($_POST['send']) && $_POST['send'] == 'send') { + try { + PhpSettings::getLocal($userinfo, array( + 'id' => $id + ))->delete(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); } else { - ask_yesno('phpsetting_reallydelete', $filename, array('id' => $id, 'page' => $page, 'action' => $action), $result['description']); + \Froxlor\UI\HTML::askYesNo('phpsetting_reallydelete', $filename, array( + 'id' => $id, + 'page' => $page, + 'action' => $action + ), $result['description']); } } else { - standard_error('nopermissionsorinvalidid'); + \Froxlor\UI\Response::standard_error('nopermissionsorinvalidid'); } } if ($action == 'edit') { - $result_stmt = Database::prepare(" - SELECT * FROM `" . TABLE_PANEL_PHPCONFIGS . "` WHERE `id` = :id" - ); - $result = Database::pexecute_first($result_stmt, array('id' => $id)); + try { + $json_result = PhpSettings::getLocal($userinfo, array( + 'id' => $id + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; - if ($result['id'] != 0 - && $result['id'] == $id - && (int)$userinfo['change_serversettings'] == 1 - ) { + if ($result['id'] != 0 && $result['id'] == $id && (int) $userinfo['change_serversettings'] == 1) { - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { - $description = validate($_POST['description'], 'description'); - $phpsettings = validate(str_replace("\r\n", "\n", $_POST['phpsettings']), 'phpsettings', '/^[^\0]*$/'); - - if (Settings::Get('system.mod_fcgid') == 1) { - $binary = makeCorrectFile(validate($_POST['binary'], 'binary')); - $file_extensions = validate($_POST['file_extensions'], 'file_extensions', '/^[a-zA-Z0-9\s]*$/'); - $mod_fcgid_starter = validate($_POST['mod_fcgid_starter'], 'mod_fcgid_starter', '/^[0-9]*$/', '', array('-1', '')); - $mod_fcgid_maxrequests = validate($_POST['mod_fcgid_maxrequests'], 'mod_fcgid_maxrequests', '/^[0-9]*$/', '', array('-1', '')); - $mod_fcgid_umask = validate($_POST['mod_fcgid_umask'], 'mod_fcgid_umask', '/^[0-9]*$/'); - // disable fpm stuff - $fpm_enableslowlog = 0; - $fpm_reqtermtimeout = 0; - $fpm_reqslowtimeout = 0; + if (isset($_POST['send']) && $_POST['send'] == 'send') { + try { + PhpSettings::getLocal($userinfo, $_POST)->update(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } - elseif (Settings::Get('phpfpm.enabled') == 1) { - $fpm_enableslowlog = isset($_POST['phpfpm_enable_slowlog']) ? (int)$_POST['phpfpm_enable_slowlog'] : 0; - $fpm_reqtermtimeout = validate($_POST['phpfpm_reqtermtimeout'], 'phpfpm_reqtermtimeout', '/^([0-9]+)(|s|m|h|d)$/'); - $fpm_reqslowtimeout = validate($_POST['phpfpm_reqslowtimeout'], 'phpfpm_reqslowtimeout', '/^([0-9]+)(|s|m|h|d)$/'); - // disable fcgid stuff - $binary = '/usr/bin/php-cgi'; - $file_extensions = 'php'; - $mod_fcgid_starter = 0; - $mod_fcgid_maxrequests = 0; - $mod_fcgid_umask = "022"; - } - - if (strlen($description) == 0 - || strlen($description) > 50 - ) { - standard_error('descriptioninvalid'); - } - - $upd_stmt = Database::prepare(" - UPDATE `" . TABLE_PANEL_PHPCONFIGS . "` SET - `description` = :desc, - `binary` = :binary, - `file_extensions` = :fext, - `mod_fcgid_starter` = :starter, - `mod_fcgid_maxrequests` = :mreq, - `mod_fcgid_umask` = :umask, - `fpm_slowlog` = :fpmslow, - `fpm_reqterm` = :fpmreqterm, - `fpm_reqslow` = :fpmreqslow, - `phpsettings` = :phpsettings - WHERE `id` = :id" - ); - $upd_data = array( - 'desc' => $description, - 'binary' => $binary, - 'fext' => $file_extensions, - 'starter' => $mod_fcgid_starter, - 'mreq' => $mod_fcgid_maxrequests, - 'umask' => $mod_fcgid_umask, - 'fpmslow' => $fpm_enableslowlog, - 'fpmreqterm' => $fpm_reqtermtimeout, - 'fpmreqslow' => $fpm_reqslowtimeout, - 'phpsettings' => $phpsettings, - 'id' => $id - ); - Database::pexecute($upd_stmt, $upd_data); - - inserttask('1'); - $log->logAction(ADM_ACTION, LOG_INFO, "php.ini setting with description '" . $description . "' has been changed by '" . $userinfo['loginname'] . "'"); - redirectTo($filename, array('page' => $page, 's' => $s)); - + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); } else { - $phpconfig_edit_data = include_once dirname(__FILE__).'/lib/formfields/admin/phpconfig/formfield.phpconfig_edit.php'; - $phpconfig_edit_form = htmlform::genHTMLForm($phpconfig_edit_data); + $fpmconfigs = ''; + $configs = Database::query("SELECT * FROM `" . TABLE_PANEL_FPMDAEMONS . "` ORDER BY `description` ASC"); + while ($row = $configs->fetch(PDO::FETCH_ASSOC)) { + $fpmconfigs .= \Froxlor\UI\HTML::makeoption($row['description'], $row['id'], $result['fpmsettingid'], true, true); + } + + $pm_select = \Froxlor\UI\HTML::makeoption('static', 'static', $result['pm'], true, true); + $pm_select .= \Froxlor\UI\HTML::makeoption('dynamic', 'dynamic', $result['pm'], true, true); + $pm_select .= \Froxlor\UI\HTML::makeoption('ondemand', 'ondemand', $result['pm'], true, true); + + $phpconfig_edit_data = include_once dirname(__FILE__) . '/lib/formfields/admin/phpconfig/formfield.phpconfig_edit.php'; + $phpconfig_edit_form = \Froxlor\UI\HtmlForm::genHTMLForm($phpconfig_edit_data); $title = $phpconfig_edit_data['phpconfig_edit']['title']; $image = $phpconfig_edit_data['phpconfig_edit']['image']; - eval("echo \"" . getTemplate("phpconfig/overview_edit") . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("phpconfig/overview_edit") . "\";"); } - } else { - standard_error('nopermissionsorinvalidid'); + \Froxlor\UI\Response::standard_error('nopermissionsorinvalidid'); + } + } +} elseif ($page == 'fpmdaemons') { + + if ($action == '') { + + try { + $json_result = FpmDaemons::getLocal($userinfo)->listing(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; + + $tablecontent = ''; + $count = 0; + if (isset($result['count']) && $result['count'] > 0) { + foreach ($result['list'] as $row) { + $configs = ""; + foreach ($row['configs'] as $configused) { + $configs .= $configused . "
"; + } + $count ++; + eval("\$tablecontent.=\"" . \Froxlor\UI\Template::getTemplate("phpconfig/fpmdaemons_overview") . "\";"); + } + } + eval("echo \"" . \Froxlor\UI\Template::getTemplate("phpconfig/fpmdaemons") . "\";"); + } + + if ($action == 'add') { + + if ((int) $userinfo['change_serversettings'] == 1) { + + if (isset($_POST['send']) && $_POST['send'] == 'send') { + try { + FpmDaemons::getLocal($userinfo, $_POST)->add(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); + } else { + + $pm_select = \Froxlor\UI\HTML::makeoption('static', 'static', 'dynamic', true, true); + $pm_select .= \Froxlor\UI\HTML::makeoption('dynamic', 'dynamic', 'dynamic', true, true); + $pm_select .= \Froxlor\UI\HTML::makeoption('ondemand', 'ondemand', 'dynamic', true, true); + + $fpmconfig_add_data = include_once dirname(__FILE__) . '/lib/formfields/admin/phpconfig/formfield.fpmconfig_add.php'; + $fpmconfig_add_form = \Froxlor\UI\HtmlForm::genHTMLForm($fpmconfig_add_data); + + $title = $fpmconfig_add_data['fpmconfig_add']['title']; + $image = $fpmconfig_add_data['fpmconfig_add']['image']; + + eval("echo \"" . \Froxlor\UI\Template::getTemplate("phpconfig/fpmconfig_add") . "\";"); + } + } else { + \Froxlor\UI\Response::standard_error('nopermissionsorinvalidid'); + } + } + + if ($action == 'delete') { + + try { + $json_result = FpmDaemons::getLocal($userinfo, array( + 'id' => $id + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; + + if ($id == 1) { + \Froxlor\UI\Response::standard_error('cannotdeletedefaultphpconfig'); + } + + if ($result['id'] != 0 && $result['id'] == $id && (int) $userinfo['change_serversettings'] == 1 && $id != 1) // cannot delete the default php.config + { + if (isset($_POST['send']) && $_POST['send'] == 'send') { + try { + FpmDaemons::getLocal($userinfo, $_POST)->delete(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); + } else { + \Froxlor\UI\HTML::askYesNo('fpmsetting_reallydelete', $filename, array( + 'id' => $id, + 'page' => $page, + 'action' => $action + ), $result['description']); + } + } else { + \Froxlor\UI\Response::standard_error('nopermissionsorinvalidid'); + } + } + + if ($action == 'edit') { + + try { + $json_result = FpmDaemons::getLocal($userinfo, array( + 'id' => $id + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; + + if ($result['id'] != 0 && $result['id'] == $id && (int) $userinfo['change_serversettings'] == 1) { + + if (isset($_POST['send']) && $_POST['send'] == 'send') { + try { + FpmDaemons::getLocal($userinfo, $_POST)->update(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); + } else { + + $pm_select = \Froxlor\UI\HTML::makeoption('static', 'static', $result['pm'], true, true); + $pm_select .= \Froxlor\UI\HTML::makeoption('dynamic', 'dynamic', $result['pm'], true, true); + $pm_select .= \Froxlor\UI\HTML::makeoption('ondemand', 'ondemand', $result['pm'], true, true); + + $fpmconfig_edit_data = include_once dirname(__FILE__) . '/lib/formfields/admin/phpconfig/formfield.fpmconfig_edit.php'; + $fpmconfig_edit_form = \Froxlor\UI\HtmlForm::genHTMLForm($fpmconfig_edit_data); + + $title = $fpmconfig_edit_data['fpmconfig_edit']['title']; + $image = $fpmconfig_edit_data['fpmconfig_edit']['image']; + + eval("echo \"" . \Froxlor\UI\Template::getTemplate("phpconfig/fpmconfig_edit") . "\";"); + } + } else { + \Froxlor\UI\Response::standard_error('nopermissionsorinvalidid'); } } } diff --git a/admin_plans.php b/admin_plans.php new file mode 100644 index 00000000..69448c1d --- /dev/null +++ b/admin_plans.php @@ -0,0 +1,322 @@ + (2010-) + * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt + * @package Panel + * + */ +define('AREA', 'admin'); +require './lib/init.php'; + +use Froxlor\Api\Commands\HostingPlans; +use Froxlor\Database\Database; +use Froxlor\Settings; + +if (isset($_POST['id'])) { + $id = intval($_POST['id']); +} elseif (isset($_GET['id'])) { + $id = intval($_GET['id']); +} + +if ($page == '' || $page == 'overview') { + + if ($action == '') { + + $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "viewed admin_plans"); + $fields = array( + 'p.name' => $lng['admin']['plans']['name'], + 'p.description' => $lng['admin']['plans']['description'], + 'adminname' => $lng['admin']['admin'], + 'p.ts' => $lng['admin']['plans']['last_update'] + ); + try { + // get total count + $json_result = HostingPlans::getLocal($userinfo)->listingCount(); + $result = json_decode($json_result, true)['data']; + // initialize pagination and filtering + $paging = new \Froxlor\UI\Pagination($userinfo, $fields, $result); + // get list + $json_result = HostingPlans::getLocal($userinfo, $paging->getApiCommandParams())->listing(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; + + $plans = ''; + $sortcode = $paging->getHtmlSortCode($lng); + $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); + $searchcode = $paging->getHtmlSearchCode($lng); + $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); + $count = 0; + + foreach ($result['list'] as $row) { + $row = \Froxlor\PhpHelper::htmlentitiesArray($row); + $row['ts_format'] = date("d.m.Y H:i", $row['ts']); + eval("\$plans.=\"" . \Froxlor\UI\Template::getTemplate("plans/plans_plan") . "\";"); + $count ++; + } + + eval("echo \"" . \Froxlor\UI\Template::getTemplate("plans/plans") . "\";"); + } elseif ($action == 'delete' && $id != 0) { + + try { + $json_result = HostingPlans::getLocal($userinfo, array( + 'id' => $id + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; + + if ($result['id'] != 0 && $result['id'] == $id && (int) $userinfo['adminid'] == $result['adminid']) { + if (isset($_POST['send']) && $_POST['send'] == 'send') { + + try { + HostingPlans::getLocal($userinfo, array( + 'id' => $id + ))->delete(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); + } else { + \Froxlor\UI\HTML::askYesNo('plan_reallydelete', $filename, array( + 'id' => $id, + 'page' => $page, + 'action' => $action + ), $result['name']); + } + } else { + \Froxlor\UI\Response::standard_error('nopermissionsorinvalidid'); + } + } elseif ($action == 'add') { + + if (isset($_POST['send']) && $_POST['send'] == 'send') { + try { + HostingPlans::getLocal($userinfo, $_POST)->add(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); + } else { + + $diskspace_ul = \Froxlor\UI\HTML::makecheckbox('diskspace_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); + $traffic_ul = \Froxlor\UI\HTML::makecheckbox('traffic_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); + $subdomains_ul = \Froxlor\UI\HTML::makecheckbox('subdomains_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); + $emails_ul = \Froxlor\UI\HTML::makecheckbox('emails_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); + $email_accounts_ul = \Froxlor\UI\HTML::makecheckbox('email_accounts_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); + $email_forwarders_ul = \Froxlor\UI\HTML::makecheckbox('email_forwarders_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); + $email_quota_ul = \Froxlor\UI\HTML::makecheckbox('email_quota_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); + $ftps_ul = \Froxlor\UI\HTML::makecheckbox('ftps_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); + $mysqls_ul = \Froxlor\UI\HTML::makecheckbox('mysqls_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true); + + $phpconfigs = array(); + $configs = Database::query(" + SELECT c.*, fc.description as interpreter + FROM `" . TABLE_PANEL_PHPCONFIGS . "` c + LEFT JOIN `" . TABLE_PANEL_FPMDAEMONS . "` fc ON fc.id = c.fpmsettingid + "); + while ($row = $configs->fetch(PDO::FETCH_ASSOC)) { + if ((int) Settings::Get('phpfpm.enabled') == 1) { + $phpconfigs[] = array( + 'label' => $row['description'] . " [" . $row['interpreter'] . "]
", + 'value' => $row['id'] + ); + } else { + $phpconfigs[] = array( + 'label' => $row['description'] . "
", + 'value' => $row['id'] + ); + } + } + + // dummy to avoid unknown variables + $language_options = null; + $gender_options = null; + $hosting_plans = null; + + $plans_add_data = include_once dirname(__FILE__) . '/lib/formfields/admin/plans/formfield.plans_add.php'; + $cust_add_data = include_once dirname(__FILE__) . '/lib/formfields/admin/customer/formfield.customer_add.php'; + // unset unneeded stuff + unset($cust_add_data['customer_add']['sections']['section_a']); + unset($cust_add_data['customer_add']['sections']['section_b']); + unset($cust_add_data['customer_add']['sections']['section_cpre']); + // merge + $plans_add_data['plans_add']['sections'] = array_merge($plans_add_data['plans_add']['sections'], $cust_add_data['customer_add']['sections']); + $plans_add_form = \Froxlor\UI\HtmlForm::genHTMLForm($plans_add_data); + + $title = $plans_add_data['plans_add']['title']; + $image = $plans_add_data['plans_add']['image']; + + eval("echo \"" . \Froxlor\UI\Template::getTemplate("plans/plans_add") . "\";"); + } + } elseif ($action == 'edit' && $id != 0) { + try { + $json_result = HostingPlans::getLocal($userinfo, array( + 'id' => $id + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; + + if ($result['name'] != '') { + + $result['value'] = json_decode($result['value'], true); + $result = \Froxlor\PhpHelper::htmlentitiesArray($result); + + foreach ($result['value'] as $index => $value) { + $result[$index] = $value; + } + $result['allowed_phpconfigs'] = json_encode($result['allowed_phpconfigs']); + + if (isset($_POST['send']) && $_POST['send'] == 'send') { + + try { + HostingPlans::getLocal($userinfo, $_POST)->update(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); + } else { + + $diskspace_ul = \Froxlor\UI\HTML::makecheckbox('diskspace_ul', $lng['customer']['unlimited'], '-1', false, $result['diskspace'], true, true); + if ($result['diskspace'] == '-1') { + $result['diskspace'] = ''; + } + + $traffic_ul = \Froxlor\UI\HTML::makecheckbox('traffic_ul', $lng['customer']['unlimited'], '-1', false, $result['traffic'], true, true); + if ($result['traffic'] == '-1') { + $result['traffic'] = ''; + } + + $subdomains_ul = \Froxlor\UI\HTML::makecheckbox('subdomains_ul', $lng['customer']['unlimited'], '-1', false, $result['subdomains'], true, true); + if ($result['subdomains'] == '-1') { + $result['subdomains'] = ''; + } + + $emails_ul = \Froxlor\UI\HTML::makecheckbox('emails_ul', $lng['customer']['unlimited'], '-1', false, $result['emails'], true, true); + if ($result['emails'] == '-1') { + $result['emails'] = ''; + } + + $email_accounts_ul = \Froxlor\UI\HTML::makecheckbox('email_accounts_ul', $lng['customer']['unlimited'], '-1', false, $result['email_accounts'], true, true); + if ($result['email_accounts'] == '-1') { + $result['email_accounts'] = ''; + } + + $email_forwarders_ul = \Froxlor\UI\HTML::makecheckbox('email_forwarders_ul', $lng['customer']['unlimited'], '-1', false, $result['email_forwarders'], true, true); + if ($result['email_forwarders'] == '-1') { + $result['email_forwarders'] = ''; + } + + $email_quota_ul = \Froxlor\UI\HTML::makecheckbox('email_quota_ul', $lng['customer']['unlimited'], '-1', false, $result['email_quota'], true, true); + if ($result['email_quota'] == '-1') { + $result['email_quota'] = ''; + } + + $ftps_ul = \Froxlor\UI\HTML::makecheckbox('ftps_ul', $lng['customer']['unlimited'], '-1', false, $result['ftps'], true, true); + if ($result['ftps'] == '-1') { + $result['ftps'] = ''; + } + + $mysqls_ul = \Froxlor\UI\HTML::makecheckbox('mysqls_ul', $lng['customer']['unlimited'], '-1', false, $result['mysqls'], true, true); + if ($result['mysqls'] == '-1') { + $result['mysqls'] = ''; + } + + $phpconfigs = array(); + $configs = Database::query(" + SELECT c.*, fc.description as interpreter + FROM `" . TABLE_PANEL_PHPCONFIGS . "` c + LEFT JOIN `" . TABLE_PANEL_FPMDAEMONS . "` fc ON fc.id = c.fpmsettingid + "); + while ($row = $configs->fetch(PDO::FETCH_ASSOC)) { + if ((int) Settings::Get('phpfpm.enabled') == 1) { + $phpconfigs[] = array( + 'label' => $row['description'] . " [" . $row['interpreter'] . "]
", + 'value' => $row['id'] + ); + } else { + $phpconfigs[] = array( + 'label' => $row['description'] . "
", + 'value' => $row['id'] + ); + } + } + + $result['imap'] = $result['email_imap']; + $result['pop3'] = $result['email_pop3']; + + // dummy to avoid unknown variables + $result['loginname'] = null; + $result['documentroot'] = null; + $result['standardsubdomain'] = null; + $result['deactivated'] = null; + $language_options = null; + $result['firstname'] = null; + $gender_options = null; + $result['company'] = null; + $result['street'] = null; + $result['zipcode'] = null; + $result['city'] = null; + $result['phone'] = null; + $result['fax'] = null; + $result['email'] = null; + $result['customernumber'] = null; + $result['custom_notes'] = null; + $result['custom_notes_show'] = null; + $result['api_allowed'] = null; + $hosting_plans = null; + $admin_select_cnt = null; + $admin_select = null; + + $plans_edit_data = include_once dirname(__FILE__) . '/lib/formfields/admin/plans/formfield.plans_edit.php'; + $cust_edit_data = include_once dirname(__FILE__) . '/lib/formfields/admin/customer/formfield.customer_edit.php'; + // unset unneeded stuff + unset($cust_edit_data['customer_edit']['sections']['section_a']); + unset($cust_edit_data['customer_edit']['sections']['section_b']); + unset($cust_edit_data['customer_edit']['sections']['section_cpre']); + // merge + $plans_edit_data['plans_edit']['sections'] = array_merge($plans_edit_data['plans_edit']['sections'], $cust_edit_data['customer_edit']['sections']); + $plans_edit_form = \Froxlor\UI\HtmlForm::genHTMLForm($plans_edit_data); + + $title = $plans_edit_data['plans_edit']['title']; + $image = $plans_edit_data['plans_edit']['image']; + + eval("echo \"" . \Froxlor\UI\Template::getTemplate("plans/plans_edit") . "\";"); + } + } + } elseif ($action == 'jqGetPlanValues') { + $planid = isset($_POST['planid']) ? (int) $_POST['planid'] : 0; + try { + $json_result = HostingPlans::getLocal($userinfo, array( + 'id' => $planid + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; + echo $result['value']; + exit(); + } +} diff --git a/admin_settings.php b/admin_settings.php index e8213225..4e9aba21 100644 --- a/admin_settings.php +++ b/admin_settings.php @@ -16,6 +16,9 @@ * @package Panel * */ +use Froxlor\Database\Database; +use Froxlor\Settings; +use Froxlor\Api\Commands\Froxlor; define('AREA', 'admin'); require './lib/init.php'; @@ -27,12 +30,10 @@ $sql_root = Database::getSqlData(); Database::needRoot(false); if ($page == 'overview' && $userinfo['change_serversettings'] == '1') { - $settings_data = loadConfigArrayDir('./actions/admin/settings/'); - $settings = loadSettings($settings_data); + $settings_data = \Froxlor\PhpHelper::loadConfigArrayDir('./actions/admin/settings/'); + Settings::loadSettingsInto($settings_data); - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { + if (isset($_POST['send']) && $_POST['send'] == 'send') { $_part = isset($_GET['part']) ? $_GET['part'] : ''; if ($_part == '') { @@ -48,38 +49,35 @@ if ($page == 'overview' && $userinfo['change_serversettings'] == '1') { $settings_part = true; } $only_enabledisable = false; - } else { $settings_all = false; $settings_part = false; $only_enabledisable = true; } - + // check if the session timeout is too low #815 - if (isset($_POST['session_sessiontimeout']) - && $_POST['session_sessiontimeout'] < 60 - ) { - standard_error($lng['error']['session_timeout'], $lng['error']['session_timeout_desc']); + if (isset($_POST['session_sessiontimeout']) && $_POST['session_sessiontimeout'] < 60) { + \Froxlor\UI\Response::standard_error($lng['error']['session_timeout'], $lng['error']['session_timeout_desc']); } - if (processFormEx( - $settings_data, - $_POST, - array('filename' => $filename, 'action' => $action, 'page' => $page), - $_part, - $settings_all, - $settings_part, - $only_enabledisable - ) - ) { - $log->logAction(ADM_ACTION, LOG_INFO, "rebuild configfiles due to changed setting"); - inserttask('1'); + if (\Froxlor\UI\Form::processFormEx($settings_data, $_POST, array( + 'filename' => $filename, + 'action' => $action, + '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'); // Using nameserver, insert a task which rebuilds the server config - inserttask('4'); + \Froxlor\System\Cronjob::inserttask('4'); + // cron.d file + \Froxlor\System\Cronjob::inserttask('99'); - standard_success('settingssaved', '', array('filename' => $filename, 'action' => $action, 'page' => $page)); + \Froxlor\UI\Response::standard_success('settingssaved', '', array( + 'filename' => $filename, + 'action' => $action, + 'page' => $page + )); } - } else { $_part = isset($_GET['part']) ? $_GET['part'] : ''; @@ -87,39 +85,36 @@ if ($page == 'overview' && $userinfo['change_serversettings'] == '1') { $_part = isset($_POST['part']) ? $_POST['part'] : ''; } - $fields = buildFormEx($settings_data, $_part); + $fields = \Froxlor\UI\Form::buildFormEx($settings_data, $_part); $settings_page = ''; if ($_part == '') { - eval("\$settings_page .= \"" . getTemplate("settings/settings_overview") . "\";"); + eval("\$settings_page .= \"" . \Froxlor\UI\Template::getTemplate("settings/settings_overview") . "\";"); } else { - eval("\$settings_page .= \"" . getTemplate("settings/settings") . "\";"); + eval("\$settings_page .= \"" . \Froxlor\UI\Template::getTemplate("settings/settings") . "\";"); } - eval("echo \"" . getTemplate("settings/settings_form_begin") . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("settings/settings_form_begin") . "\";"); eval("echo \$settings_page;"); - eval("echo \"" . getTemplate("settings/settings_form_end") . "\";"); - + eval("echo \"" . \Froxlor\UI\Template::getTemplate("settings/settings_form_end") . "\";"); } - -} elseif($page == 'phpinfo' - && $userinfo['change_serversettings'] == '1' -) { +} elseif ($page == 'phpinfo' && $userinfo['change_serversettings'] == '1') { ob_start(); phpinfo(); - $phpinfo = array('phpinfo' => array()); - if (preg_match_all( - '#(?:

(?:)?(.*?)(?:)?

)|(?:(.*?)\s*(?:(.*?)\s*(?:(.*?)\s*)?)?)#s', - ob_get_clean(), $matches, PREG_SET_ORDER - ) - ) { + $phpinfo = array( + 'phpinfo' => array() + ); + if (preg_match_all('#(?:

(?:)?(.*?)(?:)?

)|(?:(.*?)\s*(?:(.*?)\s*(?:(.*?)\s*)?)?)#s', ob_get_clean(), $matches, PREG_SET_ORDER)) { foreach ($matches as $match) { $end = array_keys($phpinfo); $end = end($end); if (strlen($match[1])) { $phpinfo[$match[1]] = array(); } elseif (isset($match[3])) { - $phpinfo[$end][$match[2]] = isset($match[4]) ? array($match[3], $match[4]) : $match[3]; + $phpinfo[$end][$match[2]] = isset($match[4]) ? array( + $match[3], + $match[4] + ) : $match[3]; } else { $phpinfo[$end][] = $match[2]; } @@ -129,112 +124,99 @@ if ($page == 'overview' && $userinfo['change_serversettings'] == '1') { $phpinfoentries = ""; foreach ($section as $key => $val) { if (is_array($val)) { - eval("\$phpinfoentries .= \"" . getTemplate("settings/phpinfo/phpinfo_3") . "\";"); + eval("\$phpinfoentries .= \"" . \Froxlor\UI\Template::getTemplate("settings/phpinfo/phpinfo_3") . "\";"); } elseif (is_string($key)) { - eval("\$phpinfoentries .= \"" . getTemplate("settings/phpinfo/phpinfo_2") . "\";"); + eval("\$phpinfoentries .= \"" . \Froxlor\UI\Template::getTemplate("settings/phpinfo/phpinfo_2") . "\";"); } else { - eval("\$phpinfoentries .= \"" . getTemplate("settings/phpinfo/phpinfo_1") . "\";"); + eval("\$phpinfoentries .= \"" . \Froxlor\UI\Template::getTemplate("settings/phpinfo/phpinfo_1") . "\";"); } } // first header -> show actual php version if (strtolower($name) == "phpinfo") { - $name = "PHP ".PHP_VERSION; + $name = "PHP " . PHP_VERSION; } - eval("\$phpinfohtml .= \"" . getTemplate("settings/phpinfo/phpinfo_table") . "\";"); + eval("\$phpinfohtml .= \"" . \Froxlor\UI\Template::getTemplate("settings/phpinfo/phpinfo_table") . "\";"); } $phpinfo = $phpinfohtml; } else { - standard_error($lng['error']['no_phpinfo']); + \Froxlor\UI\Response::standard_error($lng['error']['no_phpinfo']); } - eval("echo \"" . getTemplate("settings/phpinfo") . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("settings/phpinfo") . "\";"); +} elseif ($page == 'rebuildconfigs' && $userinfo['change_serversettings'] == '1') { + if (isset($_POST['send']) && $_POST['send'] == 'send') { -} elseif($page == 'rebuildconfigs' - && $userinfo['change_serversettings'] == '1' -) { - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { - - $log->logAction(ADM_ACTION, LOG_INFO, "rebuild configfiles"); - inserttask('1'); - inserttask('10'); + $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "rebuild configfiles"); + \Froxlor\System\Cronjob::inserttask('1'); + \Froxlor\System\Cronjob::inserttask('10'); // Using nameserver, insert a task which rebuilds the server config - inserttask('4'); - - standard_success('rebuildingconfigs', '', array('filename' => 'admin_index.php')); + \Froxlor\System\Cronjob::inserttask('4'); + // cron.d file + \Froxlor\System\Cronjob::inserttask('99'); + \Froxlor\UI\Response::standard_success('rebuildingconfigs', '', array( + 'filename' => 'admin_index.php' + )); } else { - ask_yesno('admin_configs_reallyrebuild', $filename, array('page' => $page)); + \Froxlor\UI\HTML::askYesNo('admin_configs_reallyrebuild', $filename, array( + 'page' => $page + )); } +} elseif ($page == 'updatecounters' && $userinfo['change_serversettings'] == '1') { -} elseif($page == 'updatecounters' - && $userinfo['change_serversettings'] == '1' -) { + if (isset($_POST['send']) && $_POST['send'] == 'send') { - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { - - $log->logAction(ADM_ACTION, LOG_INFO, "updated resource-counters"); - $updatecounters = updateCounters(true); + $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "updated resource-counters"); + $updatecounters = \Froxlor\User::updateCounters(true); $customers = ''; foreach ($updatecounters['customers'] as $customerid => $customer) { - eval("\$customers.=\"" . getTemplate("settings/updatecounters_row_customer") . "\";"); + eval("\$customers.=\"" . \Froxlor\UI\Template::getTemplate("settings/updatecounters_row_customer") . "\";"); } $admins = ''; foreach ($updatecounters['admins'] as $adminid => $admin) { - eval("\$admins.=\"" . getTemplate("settings/updatecounters_row_admin") . "\";"); + eval("\$admins.=\"" . \Froxlor\UI\Template::getTemplate("settings/updatecounters_row_admin") . "\";"); } - eval("echo \"" . getTemplate("settings/updatecounters") . "\";"); - + eval("echo \"" . \Froxlor\UI\Template::getTemplate("settings/updatecounters") . "\";"); } else { - ask_yesno('admin_counters_reallyupdate', $filename, array('page' => $page)); + \Froxlor\UI\HTML::askYesNo('admin_counters_reallyupdate', $filename, array( + 'page' => $page + )); } +} elseif ($page == 'wipecleartextmailpws' && $userinfo['change_serversettings'] == '1') { -} elseif ($page == 'wipecleartextmailpws' - && $userinfo['change_serversettings'] == '1' -) { + if (isset($_POST['send']) && $_POST['send'] == 'send') { - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { - - $log->logAction(ADM_ACTION, LOG_WARNING, "wiped all cleartext mail passwords"); + $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "wiped all cleartext mail passwords"); Database::query("UPDATE `" . TABLE_MAIL_USERS . "` SET `password` = '';"); Database::query("UPDATE `" . TABLE_PANEL_SETTINGS . "` SET `value` = '0' WHERE `settinggroup` = 'system' AND `varname` = 'mailpwcleartext'"); - redirectTo($filename, array('s' => $s)); - + \Froxlor\UI\Response::redirectTo($filename, array( + 's' => $s + )); } else { - ask_yesno('admin_cleartextmailpws_reallywipe', $filename, array('page' => $page)); + \Froxlor\UI\HTML::askYesNo('admin_cleartextmailpws_reallywipe', $filename, array( + 'page' => $page + )); } +} elseif ($page == 'wipequotas' && $userinfo['change_serversettings'] == '1') { -} elseif($page == 'wipequotas' - && $userinfo['change_serversettings'] == '1' -) { + if (isset($_POST['send']) && $_POST['send'] == 'send') { - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { - - $log->logAction(ADM_ACTION, LOG_WARNING, "wiped all mailquotas"); + $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "wiped all mailquotas"); // Set the quota to 0 which means unlimited Database::query("UPDATE `" . TABLE_MAIL_USERS . "` SET `quota` = '0';"); Database::query("UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET `email_quota_used` = '0'"); - redirectTo($filename, array('s' => $s)); - + \Froxlor\UI\Response::redirectTo($filename, array( + 's' => $s + )); } else { - ask_yesno('admin_quotas_reallywipe', $filename, array('page' => $page)); + \Froxlor\UI\HTML::askYesNo('admin_quotas_reallywipe', $filename, array( + 'page' => $page + )); } - -} elseif ($page == 'enforcequotas' - && $userinfo['change_serversettings'] == '1' -) { - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { +} elseif ($page == 'enforcequotas' && $userinfo['change_serversettings'] == '1') { + if (isset($_POST['send']) && $_POST['send'] == 'send') { // Fetch all accounts $result_stmt = Database::query("SELECT `quota`, `customerid` FROM `" . TABLE_MAIL_USERS . "`"); @@ -248,7 +230,10 @@ if ($page == 'overview' && $userinfo['change_serversettings'] == '1') { while ($array = $result_stmt->fetch(PDO::FETCH_ASSOC)) { $difference = Settings::Get('system.mail_quota') - $array['quota']; - Database::pexecute($upd_stmt, array('diff' => $difference, 'customerid' => $customerid)); + Database::pexecute($upd_stmt, array( + 'diff' => $difference, + 'customerid' => $customerid + )); } } @@ -256,27 +241,29 @@ if ($page == 'overview' && $userinfo['change_serversettings'] == '1') { $upd_stmt = Database::prepare(" UPDATE `" . TABLE_MAIL_USERS . "` SET `quota` = :quota "); - Database::pexecute($upd_stmt, array('quota' => Settings::Get('system.mail_quota'))); + Database::pexecute($upd_stmt, array( + 'quota' => Settings::Get('system.mail_quota') + )); // Update the Customer, if the used quota is bigger than the allowed quota Database::query("UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET `email_quota` = `email_quota_used` WHERE `email_quota` < `email_quota_used`"); - $log->logAction(ADM_ACTION, LOG_WARNING, 'enforcing mailquota to all customers: ' . Settings::Get('system.mail_quota') . ' MB'); - redirectTo($filename, array('s' => $s)); - + $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, 'enforcing mailquota to all customers: ' . Settings::Get('system.mail_quota') . ' MB'); + \Froxlor\UI\Response::redirectTo($filename, array( + 's' => $s + )); } else { - ask_yesno('admin_quotas_reallyenforce', $filename, array('page' => $page)); + \Froxlor\UI\HTML::askYesNo('admin_quotas_reallyenforce', $filename, array( + 'page' => $page + )); } -} elseif ($page == 'integritycheck' - && $userinfo['change_serversettings'] == '1' -) { - $integrity = new IntegrityCheck(); - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { +} elseif ($page == 'integritycheck' && $userinfo['change_serversettings'] == '1') { + $integrity = new \Froxlor\Database\IntegrityCheck(); + if (isset($_POST['send']) && $_POST['send'] == 'send') { $integrity->fixAll(); - } elseif(isset($_GET['action']) - && $_GET['action'] == "fix") { - ask_yesno('admin_integritycheck_reallyfix', $filename, array('page' => $page)); + } elseif (isset($_GET['action']) && $_GET['action'] == "fix") { + \Froxlor\UI\HTML::askYesNo('admin_integritycheck_reallyfix', $filename, array( + 'page' => $page + )); } $integritycheck = ''; @@ -284,7 +271,114 @@ if ($page == 'overview' && $userinfo['change_serversettings'] == '1') { $displayid = $id + 1; $result = $integrity->$check(); $checkdesc = $lng['integrity_check'][$check]; - eval("\$integritycheck.=\"" . getTemplate("settings/integritycheck_row") . "\";"); + eval("\$integritycheck.=\"" . \Froxlor\UI\Template::getTemplate("settings/integritycheck_row") . "\";"); } - eval("echo \"" . getTemplate("settings/integritycheck") . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("settings/integritycheck") . "\";"); +} elseif ($page == 'importexport' && $userinfo['change_serversettings'] == '1') { + // check for json-stuff + if (! extension_loaded('json')) { + \Froxlor\UI\Response::standard_error('jsonextensionnotfound'); + } + + if (isset($_GET['action']) && $_GET['action'] == "export") { + // export + try { + $json_result = Froxlor::getLocal($userinfo)->exportSettings(); + $json_export = json_decode($json_result, true)['data']; + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + header('Content-disposition: attachment; filename=Froxlor_settings-' . $version . '-' . $dbversion . '_' . date('d.m.Y') . '.json'); + header('Content-type: application/json'); + echo $json_export; + exit(); + } elseif (isset($_GET['action']) && $_GET['action'] == "import") { + // import + if (isset($_POST['send']) && $_POST['send'] == 'send') { + // get uploaded file + if (isset($_FILES["import_file"]["tmp_name"])) { + $imp_content = file_get_contents($_FILES["import_file"]["tmp_name"]); + try { + Froxlor::getLocal($userinfo, array( + 'json_str' => $imp_content + ))->importSettings(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + \Froxlor\UI\Response::standard_success('settingsimported', '', array( + 'filename' => 'admin_settings.php' + )); + } + \Froxlor\UI\Response::dynamic_error("Upload failed"); + } + } else { + eval("echo \"" . \Froxlor\UI\Template::getTemplate("settings/importexport/index") . "\";"); + } +} elseif ($page == 'testmail') { + if (isset($_POST['send']) && $_POST['send'] == 'send') { + $test_addr = isset($_POST['test_addr']) ? $_POST['test_addr'] : null; + + /** + * Initialize the mailingsystem + */ + $testmail = new \PHPMailer\PHPMailer\PHPMailer(true); + $testmail->CharSet = "UTF-8"; + + if (Settings::Get('system.mail_use_smtp')) { + $testmail->isSMTP(); + $testmail->Host = Settings::Get('system.mail_smtp_host'); + $testmail->SMTPAuth = Settings::Get('system.mail_smtp_auth') == '1' ? true : false; + $testmail->Username = Settings::Get('system.mail_smtp_user'); + $testmail->Password = Settings::Get('system.mail_smtp_passwd'); + if (Settings::Get('system.mail_smtp_usetls')) { + $testmail->SMTPSecure = 'tls'; + } else { + $testmail->SMTPAutoTLS = false; + } + $testmail->Port = Settings::Get('system.mail_smtp_port'); + } + + $_mailerror = false; + if (\PHPMailer\PHPMailer\PHPMailer::ValidateAddress(Settings::Get('panel.adminmail')) !== false) { + // set return-to address and custom sender-name, see #76 + $testmail->SetFrom(Settings::Get('panel.adminmail'), Settings::Get('panel.adminmail_defname')); + if (Settings::Get('panel.adminmail_return') != '') { + $testmail->AddReplyTo(Settings::Get('panel.adminmail_return'), Settings::Get('panel.adminmail_defname')); + } + + try { + $testmail->Subject = "Froxlor Test-Mail"; + $mail_body = "Yay, this worked :)"; + $testmail->AltBody = $mail_body; + $testmail->MsgHTML(str_replace("\n", "
", $mail_body)); + $testmail->AddAddress($test_addr); + $testmail->Send(); + } catch (\PHPMailer\PHPMailer\Exception $e) { + $mailerr_msg = $e->errorMessage(); + $_mailerror = true; + } catch (Exception $e) { + $mailerr_msg = $e->getMessage(); + $_mailerror = true; + } + + if (! $_mailerror) { + // success + $mail->ClearAddresses(); + \Froxlor\UI\Response::standard_success('testmailsent', '', array( + 'filename' => 'admin_settings.php', + 'page' => 'testmail' + )); + } + } else { + // invalid sender e-mail + $mailerr_msg = "Invalid sender e-mail address: " . Settings::Get('panel.adminmail'); + $_mailerror = true; + } + } + + $mail_smtp_user = Settings::Get('system.mail_smtp_user'); + $mail_smtp_host = Settings::Get('system.mail_smtp_host'); + $mail_smtp_port = Settings::Get('system.mail_smtp_port'); + + eval("echo \"" . \Froxlor\UI\Template::getTemplate("settings/testmail") . "\";"); } diff --git a/admin_templates.php b/admin_templates.php index cec93081..42db5d8f 100644 --- a/admin_templates.php +++ b/admin_templates.php @@ -16,23 +16,23 @@ * @package Panel * */ - define('AREA', 'admin'); require './lib/init.php'; +use Froxlor\Database\Database; +use Froxlor\Settings; + if (isset($_POST['subjectid'])) { $subjectid = intval($_POST['subjectid']); $mailbodyid = intval($_POST['mailbodyid']); - -} elseif(isset($_GET['subjectid'])) { +} elseif (isset($_GET['subjectid'])) { $subjectid = intval($_GET['subjectid']); $mailbodyid = intval($_GET['mailbodyid']); } if (isset($_POST['id'])) { $id = intval($_POST['id']); - -} elseif(isset($_GET['id'])) { +} elseif (isset($_GET['id'])) { $id = intval($_GET['id']); } @@ -45,21 +45,8 @@ $available_templates = array( ); // only show templates of features that are enabled #1191 -if ((int)Settings::Get('system.report_enable') == 1) { - array_push($available_templates, - 'trafficmaxpercent', - 'diskmaxpercent' - ); -} - -if ((int)Settings::Get('ticket.enabled') == 1) { - array_push($available_templates, - 'new_ticket_by_customer', - 'new_ticket_for_customer', - 'new_ticket_by_staff', - 'new_reply_ticket_by_customer', - 'new_reply_ticket_by_staff' - ); +if ((int) Settings::Get('system.report_enable') == 1) { + array_push($available_templates, 'trafficmaxpercent', 'diskmaxpercent'); } $file_templates = array( @@ -67,8 +54,8 @@ $file_templates = array( ); if ($action == '') { - //email templates - $log->logAction(ADM_ACTION, LOG_NOTICE, "viewed admin_templates"); + // email templates + $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "viewed admin_templates"); if (Settings::Get('panel.sendalternativemail') == 1) { $available_templates[] = 'pop_success_alternative'; @@ -78,9 +65,10 @@ if ($action == '') { $result_stmt = Database::prepare(" SELECT `id`, `language`, `varname` FROM `" . TABLE_PANEL_TEMPLATES . "` WHERE `adminid` = :adminid AND `templategroup`='mails' - ORDER BY `language`, `varname`" - ); - Database::pexecute($result_stmt, array('adminid' => $userinfo['adminid'])); + ORDER BY `language`, `varname`"); + Database::pexecute($result_stmt, array( + 'adminid' => $userinfo['adminid'] + )); while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { $parts = array(); @@ -94,20 +82,22 @@ if ($action == '') { $subjectid = $email['subject']; $mailbodyid = $email['mailbody']; $template = $lng['admin']['templates'][$action]; - eval("\$templates.=\"" . getTemplate("templates/templates_template") . "\";"); + eval("\$templates.=\"" . \Froxlor\UI\Template::getTemplate("templates/templates_template") . "\";"); } } $add = false; - while (list($language_file, $language_name) = each($languages)) { + foreach ($languages as $language_file => $language_name) { $templates_done = array(); $result_stmt = Database::prepare(" SELECT `varname` FROM `" . TABLE_PANEL_TEMPLATES . "` WHERE `adminid` = :adminid AND `language`= :lang - AND `templategroup` = 'mails' AND `varname` LIKE '%_subject'" - ); - Database::pexecute($result_stmt, array('adminid' => $userinfo['adminid'], 'lang' => $language_name)); + AND `templategroup` = 'mails' AND `varname` LIKE '%_subject'"); + Database::pexecute($result_stmt, array( + 'adminid' => $userinfo['adminid'], + 'lang' => $language_name + )); while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { $templates_done[] = str_replace('_subject', '', $row['varname']); @@ -118,111 +108,115 @@ if ($action == '') { } } - //filetemplates + // filetemplates $filetemplates = ''; $filetemplateadd = false; $result_stmt = Database::prepare(" SELECT `id`, `varname` FROM `" . TABLE_PANEL_TEMPLATES . "` - WHERE `adminid` = :adminid AND `templategroup`='files'" - ); - Database::pexecute($result_stmt, array('adminid' => $userinfo['adminid'])); + WHERE `adminid` = :adminid AND `templategroup`='files'"); + Database::pexecute($result_stmt, array( + 'adminid' => $userinfo['adminid'] + )); if (Database::num_rows() != count($file_templates)) { $filetemplateadd = true; } while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { - eval("\$filetemplates.=\"" . getTemplate("templates/templates_filetemplate") . "\";"); + eval("\$filetemplates.=\"" . \Froxlor\UI\Template::getTemplate("templates/templates_filetemplate") . "\";"); } - eval("echo \"" . getTemplate("templates/templates") . "\";"); - -} elseif($action == 'delete' - && $subjectid != 0 - && $mailbodyid != 0 -) { - //email templates + eval("echo \"" . \Froxlor\UI\Template::getTemplate("templates/templates") . "\";"); +} elseif ($action == 'delete' && $subjectid != 0 && $mailbodyid != 0) { + // email templates $result_stmt = Database::prepare(" SELECT `language`, `varname` FROM `" . TABLE_PANEL_TEMPLATES . "` - WHERE `adminid` = :adminid AND `id` = :id" - ); - Database::pexecute($result_stmt, array('adminid' => $userinfo['adminid'], 'id' => $subjectid)); + WHERE `adminid` = :adminid AND `id` = :id"); + Database::pexecute($result_stmt, array( + 'adminid' => $userinfo['adminid'], + 'id' => $subjectid + )); $result = $result_stmt->fetch(PDO::FETCH_ASSOC); if ($result['varname'] != '') { - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { + if (isset($_POST['send']) && $_POST['send'] == 'send') { $del_stmt = Database::prepare(" DELETE FROM `" . TABLE_PANEL_TEMPLATES . "` WHERE `adminid` = :adminid - AND (`id` = :ida OR `id` = :idb)" - ); + AND (`id` = :ida OR `id` = :idb)"); Database::pexecute($del_stmt, array( 'adminid' => $userinfo['adminid'], 'ida' => $subjectid, 'idb' => $mailbodyid )); - $log->logAction(ADM_ACTION, LOG_INFO, "deleted template '" . $result['language'] . ' - ' . $lng['admin']['templates'][str_replace('_subject', '', $result['varname'])] . "'"); - redirectTo($filename, array('page' => $page, 's' => $s)); - + $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "deleted template '" . $result['language'] . ' - ' . $lng['admin']['templates'][str_replace('_subject', '', $result['varname'])] . "'"); + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); } else { - ask_yesno('admin_template_reallydelete', $filename, array('subjectid' => $subjectid, 'mailbodyid' => $mailbodyid, 'page' => $page, 'action' => $action), $result['language'] . ' - ' . $lng['admin']['templates'][str_replace('_subject', '', $result['varname'])]); + \Froxlor\UI\HTML::askYesNo('admin_template_reallydelete', $filename, array( + 'subjectid' => $subjectid, + 'mailbodyid' => $mailbodyid, + 'page' => $page, + 'action' => $action + ), $result['language'] . ' - ' . $lng['admin']['templates'][str_replace('_subject', '', $result['varname'])]); } } - -} elseif($action == 'deletef' - && $id != 0 -) { - //file templates +} elseif ($action == 'deletef' && $id != 0) { + // file templates $result_stmt = Database::prepare(" SELECT * FROM `" . TABLE_PANEL_TEMPLATES . "` - WHERE `adminid` = :adminid AND `id` = :id" - ); - Database::pexecute($result_stmt, array('adminid' => $userinfo['adminid'], 'id' => $id)); + WHERE `adminid` = :adminid AND `id` = :id"); + Database::pexecute($result_stmt, array( + 'adminid' => $userinfo['adminid'], + 'id' => $id + )); if (Database::num_rows() > 0) { $row = $result_stmt->fetch(PDO::FETCH_ASSOC); - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { + if (isset($_POST['send']) && $_POST['send'] == 'send') { $del_stmt = Database::prepare(" DELETE FROM `" . TABLE_PANEL_TEMPLATES . "` - WHERE `adminid` = :adminid AND `id` = :id" - ); - Database::pexecute($del_stmt, array('adminid' => $userinfo['adminid'], 'id' => $id)); - $log->logAction(ADM_ACTION, LOG_INFO, "deleted template '" . $lng['admin']['templates'][$row['varname']] . "'"); - redirectTo($filename, array('page' => $page, 's' => $s)); - + WHERE `adminid` = :adminid AND `id` = :id"); + Database::pexecute($del_stmt, array( + 'adminid' => $userinfo['adminid'], + 'id' => $id + )); + $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "deleted template '" . $lng['admin']['templates'][$row['varname']] . "'"); + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); } else { - ask_yesno('admin_template_reallydelete', $filename, array('id' => $id, 'page' => $page, 'action' => $action), $lng['admin']['templates'][$row['varname']]); + \Froxlor\UI\HTML::askYesNo('admin_template_reallydelete', $filename, array( + 'id' => $id, + 'page' => $page, + 'action' => $action + ), $lng['admin']['templates'][$row['varname']]); } - } else { - standard_error('templatenotfound'); + \Froxlor\UI\Response::standard_error('templatenotfound'); } - -} elseif($action == 'add') { +} elseif ($action == 'add') { if (Settings::Get('panel.sendalternativemail') == 1) { $available_templates[] = 'pop_success_alternative'; } - if (isset($_POST['prepare']) - && $_POST['prepare'] == 'prepare' - ) { - //email templates - $language = htmlentities(validate($_POST['language'], 'language', '/^[^\r\n\0"\']+$/', 'nolanguageselect')); - $template = validate($_POST['template'], 'template'); + if (isset($_POST['prepare']) && $_POST['prepare'] == 'prepare') { + // email templates + $language = htmlentities(\Froxlor\Validate\Validate::validate($_POST['language'], 'language', '/^[^\r\n\0"\']+$/', 'nolanguageselect')); + $template = \Froxlor\Validate\Validate::validate($_POST['template'], 'template'); $lng_bak = $lng; foreach ($langs['English'] as $key => $value) { - include_once makeSecurePath($value['file']); + include_once \Froxlor\FileDir::makeSecurePath($value['file']); } if ($language != 'English') { foreach ($langs[$language] as $key => $value) { - include makeSecurePath($value['file']); + include \Froxlor\FileDir::makeSecurePath($value['file']); } } @@ -231,38 +225,36 @@ if ($action == '') { $lng = $lng_bak; - $template_add_data = include_once dirname(__FILE__).'/lib/formfields/admin/templates/formfield.template_add.php'; - $template_add_form = htmlform::genHTMLForm($template_add_data); + $template_add_data = include_once dirname(__FILE__) . '/lib/formfields/admin/templates/formfield.template_add.php'; + $template_add_form = \Froxlor\UI\HtmlForm::genHTMLForm($template_add_data); $title = $template_add_data['template_add']['title']; $image = $template_add_data['template_add']['image']; - eval("echo \"" . getTemplate("templates/templates_add_2") . "\";"); - - } elseif(isset($_POST['send']) - && $_POST['send'] == 'send' - ) { - //email templates - $language = htmlentities(validate($_POST['language'], 'language', '/^[^\r\n\0"\']+$/', 'nolanguageselect')); - $template = validate($_POST['template'], 'template'); - $subject = validate($_POST['subject'], 'subject', '/^[^\r\n\0]+$/', 'nosubjectcreate'); - $mailbody = validate($_POST['mailbody'], 'mailbody', '/^[^\0]+$/', 'nomailbodycreate'); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("templates/templates_add_2") . "\";"); + } elseif (isset($_POST['send']) && $_POST['send'] == 'send') { + // email templates + $language = htmlentities(\Froxlor\Validate\Validate::validate($_POST['language'], 'language', '/^[^\r\n\0"\']+$/', 'nolanguageselect')); + $template = \Froxlor\Validate\Validate::validate($_POST['template'], 'template'); + $subject = \Froxlor\Validate\Validate::validate($_POST['subject'], 'subject', '/^[^\r\n\0]+$/', 'nosubjectcreate'); + $mailbody = \Froxlor\Validate\Validate::validate($_POST['mailbody'], 'mailbody', '/^[^\0]+$/', 'nomailbodycreate'); $templates = array(); $result_stmt = Database::prepare(" SELECT `varname` FROM `" . TABLE_PANEL_TEMPLATES . "` WHERE `adminid` = :adminid AND `language` = :lang - AND `templategroup` = 'mails' AND `varname` LIKE '%_subject'" - ); - Database::pexecute($result_stmt, array('adminid' => $userinfo['adminid'], 'lang' => $language)); + AND `templategroup` = 'mails' AND `varname` LIKE '%_subject'"); + Database::pexecute($result_stmt, array( + 'adminid' => $userinfo['adminid'], + 'lang' => $language + )); - while($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { + while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { $templates[] = str_replace('_subject', '', $row['varname']); } $templates = array_diff($available_templates, $templates); if (array_search($template, $templates) === false) { - standard_error('templatenotfound'); - + \Froxlor\UI\Response::standard_error('templatenotfound'); } else { $ins_stmt = Database::prepare(" INSERT INTO `" . TABLE_PANEL_TEMPLATES . "` SET @@ -270,14 +262,13 @@ if ($action == '') { `language` = :lang, `templategroup` = 'mails', `varname` = :var, - `value` = :value" - ); + `value` = :value"); // mail-subject $ins_data = array( 'adminid' => $userinfo['adminid'], 'lang' => $language, - 'var' => $template.'_subject', + 'var' => $template . '_subject', 'value' => $subject ); Database::pexecute($ins_stmt, $ins_data); @@ -286,21 +277,21 @@ if ($action == '') { $ins_data = array( 'adminid' => $userinfo['adminid'], 'lang' => $language, - 'var' => $template.'_mailbody', + 'var' => $template . '_mailbody', 'value' => $mailbody ); Database::pexecute($ins_stmt, $ins_data); - $log->logAction(ADM_ACTION, LOG_INFO, "added template '" . $language . ' - ' . $template . "'"); - redirectTo($filename, array('page' => $page, 's' => $s)); + $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "added template '" . $language . ' - ' . $template . "'"); + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); } - - } elseif(isset($_POST['filesend']) - && $_POST['filesend'] == 'filesend' - ) { - //file templates - $template = validate($_POST['template'], 'template'); - $filecontent = validate($_POST['filecontent'], 'filecontent', '/^[^\0]+$/', 'filecontentnotset'); + } elseif (isset($_POST['filesend']) && $_POST['filesend'] == 'filesend') { + // file templates + $template = \Froxlor\Validate\Validate::validate($_POST['template'], 'template'); + $filecontent = \Froxlor\Validate\Validate::validate($_POST['filecontent'], 'filecontent', '/^[^\0]+$/', 'filecontentnotset'); $ins_stmt = Database::prepare(" INSERT INTO `" . TABLE_PANEL_TEMPLATES . "` SET @@ -308,8 +299,7 @@ if ($action == '') { `language` = '', `templategroup` = 'files', `varname` = :var, - `value` = :value" - ); + `value` = :value"); $ins_data = array( 'adminid' => $userinfo['adminid'], @@ -318,24 +308,28 @@ if ($action == '') { ); Database::pexecute($ins_stmt, $ins_data); - $log->logAction(ADM_ACTION, LOG_INFO, "added template '" . $template . "'"); - redirectTo($filename, array('page' => $page, 's' => $s)); + $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "added template '" . $template . "'"); + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); + } elseif (! isset($_GET['files'])) { - } elseif(!isset($_GET['files'])) { - - //email templates + // email templates $add = false; $language_options = ''; $template_options = ''; - while (list($language_file, $language_name) = each($languages)) { + foreach ($languages as $language_file => $language_name) { $templates = array(); $result_stmt = Database::prepare(" SELECT `varname` FROM `" . TABLE_PANEL_TEMPLATES . "` WHERE `adminid` = :adminid AND `language` = :lang - AND `templategroup` = 'mails' AND `varname` LIKE '%_subject'" - ); - Database::pexecute($result_stmt, array('adminid' => $userinfo['adminid'], 'lang' => $language_name)); + AND `templategroup` = 'mails' AND `varname` LIKE '%_subject'"); + Database::pexecute($result_stmt, array( + 'adminid' => $userinfo['adminid'], + 'lang' => $language_name + )); while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { $templates[] = str_replace('_subject', '', $row['varname']); @@ -343,33 +337,32 @@ if ($action == '') { if (count(array_diff($available_templates, $templates)) > 0) { $add = true; - $language_options.= makeoption($language_name, $language_file, $userinfo['language'], true, true); + $language_options .= \Froxlor\UI\HTML::makeoption($language_name, $language_file, $userinfo['language'], true, true); $templates = array_diff($available_templates, $templates); foreach ($templates as $template) { - $template_options.= makeoption($lng['admin']['templates'][$template], $template, NULL, true, true, $language_file) . "\n"; + $template_options .= \Froxlor\UI\HTML::makeoption($lng['admin']['templates'][$template], $template, NULL, true, true, $language_file) . "\n"; } } } if ($add) { - eval("echo \"" . getTemplate("templates/templates_add_1") . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("templates/templates_add_1") . "\";"); } else { - standard_error('alltemplatesdefined'); + \Froxlor\UI\Response::standard_error('alltemplatesdefined'); } - } else { - //filetemplates + // filetemplates $result_stmt = Database::prepare(" SELECT `id`, `varname` FROM `" . TABLE_PANEL_TEMPLATES . "` - WHERE `adminid` = :adminid AND `templategroup`='files'" - ); - Database::pexecute($result_stmt, array('adminid' => $userinfo['adminid'])); + WHERE `adminid` = :adminid AND `templategroup`='files'"); + Database::pexecute($result_stmt, array( + 'adminid' => $userinfo['adminid'] + )); if (Database::num_rows() == count($file_templates)) { - standard_error('alltemplatesdefined'); - + \Froxlor\UI\Response::standard_error('alltemplatesdefined'); } else { $templatesdefined = array(); @@ -380,44 +373,39 @@ if ($action == '') { } foreach (array_diff($file_templates, $templatesdefined) as $template) { - $free_templates.= makeoption($lng['admin']['templates'][$template], $template, '', true); + $free_templates .= \Froxlor\UI\HTML::makeoption($lng['admin']['templates'][$template], $template, '', true); } - $filetemplate_add_data = include_once dirname(__FILE__).'/lib/formfields/admin/templates/formfield.filetemplate_add.php'; - $filetemplate_add_form = htmlform::genHTMLForm($filetemplate_add_data); + $filetemplate_add_data = include_once dirname(__FILE__) . '/lib/formfields/admin/templates/formfield.filetemplate_add.php'; + $filetemplate_add_form = \Froxlor\UI\HtmlForm::genHTMLForm($filetemplate_add_data); $title = $filetemplate_add_data['filetemplate_add']['title']; $image = $filetemplate_add_data['filetemplate_add']['image']; - eval("echo \"" . getTemplate("templates/filetemplates_add") . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("templates/filetemplates_add") . "\";"); } } - -} elseif($action == 'edit' - && $subjectid != 0 - && $mailbodyid != 0 -) { - //email templates +} elseif ($action == 'edit' && $subjectid != 0 && $mailbodyid != 0) { + // email templates $result_stmt = Database::prepare(" SELECT `language`, `varname`, `value` FROM `" . TABLE_PANEL_TEMPLATES . "` - WHERE `adminid` = :adminid AND `id` = :subjectid" - ); - Database::pexecute($result_stmt, array('adminid' => $userinfo['adminid'], 'subjectid' => $subjectid)); + WHERE `adminid` = :adminid AND `id` = :subjectid"); + Database::pexecute($result_stmt, array( + 'adminid' => $userinfo['adminid'], + 'subjectid' => $subjectid + )); $result = $result_stmt->fetch(PDO::FETCH_ASSOC); if ($result['varname'] != '') { - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { - $subject = validate($_POST['subject'], 'subject', '/^[^\r\n\0]+$/', 'nosubjectcreate'); - $mailbody = validate($_POST['mailbody'], 'mailbody', '/^[^\0]+$/', 'nomailbodycreate'); + if (isset($_POST['send']) && $_POST['send'] == 'send') { + $subject = \Froxlor\Validate\Validate::validate($_POST['subject'], 'subject', '/^[^\r\n\0]+$/', 'nosubjectcreate'); + $mailbody = \Froxlor\Validate\Validate::validate($_POST['mailbody'], 'mailbody', '/^[^\0]+$/', 'nomailbodycreate'); $upd_stmt = Database::prepare(" UPDATE `" . TABLE_PANEL_TEMPLATES . "` SET `value` = :value - WHERE `adminid` = :adminid AND `id` = :id" - ); + WHERE `adminid` = :adminid AND `id` = :id"); // subject Database::pexecute($upd_stmt, array( 'value' => $subject, @@ -431,85 +419,85 @@ if ($action == '') { 'id' => $mailbodyid )); - $log->logAction(ADM_ACTION, LOG_INFO, "edited template '" . $result['varname'] . "'"); - redirectTo($filename, array('page' => $page, 's' => $s)); - + $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "edited template '" . $result['varname'] . "'"); + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); } else { - $result = htmlentities_array($result); + $result = \Froxlor\PhpHelper::htmlentitiesArray($result); $template = $lng['admin']['templates'][str_replace('_subject', '', $result['varname'])]; $subject = $result['value']; $result_stmt = Database::prepare(" SELECT `language`, `varname`, `value` FROM `" . TABLE_PANEL_TEMPLATES . "` - WHERE `id` = :id" - ); - Database::pexecute($result_stmt, array('id' => $mailbodyid)); + WHERE `id` = :id"); + Database::pexecute($result_stmt, array( + 'id' => $mailbodyid + )); $result = $result_stmt->fetch(PDO::FETCH_ASSOC); - + $template_name = str_replace('_mailbody', '', $result['varname']); // don't escape the already escaped language-string so save up before htmlentities() $language = $result['language']; - $result = htmlentities_array($result); + $result = \Froxlor\PhpHelper::htmlentitiesArray($result); $mailbody = $result['value']; - $template_edit_data = include_once dirname(__FILE__).'/lib/formfields/admin/templates/formfield.template_edit.php'; - $template_edit_form = htmlform::genHTMLForm($template_edit_data); + $template_edit_data = include_once dirname(__FILE__) . '/lib/formfields/admin/templates/formfield.template_edit.php'; + $template_edit_form = \Froxlor\UI\HtmlForm::genHTMLForm($template_edit_data); $title = $template_edit_data['template_edit']['title']; $image = $template_edit_data['template_edit']['image']; - eval("echo \"" . getTemplate("templates/templates_edit") . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("templates/templates_edit") . "\";"); } } - -} elseif($action == 'editf' - && $id != 0 -) { - //file templates +} elseif ($action == 'editf' && $id != 0) { + // file templates $result_stmt = Database::prepare(" SELECT * FROM `" . TABLE_PANEL_TEMPLATES . "` - WHERE `adminid` = :adminid AND `id` = :id" - ); - Database::pexecute($result_stmt, array('adminid' => $userinfo['adminid'], 'id' => $id)); + WHERE `adminid` = :adminid AND `id` = :id"); + Database::pexecute($result_stmt, array( + 'adminid' => $userinfo['adminid'], + 'id' => $id + )); - if(Database::num_rows() > 0) { + if (Database::num_rows() > 0) { $row = $result_stmt->fetch(PDO::FETCH_ASSOC); - //filetemplates - if (isset($_POST['filesend']) - && $_POST['filesend'] == 'filesend' - ) { - $filecontent = validate($_POST['filecontent'], 'filecontent', '/^[^\0]+$/', 'filecontentnotset'); + // filetemplates + if (isset($_POST['filesend']) && $_POST['filesend'] == 'filesend') { + $filecontent = \Froxlor\Validate\Validate::validate($_POST['filecontent'], 'filecontent', '/^[^\0]+$/', 'filecontentnotset'); $upd_stmt = Database::prepare(" UPDATE `" . TABLE_PANEL_TEMPLATES . "` SET `value` = :value - WHERE `adminid` = :adminid AND `id` = :id" - ); + WHERE `adminid` = :adminid AND `id` = :id"); Database::pexecute($upd_stmt, array( 'value' => $filecontent, 'adminid' => $userinfo['adminid'], 'id' => $id )); - $log->logAction(ADM_ACTION, LOG_INFO, "edited template '" . $row['varname'] . "'"); - redirectTo($filename, array('page' => $page, 's' => $s)); - + $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "edited template '" . $row['varname'] . "'"); + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); } else { - $row = htmlentities_array($row); + $row = \Froxlor\PhpHelper::htmlentitiesArray($row); - $filetemplate_edit_data = include_once dirname(__FILE__).'/lib/formfields/admin/templates/formfield.filetemplate_edit.php'; - $filetemplate_edit_form = htmlform::genHTMLForm($filetemplate_edit_data); + $filetemplate_edit_data = include_once dirname(__FILE__) . '/lib/formfields/admin/templates/formfield.filetemplate_edit.php'; + $filetemplate_edit_form = \Froxlor\UI\HtmlForm::genHTMLForm($filetemplate_edit_data); $title = $filetemplate_edit_data['filetemplate_edit']['title']; $image = $filetemplate_edit_data['filetemplate_edit']['image']; - eval("echo \"" . getTemplate("templates/filetemplates_edit") . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("templates/filetemplates_edit") . "\";"); } - } else { - standard_error('templatenotfound'); + \Froxlor\UI\Response::standard_error('templatenotfound'); } } diff --git a/admin_tickets.php b/admin_tickets.php deleted file mode 100644 index fbb569a3..00000000 --- a/admin_tickets.php +++ /dev/null @@ -1,909 +0,0 @@ - (2003-2009) - * @author Froxlor team (2010-) - * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt - * @package Panel - * - */ - -define('AREA', 'admin'); -require './lib/init.php'; - -if (isset($_POST['id'])) { - $id = intval($_POST['id']); - -} elseif(isset($_GET['id'])) { - - $id = intval($_GET['id']); - - // only check if this is not a category-id - if (!isset($_GET['page']) || (isset($_GET['page']) && $_GET['page'] != 'categories')) { - if (!$userinfo['customers_see_all']) { - /* - * Check if the current user is allowed to see the current ticket. - */ - $stmt = Database::prepare(" - SELECT `id` FROM `panel_tickets` - WHERE `id` = :id AND `adminid` = :adminid - "); - $result = Database::pexecute_first($stmt, array('id' => $id, 'adminid' => $userinfo['adminid'])); - - if ($result == null) { - // no rights to see the requested ticket - standard_error(array('ticketnotaccessible')); - } - } - } -} - -if ($page == 'tickets' - && $userinfo['customers'] != '0' -) { - // Let's see how many customers we have - $countcustomers_stmt = Database::prepare(" - SELECT COUNT(`customerid`) as `countcustomers` - FROM `" . TABLE_PANEL_CUSTOMERS . "` " . - ($userinfo['customers_see_all'] ? '' : "WHERE `adminid` = :adminid") - ); - $countcustomers = Database::pexecute_first($countcustomers_stmt, array('adminid' => $userinfo['adminid'])); - $countcustomers = (int)$countcustomers['countcustomers']; - - if ($action == '') { - $log->logAction(ADM_ACTION, LOG_NOTICE, "viewed admin_tickets"); - $fields = array( - 'status' => $lng['ticket']['status'], - 'lastchange' => $lng['ticket']['lastchange'], - 'subject' => $lng['ticket']['subject'], - 'lastreplier' => $lng['ticket']['lastreplier'] - ); - $paging = new paging($userinfo, TABLE_PANEL_TICKETS, $fields, null, null, 1, 'desc'); - $result_stmt = Database::prepare(" - SELECT `main`.`id`, `main`.`customerid`, ( - SELECT COUNT(`sub`.`id`) - FROM `" . TABLE_PANEL_TICKETS . "` `sub` - WHERE `sub`.`answerto` = `main`.`id`) as `ticket_answers`, - `main`.`lastchange`, `main`.`subject`, `main`.`status`, `main`.`lastreplier`, `main`.`priority` - FROM `" . TABLE_PANEL_TICKETS . "` as `main` - WHERE `main`.`answerto` = '0' AND `archived` = '0' " . - ($userinfo['customers_see_all'] ? '' : " AND `adminid` = :adminid") . - $paging->getSqlWhere(true) . " " . $paging->getSqlOrderBy() . " " . $paging->getSqlLimit() - ); - Database::pexecute($result_stmt, array('adminid' => $userinfo['adminid'])); - $num_rows = Database::num_rows(); - $paging->setEntries($num_rows); - $sortcode = $paging->getHtmlSortCode($lng); - $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); - $searchcode = $paging->getHtmlSearchCode($lng); - $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); - $ctickets = array(); - - while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { - if (!isset($ctickets[$row['customerid']]) - || !is_array($ctickets[$row['customerid']]) - ) { - $ctickets[$row['customerid']] = array(); - } - $ctickets[$row['customerid']][$row['id']] = $row; - } - - if ($paging->sortfield == 'customerid' - && $paging->sortorder == 'desc' - ) { - krsort($ctickets); - } else { - ksort($ctickets); - } - - $i = 0; - $count = 0; - $tickets_count = 0; - $tickets = ''; - foreach ($ctickets as $cid => $ticketrows) { - $_cid = 0; - foreach ($ticketrows as $row) { - if ($paging->checkDisplay($i)) { - - $row = htmlentities_array($row); - $row['lastchange'] = date("d.m.y H:i", $row['lastchange']); - - if ($_cid != $row['customerid']) { - $cid = $row['customerid']; - $usr_stmt = Database::prepare(' - SELECT `customerid`, `firstname`, `name`, `company`, `loginname` - FROM `' . TABLE_PANEL_CUSTOMERS . '` - WHERE `customerid` = :cid' - ); - $usr = Database::pexecute_first($usr_stmt, array('cid' => $cid)); - - if (isset($usr['loginname'])) { - $customer = getCorrectFullUserDetails($usr); - $customerloginname = $usr['loginname']; - $customerid = $usr['customerid']; - } else { - $customer = $lng['ticket']['nonexistingcustomer']; - } - eval("\$tickets.=\"" . getTemplate("tickets/tickets_customer") . "\";"); - } - - $tickets_count++; - - if ($row['status'] >= 0 - && $row['status'] <= 2 - ) { - $reopen = 0; - } else { - $reopen = 1; - } - - $row['status'] = ticket::getStatusText($lng, $row['status']); - $row['priority'] = ticket::getPriorityText($lng, $row['priority']); - - if ($row['lastreplier'] == '1') { - $row['lastreplier'] = $lng['ticket']['staff']; - $cananswer = 0; - } else { - $row['lastreplier'] = $lng['ticket']['customer']; - $cananswer = 1; - } - - $row['subject'] = html_entity_decode($row['subject']); - if (strlen($row['subject']) > 30) { - $ts = wordwrap($row['subject'], 30, "|"); - $ts = explode("|", $ts); - $row['subject'] = $ts[0]. '...'; - } - - eval("\$tickets.=\"" . getTemplate("tickets/tickets_tickets") . "\";"); - $count++; - $_cid = $row['customerid']; - } - $i++; - } - } - eval("echo \"" . getTemplate("tickets/tickets") . "\";"); - - } elseif($action == 'new') { - - if ($userinfo['tickets_used'] < $userinfo['tickets'] - || $userinfo['tickets'] == '-1' - ) { - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { - $newticket = ticket::getInstanceOf($userinfo, -1); - $newticket->Set('subject', validate($_POST['subject'], 'subject'), true, false); - $newticket->Set('priority', validate($_POST['priority'], 'priority'), true, false); - $newticket->Set('category', validate($_POST['category'], 'category'), true, false); - $newticket->Set('customer', (int)$_POST['customer'], true, false); - $newticket->Set('message', validate(htmlentities(str_replace("\r\n", "\n", $_POST['message'])), 'message', '/^[^\0]*$/'), true, false); - - if ($newticket->Get('subject') == null) { - standard_error(array('stringisempty', 'mysubject')); - } elseif($newticket->Get('message') == null) { - standard_error(array('stringisempty', 'mymessage')); - } else { - $now = time(); - $newticket->Set('admin', $userinfo['adminid'], true, true); - $newticket->Set('dt', $now, true, true); - $newticket->Set('lastchange', $now, true, true); - $newticket->Set('ip', $_SERVER['REMOTE_ADDR'], true, true); - $newticket->Set('status', '0', true, true); - $newticket->Set('lastreplier', '1', true, true); - $newticket->Set('by', '1', true, true); - $newticket->Insert(); - $newticket->sendMail((int)$newticket->Get('customer'), 'new_ticket_by_staff_subject', $lng['mails']['new_ticket_by_staff']['subject'], 'new_ticket_by_staff_mailbody', $lng['mails']['new_ticket_by_staff']['mailbody']); - $log->logAction(ADM_ACTION, LOG_NOTICE, "opened a new ticket for customer #" . $newticket->Get('customer') . " - '" . $newticket->Get('subject') . "'"); - redirectTo($filename, Array('page' => $page, 's' => $s)); - } - } else { - $categories = ''; - $where = ''; - if ($userinfo['tickets_see_all'] != '1') { - $where = 'WHERE `adminid` = :adminid'; - } - $result_stmt = Database::prepare(' - SELECT `id`, `name` FROM `' . TABLE_PANEL_TICKET_CATS . '` - '.$where.' ORDER BY `logicalorder`, `name` ASC' - ); - $result = Database::pexecute_first($result_stmt, array('adminid' => $userinfo['adminid'])); - - if (isset($result['name']) - && $result['name'] != '' - ) { - $result2_stmt = Database::prepare(' - SELECT `id`, `name` FROM `' . TABLE_PANEL_TICKET_CATS . '` - '.$where.' ORDER BY `logicalorder`, `name` ASC' - ); - Database::pexecute($result2_stmt, array('adminid' => $userinfo['adminid'])); - - while ($row = $result2_stmt->fetch(PDO::FETCH_ASSOC)) { - $categories.= makeoption($row['name'], $row['id']); - } - - } else { - $categories = makeoption($lng['ticket']['no_cat'], '0'); - } - - $customers = ''; - $result_customers_stmt = Database::prepare(" - SELECT `customerid`, `loginname`, `name`, `firstname`, `company` - FROM `" . TABLE_PANEL_CUSTOMERS . "` " . - ($userinfo['customers_see_all'] ? '' : " WHERE `adminid` = :adminid")." - ORDER BY `name` ASC" - ); - Database::pexecute($result_customers_stmt, array('adminid' => $userinfo['adminid'])); - - while ($row_customer = $result_customers_stmt->fetch(PDO::FETCH_ASSOC)) { - $customers.= makeoption(getCorrectFullUserDetails($row_customer) . ' (' . $row_customer['loginname'] . ')', $row_customer['customerid']); - } - - $def_prio = Settings::Get('ticket.default_priority'); - $priorities = makeoption($lng['ticket']['high'], '1', $def_prio); - $priorities.= makeoption($lng['ticket']['normal'], '2', $def_prio); - $priorities.= makeoption($lng['ticket']['low'], '3', $def_prio); - - $ticket_new_data = include_once dirname(__FILE__).'/lib/formfields/admin/tickets/formfield.ticket_new.php'; - $ticket_new_form = htmlform::genHTMLForm($ticket_new_data); - - $title = $ticket_new_data['ticket_new']['title']; - $image = $ticket_new_data['ticket_new']['image']; - - eval("echo \"" . getTemplate("tickets/tickets_new") . "\";"); - } - - } else { - standard_error('nomoreticketsavailable'); - } - - } elseif($action == 'answer' - && $id != 0 - ) { - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { - $replyticket = ticket::getInstanceOf($userinfo, -1); - $replyticket->Set('subject', validate($_POST['subject'], 'subject'), true, false); - $replyticket->Set('priority', validate($_POST['priority'], 'priority'), true, false); - $replyticket->Set('message', validate(htmlentities(str_replace("\r\n", "\n", $_POST['message'])), 'message', '/^[^\0]*$/'), true, false); - - if ($replyticket->Get('message') == null) { - standard_error(array('stringisempty', 'mymessage')); - } else { - $now = time(); - $mainticket = ticket::getInstanceOf($userinfo, (int)$id); - $replyticket->Set('customer', $mainticket->Get('customer'), true, true); - $replyticket->Set('lastchange', $now, true, true); - $replyticket->Set('ip', $_SERVER['REMOTE_ADDR'], true, true); - $replyticket->Set('status', '1', true, true); - $replyticket->Set('answerto', (int)$id, true, false); - $replyticket->Set('by', '1', true, true); - $replyticket->Insert(); - - // Update priority if changed - if ($replyticket->Get('priority') != $mainticket->Get('priority')) { - $mainticket->Set('priority', $replyticket->Get('priority'), true); - } - - $mainticket->Set('lastchange', $now); - $mainticket->Set('lastreplier', '1'); - $mainticket->Set('status', '2'); - $mainticket->Update(); - $mainticket->sendMail((int)$mainticket->Get('customer'), 'new_reply_ticket_by_staff_subject', $lng['mails']['new_reply_ticket_by_staff']['subject'], 'new_reply_ticket_by_staff_mailbody', $lng['mails']['new_reply_ticket_by_staff']['mailbody']); - $log->logAction(ADM_ACTION, LOG_NOTICE, "answered ticket '" . $mainticket->Get('subject') . "'"); - redirectTo($filename, array('page' => $page, 's' => $s)); - } - - } else { - - $ticket_replies = ''; - $mainticket = ticket::getInstanceOf($userinfo, (int)$id); - $dt = date("d.m.Y H:i\h", $mainticket->Get('dt')); - $status = ticket::getStatusText($lng, $mainticket->Get('status')); - - if ($mainticket->Get('status') >= 0 - && $mainticket->Get('status') <= 2 - ) { - $isclosed = 0; - } else { - $isclosed = 1; - } - - if ($mainticket->Get('by') == '1') { - $by = $lng['ticket']['staff']; - } else { - $cid = $mainticket->Get('customer'); - $usr_stmt = Database::prepare(' - SELECT `customerid`, `firstname`, `name`, `company`, `loginname` - FROM `' . TABLE_PANEL_CUSTOMERS . '` - WHERE `customerid` = :cid' - ); - $usr = Database::pexecute_first($usr_stmt, array('cid' => $cid)); - $by = ''; - $by .= getCorrectFullUserDetails($usr).''; - } - - $subject = $mainticket->Get('subject'); - $message = $mainticket->Get('message'); - eval("\$ticket_replies.=\"" . getTemplate("tickets/tickets_tickets_main") . "\";"); - - $result_stmt = Database::prepare(' - SELECT `name` FROM `' . TABLE_PANEL_TICKET_CATS . '` WHERE `id` = :cid' - ); - $row = Database::pexecute_first($result_stmt, array('cid' => $mainticket->Get('category'))); - - $andere_stmt = Database::prepare(' - SELECT * FROM `' . TABLE_PANEL_TICKETS . '` - WHERE `answerto` = :id ORDER BY `lastchange` ASC' - ); - Database::pexecute($andere_stmt, array('id' => $id)); - $numrows_andere = Database::num_rows(); - - while ($row2 = $andere_stmt->fetch(PDO::FETCH_ASSOC)) { - $subticket = ticket::getInstanceOf($userinfo, (int)$row2['id']); - $lastchange = date("d.m.Y H:i\h", $subticket->Get('lastchange')); - - if ($subticket->Get('by') == '1') { - $by = $lng['ticket']['staff']; - } else { - $cid = $subticket->Get('customer'); - $usr_stmt = Database::prepare(' - SELECT `customerid`, `firstname`, `name`, `company`, `loginname` - FROM `' . TABLE_PANEL_CUSTOMERS . '` - WHERE `customerid` = :cid' - ); - $usr = Database::pexecute_first($usr_stmt, array('cid' => $cid)); - $by = ''; - $by .= getCorrectFullUserDetails($usr).''; - } - - $subject = $subticket->Get('subject'); - $message = $subticket->Get('message'); - - $row2 = htmlentities_array($row2); - eval("\$ticket_replies.=\"" . getTemplate("tickets/tickets_tickets_list") . "\";"); - } - - $priorities = makeoption($lng['ticket']['high'], '1', $mainticket->Get('priority'), true, true); - $priorities.= makeoption($lng['ticket']['normal'], '2', $mainticket->Get('priority'), true, true); - $priorities.= makeoption($lng['ticket']['low'], '3', $mainticket->Get('priority'), true, true); - $subject = htmlentities($mainticket->Get('subject')); - $ticket_replies_count = $numrows_andere + 1; - - // don't forget the main-ticket! - $ticket_reply_data = include_once dirname(__FILE__).'/lib/formfields/admin/tickets/formfield.ticket_reply.php'; - $ticket_reply_form = htmlform::genHTMLForm($ticket_reply_data); - - $title = $ticket_reply_data['ticket_reply']['title']; - $image = $ticket_reply_data['ticket_reply']['image']; - - eval("echo \"" . getTemplate("tickets/tickets_reply") . "\";"); - } - - } elseif($action == 'close' - && $id != 0 - ) { - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { - $now = time(); - $mainticket = ticket::getInstanceOf($userinfo, (int)$id); - $mainticket->Set('lastchange', $now, true, true); - $mainticket->Set('lastreplier', '1', true, true); - $mainticket->Set('status', '3', true, true); - $mainticket->Update(); - $log->logAction(ADM_ACTION, LOG_NOTICE, "closed ticket '" . $mainticket->Get('subject') . "'"); - redirectTo($filename, array('page' => $page, 's' => $s)); - } else { - $mainticket = ticket::getInstanceOf($userinfo, (int)$id); - ask_yesno('ticket_reallyclose', $filename, array('id' => $id, 'page' => $page, 'action' => $action), $mainticket->Get('subject')); - } - - } elseif($action == 'reopen' - && $id != 0 - ) { - $now = time(); - $mainticket = ticket::getInstanceOf($userinfo, (int)$id); - $mainticket->Set('lastchange', $now, true, true); - $mainticket->Set('lastreplier', '1', true, true); - $mainticket->Set('status', '0', true, true); - $mainticket->Update(); - $log->logAction(ADM_ACTION, LOG_NOTICE, "reopened ticket '" . $mainticket->Get('subject') . "'"); - redirectTo($filename, array('page' => $page, 's' => $s)); - - } elseif($action == 'archive' - && $id != 0 - ) { - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { - $now = time(); - $mainticket = ticket::getInstanceOf($userinfo, (int)$id); - $mainticket->Set('lastchange', $now, true, true); - $mainticket->Set('lastreplier', '1', true, true); - $mainticket->Set('status', '3', true, true); - $mainticket->Update(); - $mainticket->Archive(); - $log->logAction(ADM_ACTION, LOG_NOTICE, "archived ticket '" . $mainticket->Get('subject') . "'"); - redirectTo($filename, array('page' => $page, 's' => $s)); - } else { - $mainticket = ticket::getInstanceOf($userinfo, (int)$id); - ask_yesno('ticket_reallyarchive', $filename, array('id' => $id, 'page' => $page, 'action' => $action), $mainticket->Get('subject')); - } - - } elseif($action == 'delete' - && $id != 0 - ) { - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { - $mainticket = ticket::getInstanceOf($userinfo, (int)$id); - $log->logAction(ADM_ACTION, LOG_INFO, "deleted ticket '" . $mainticket->Get('subject') . "'"); - $mainticket->Delete(); - redirectTo($filename, array('page' => $page, 's' => $s)); - } else { - $mainticket = ticket::getInstanceOf($userinfo, (int)$id); - ask_yesno('ticket_reallydelete', $filename, array('id' => $id, 'page' => $page, 'action' => $action), $mainticket->Get('subject')); - } - } - -} elseif($page == 'categories' - && $userinfo['customers'] != '0' -) { - if ($action == '') { - - $log->logAction(ADM_ACTION, LOG_NOTICE, "viewed admin_tickets::categories"); - $fields = array( - 'name' => $lng['ticket']['category'], - 'logicalorder' => $lng['ticket']['logicalorder'] - ); - - $where = '1'; // WHERE 1 is like no 'where-clause' - if ($userinfo['tickets_see_all'] != '1') { - $where = " `main`.`adminid` = :adminid"; - } - $paging = new paging($userinfo, TABLE_PANEL_TICKET_CATS, $fields); - $result_stmt = Database::prepare(" - SELECT `main`.`id`, `main`.`name`, `main`.`logicalorder`, ( - SELECT COUNT(`sub`.`id`) FROM `" . TABLE_PANEL_TICKETS . "` `sub` - WHERE `sub`.`category` = `main`.`id` - AND `sub`.`answerto` = '0' - AND `sub`.`adminid` = :adminid - ) as `ticketcount`, ( - SELECT COUNT(`sub2`.`id`) FROM `" . TABLE_PANEL_TICKETS . "` `sub2` - WHERE `sub2`.`category` = `main`.`id` - AND `sub2`.`answerto` = '0' - AND (`sub2`.`status` = '0' OR `sub2`.`status` = '1' OR `sub2`.`status` = '2') - AND `sub2`.`adminid` = :adminid - ) as `ticketcountnotclosed` - FROM `" . TABLE_PANEL_TICKET_CATS . "` `main` - WHERE " . $where . $paging->getSqlWhere(true) . " " . - $paging->getSqlOrderBy() . " " . $paging->getSqlLimit() - ); - Database::pexecute($result_stmt, array('adminid' => $userinfo['adminid'])); - $numrows = Database::num_rows(); - $paging->setEntries($numrows); - $sortcode = $paging->getHtmlSortCode($lng); - $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); - $searchcode = $paging->getHtmlSearchCode($lng); - $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); - $i = 0; - $count = 0; - $ticketcategories = ''; - $categories_count = $numrows; - - while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { - - if ($paging->checkDisplay($i)) { - $row = htmlentities_array($row); - $closedtickets_count = ($row['ticketcount'] - $row['ticketcountnotclosed']); - eval("\$ticketcategories.=\"" . getTemplate("tickets/tickets_categories") . "\";"); - $count++; - } - $i++; - } - eval("echo \"" . getTemplate("tickets/categories") . "\";"); - - } elseif($action == 'addcategory') { - - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { - - $category = validate($_POST['category'], 'category'); - $order = validate($_POST['logicalorder'], 'logicalorder'); - - if ($order < 1 || $order >= 1000) { - // use the latest available - $order = ticket::getHighestOrderNumber($userinfo['adminid']) + 1; - } - - if ($category == '') { - standard_error(array('stringisempty', 'mycategory')); - } else { - ticket::addCategory($category, $userinfo['adminid'], $order); - $log->logAction(ADM_ACTION, LOG_INFO, "added ticket-category '" . $category . "'"); - redirectTo($filename, array('page' => $page, 's' => $s)); - } - } else { - $order = ticket::getHighestOrderNumber($userinfo['adminid']) + 1; - - $category_new_data = include_once dirname(__FILE__).'/lib/formfields/admin/tickets/formfield.category_new.php'; - $category_new_form = htmlform::genHTMLForm($category_new_data); - - $title = $category_new_data['category_new']['title']; - $image = $category_new_data['category_new']['image']; - - eval("echo \"" . getTemplate("tickets/tickets_newcategory") . "\";"); - } - - } elseif($action == 'editcategory' - && $id != 0 - ) { - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { - - $category = validate($_POST['category'], 'category'); - $order = validate($_POST['logicalorder'], 'logicalorder'); - - if ($order < 1 || $order >= 1000) { - $order = 1; - } - - if ($category == '') { - standard_error(array('stringisempty', 'mycategory')); - } else { - ticket::editCategory($category, $id, $order); - $log->logAction(ADM_ACTION, LOG_INFO, "edited ticket-category '" . $category . "'"); - redirectTo($filename, array('page' => $page, 's' => $s)); - } - } else { - $row_stmt = Database::prepare(' - SELECT * FROM `' . TABLE_PANEL_TICKET_CATS . '` WHERE `id` = :id' - ); - $row = Database::pexecute_first($row_stmt, array('id' => $id)); - $row = htmlentities_array($row); - $category_edit_data = include_once dirname(__FILE__).'/lib/formfields/admin/tickets/formfield.category_edit.php'; - $category_edit_form = htmlform::genHTMLForm($category_edit_data); - - $title = $category_edit_data['category_edit']['title']; - $image = $category_edit_data['category_edit']['image']; - - eval("echo \"" . getTemplate("tickets/tickets_editcategory") . "\";"); - } - - } elseif($action == 'deletecategory' - && $id != 0 - ) { - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { - if (ticket::deleteCategory($id) == false) { - standard_error('categoryhastickets'); - } - - $log->logAction(ADM_ACTION, LOG_INFO, "deleted ticket-category #" . $id); - redirectTo($filename, array('page' => $page, 's' => $s)); - - } else { - $name = ticket::getCategoryName($id); - ask_yesno('ticket_reallydeletecat', $filename, array('id' => $id, 'page' => $page, 'action' => $action), $name); - } - } - -} elseif($page == 'archive' - && $userinfo['customers'] != '0' -) { - if ($action == '') { - - $log->logAction(ADM_ACTION, LOG_NOTICE, "viewed admin_tickets::archive"); - - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { - $priority = array(); - $categories = array(); - $subject = validate($_POST['subject'], 'subject'); - $priority[0] = isset($_POST['priority1']) ? $_POST['priority1'] : ''; - $priority[1] = isset($_POST['priority2']) ? $_POST['priority2'] : ''; - $priority[2] = isset($_POST['priority3']) ? $_POST['priority3'] : ''; - $fromdate = validate($_POST['fromdate'], 'fromdate'); - $todate = validate($_POST['todate'], 'todate'); - $message = validate($_POST['message'], 'message'); - $customer = validate($_POST['customer'], 'customer'); - - $cat_stmt = Database::query('SELECT COUNT(`id`) as `ccount` FROM `' . TABLE_PANEL_TICKET_CATS . '`'); - $cat = $cat_stmt->fetch(PDO::FETCH_ASSOC); - - for ($x = 0;$x < $cat['ccount'];$x++) { - $categories[$x] = isset($_POST['category' . $x]) ? $_POST['category' . $x] : ''; - } - - $archive_search = ticket::getArchiveSearchStatement($subject, $priority, $fromdate, $todate, $message, $customer, $userinfo['adminid'], $categories); - - $query = $archive_search[0]; - $archive_params = $archive_search[1]; - - $fields = array( - 'lastchange' => $lng['ticket']['lastchange'], - 'subject' => $lng['ticket']['subject'], - 'lastreplier' => $lng['ticket']['lastreplier'] - ); - $paging = new paging($userinfo, TABLE_PANEL_TICKETS, $fields); - $result_stmt = Database::prepare($query . $paging->getSqlWhere(true) . " " . $paging->getSqlOrderBy() . " " . $paging->getSqlLimit()); - Database::pexecute($result_stmt, $archive_params); - $sortcode = $paging->getHtmlSortCode($lng); - $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); - $searchcode = $paging->getHtmlSearchCode($lng); - $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); - $ctickets = array(); - - while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { - if (!isset($ctickets[$row['customerid']]) - || !is_array($ctickets[$row['customerid']]) - ) { - $ctickets[$row['customerid']] = array(); - } - $ctickets[$row['customerid']][$row['id']] = $row; - } - - if ($paging->sortfield == 'customerid' - && $paging->sortorder == 'desc' - ) { - krsort($ctickets); - } else { - ksort($ctickets); - } - - $i = 0; - $count = 0; - $tickets_count = 0; - $tickets = ''; - foreach ($ctickets as $cid => $ticketrows) { - if ($paging->sortfield == 'lastchange' - && $paging->sortorder == 'desc' - ) { - krsort($ticketrows); - } else { - ksort($ticketrows); - } - - $_cid = -1; - foreach ($ticketrows as $ticket) { - if ($paging->checkDisplay($i)) { - $ticket['lastchange'] = date("d.m.y H:i", $ticket['lastchange']); - if ($_cid != $ticket['customerid']) { - $cid = $ticket['customerid']; - $usr_stmt = Database::prepare(' - SELECT `customerid`, `firstname`, `name`, `company`, `loginname` - FROM `' . TABLE_PANEL_CUSTOMERS . '` - WHERE `customerid` = :cid' - ); - $usr = Database::pexecute_first($usr_stmt, array('cid' => $cid)); - - if (isset($usr['loginname'])) { - $customer = getCorrectFullUserDetails($usr); - $customerloginname = $usr['loginname']; - $customerid = $usr['customerid']; - } else { - $customer = $lng['ticket']['nonexistingcustomer']; - $customerid = 0; - $customerloginname = ''; - } - eval("\$tickets.=\"" . getTemplate("tickets/tickets_customer") . "\";"); - } - - $tickets_count++; - switch ($ticket['priority']) - { - case 1: $ticket['display'] = 'high'; - break; - case 2: $ticket['display'] = 'normal'; - break; - case 3: $ticket['display'] = 'low'; - break; - default: $ticket['display'] = 'unknown'; - } - $ticket['priority'] = ticket::getPriorityText($lng, $ticket['priority']); - - if ($ticket['lastreplier'] == '1') { - $ticket['lastreplier'] = $lng['ticket']['staff']; - } else { - $ticket['lastreplier'] = $lng['ticket']['customer']; - } - - if (strlen($ticket['subject']) > 20) { - $ticket['subject'] = substr($ticket['subject'], 0, 17) . '...'; - } - $ticket = htmlentities_array($ticket); - eval("\$tickets.=\"" . getTemplate("tickets/archived_tickets") . "\";"); - $count++; - $_cid = $ticket['customerid']; - } - } - $i++; - } - eval("echo \"" . getTemplate("tickets/archivesearch") . "\";"); - - } else { - - $archived = array(); - $archived = ticket::getLastArchived(6, $userinfo['adminid']); - $tickets = ''; - - if ($archived !== false) { - - foreach ($archived as $id => $ticket) { - - $ticket['lastchange'] = date("d.m.y H:i", $ticket['lastchange']); - $ticket['priority'] = ticket::getPriorityText($lng, $ticket['priority']); - - if ($ticket['lastreplier'] == '1') { - $ticket['lastreplier'] = $lng['ticket']['staff']; - } else { - $ticket['lastreplier'] = $lng['ticket']['customer']; - } - - if (strlen($ticket['subject']) > 20) { - $ticket['subject'] = substr($ticket['subject'], 0, 17) . '...'; - } - eval("\$tickets.=\"" . getTemplate("tickets/archived_tickets") . "\";"); - } - } - - $priorities_options = makecheckbox('priority1', $lng['ticket']['high'], '1'); - $priorities_options.= makecheckbox('priority2', $lng['ticket']['normal'], '2'); - $priorities_options.= makecheckbox('priority3', $lng['ticket']['low'], '3'); - $category_options = ''; - $ccount = 0; - $result = Database::query('SELECT * FROM `' . TABLE_PANEL_TICKET_CATS . '` ORDER BY `name` ASC'); - - while ($row = $result->fetch(PDO::FETCH_ASSOC)) { - $category_options.= makecheckbox('category' . $ccount, $row['name'], $row['id'], true); - $ccount++; - } - - $customers = makeoption($lng['ticket']['nocustomer'], '-1', '-1'); - $result_customers_stmt = Database::prepare(" - SELECT `customerid`, `loginname`, `name`, `firstname`, `company` - FROM `" . TABLE_PANEL_CUSTOMERS . "` " . - ($userinfo['customers_see_all'] ? '' : " WHERE `adminid` = :adminid")." - ORDER BY `name` ASC" - ); - Database::pexecute($result_customers_stmt, array('adminid' => $userinfo['adminid'])); - - while ($row_customer = $result_customers_stmt->fetch(PDO::FETCH_ASSOC)) { - $customers.= makeoption(getCorrectFullUserDetails($row_customer) . ' (' . $row_customer['loginname'] . ')', $row_customer['customerid']); - } - eval("echo \"" . getTemplate("tickets/archive") . "\";"); - } - - } elseif($action == 'view' - && $id != 0 - ) { - $log->logAction(ADM_ACTION, LOG_NOTICE, "viewed archived-ticket #" . $id); - $ticket_replies = ''; - $mainticket = ticket::getInstanceOf($userinfo, (int)$id); - $lastchange = date("d.m.Y H:i\h", $mainticket->Get('lastchange')); - $dt = date("d.m.Y H:i\h", $mainticket->Get('dt')); - $status = ticket::getStatusText($lng, $mainticket->Get('status')); - $isclosed = 1; - - if ($mainticket->Get('by') == '1') { - $by = $lng['ticket']['staff']; - } else { - $cid = $mainticket->Get('customer'); - $usr_stmt = Database::prepare(' - SELECT `customerid`, `firstname`, `name`, `company`, `loginname` - FROM `' . TABLE_PANEL_CUSTOMERS . '` - WHERE `customerid` = :cid' - ); - $usr = Database::pexecute_first($usr_stmt, array('cid' => $cid)); - - if (isset($usr['loginname'])) { - $customer = getCorrectFullUserDetails($usr); - $customerloginname = ' ('.$usr['loginname'].')'; - $customerid = $usr['customerid']; - } else { - $customer = $lng['ticket']['nonexistingcustomer']; - $customerid = 0; - $customerloginname = ''; - } - if ($customerid != 0) { - $by = ''; - $by .= $customer.$customerloginname.''; - } else { - $by = $customer; - } - } - - $subject = $mainticket->Get('subject'); - $message = $mainticket->Get('message'); - eval("\$ticket_replies.=\"" . getTemplate("tickets/tickets_tickets_main") . "\";"); - - $result_stmt = Database::prepare(' - SELECT `name` FROM `' . TABLE_PANEL_TICKET_CATS . '` WHERE `id` = :cid' - ); - $row = Database::pexecute_first($result_stmt, array('cid' => $mainticket->Get('category'))); - - $andere_stmt = Database::prepare(' - SELECT * FROM `' . TABLE_PANEL_TICKETS . '` WHERE `answerto` = :id' - ); - Database::pexecute($andere_stmt, array('id' => $id)); - $numrows_andere = Database::num_rows(); - - while ($row2 = $andere_stmt->fetch(PDO::FETCH_ASSOC)) { - $subticket = ticket::getInstanceOf($userinfo, (int)$row2['id']); - $lastchange = date("d.m.Y H:i\h", $subticket->Get('lastchange')); - - if ($subticket->Get('by') == '1') { - $by = $lng['ticket']['staff']; - } else { - $cid = $subticket->Get('customer'); - $usr_stmt = Database::prepare(' - SELECT `customerid`, `firstname`, `name`, `company`, `loginname` - FROM `' . TABLE_PANEL_CUSTOMERS . '` - WHERE `customerid` = :cid' - ); - $usr = Database::pexecute_first($usr_stmt, array('cid' => $cid)); - - if (isset($usr['loginname'])) { - $customer = getCorrectFullUserDetails($usr); - $customerloginname = ' ('.$usr['loginname'].')'; - $customerid = $usr['customerid']; - } else { - $customer = $lng['ticket']['nonexistingcustomer']; - $customerid = 0; - $customerloginname = ''; - } - if ($customerid != 0) { - $by = ''; - $by .= $customer.$customerloginname.''; - } else { - $by = $customer; - } - } - - $subject = $subticket->Get('subject'); - $message = $subticket->Get('message'); - eval("\$ticket_replies.=\"" . getTemplate("tickets/tickets_tickets_list") . "\";"); - } - - $priorities = makeoption($lng['ticket']['high'], '1', htmlentities($mainticket->Get('priority')), true, true); - $priorities.= makeoption($lng['ticket']['normal'], '2', htmlentities($mainticket->Get('priority')), true, true); - $priorities.= makeoption($lng['ticket']['low'], '3', htmlentities($mainticket->Get('priority')), true, true); - $subject = $mainticket->Get('subject'); - $ticket_replies_count = $numrows_andere + 1; - - // don't forget the main-ticket! - eval("echo \"" . getTemplate("tickets/tickets_view") . "\";"); - - } elseif($action == 'delete' - && $id != 0 - ) { - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { - $mainticket = ticket::getInstanceOf($userinfo, (int)$id); - $log->logAction(ADM_ACTION, LOG_INFO, "deleted archived ticket '" . $mainticket->Get('subject') . "'"); - $mainticket->Delete(); - redirectTo($filename, array('page' => $page, 's' => $s)); - } else { - $mainticket = ticket::getInstanceOf($userinfo, (int)$id); - ask_yesno('ticket_reallydelete', $filename, array('id' => $id, 'page' => $page, 'action' => $action), $mainticket->Get('subject')); - } - } -} else { - standard_error('nocustomerforticket'); -} diff --git a/admin_traffic.php b/admin_traffic.php index fdf8b6da..a7f22f4f 100644 --- a/admin_traffic.php +++ b/admin_traffic.php @@ -15,23 +15,15 @@ * @package Panel * */ - define('AREA', 'admin'); require './lib/init.php'; -if ($action == 'logout') { - $logout_stmt = Database::prepare(" - DELETE FROM `" . TABLE_PANEL_SESSIONS . "` - WHERE `userid` = :adminid - AND `adminsession` = '1'" - ); - Database::pexecute($logout_stmt, array('adminid' => $userinfo['adminid'])); - redirectTo('index.php'); -} +use Froxlor\Database\Database; +use Froxlor\Settings; if (isset($_POST['id'])) { $id = intval($_POST['id']); -} elseif(isset($_GET['id'])) { +} elseif (isset($_GET['id'])) { $id = intval($_GET['id']); } @@ -48,52 +40,52 @@ $months = array( '9' => 'sep', '10' => 'oct', '11' => 'nov', - '12' => 'dec', + '12' => 'dec' ); if ($page == 'overview' || $page == 'customers') { $customerview = 1; $stats_tables = ''; - $minyear_stmt = Database::query("SELECT `year` FROM `". TABLE_PANEL_TRAFFIC . "` ORDER BY `year` ASC LIMIT 1"); + $minyear_stmt = Database::query("SELECT `year` FROM `" . TABLE_PANEL_TRAFFIC . "` ORDER BY `year` ASC LIMIT 1"); $minyear = $minyear_stmt->fetch(PDO::FETCH_ASSOC); - if (!isset($minyear['year']) || $minyear['year'] == 0) { + if (! isset($minyear['year']) || $minyear['year'] == 0) { $maxyears = 0; } else { $maxyears = date("Y") - $minyear['year']; } - for ($years = 0; $years<=$maxyears; $years++) { + for ($years = 0; $years <= $maxyears; $years ++) { - $overview['year'] = date("Y")-$years; + $overview['year'] = date("Y") - $years; $overview['type'] = $lng['traffic']['customer']; $domain_list = ''; $totals = array( - 'jan' => 0, - 'feb' => 0, - 'mar' => 0, - 'apr' => 0, - 'may' => 0, - 'jun' => 0, - 'jul' => 0, - 'aug' => 0, - 'sep' => 0, - 'oct' => 0, - 'nov' => 0, - 'dec' => 0, + 'jan' => 0, + 'feb' => 0, + 'mar' => 0, + 'apr' => 0, + 'may' => 0, + 'jun' => 0, + 'jul' => 0, + 'aug' => 0, + 'sep' => 0, + 'oct' => 0, + 'nov' => 0, + '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'])); + WHERE `deactivated`='0'" . ($userinfo['customers_see_all'] ? '' : " AND `adminid` = :id") . " + ORDER BY name"); + Database::pexecute($customer_name_list_stmt, array( + 'id' => $userinfo['adminid'] + )); - while($customer_name = $customer_name_list_stmt->fetch(PDO::FETCH_ASSOC)) { + while ($customer_name = $customer_name_list_stmt->fetch(PDO::FETCH_ASSOC)) { $virtual_host = array( 'name' => ($customer_name['company'] == '' ? $customer_name['name'] . ", " . $customer_name['firstname'] : $customer_name['company']), @@ -109,33 +101,35 @@ if ($page == 'overview' || $page == 'customers') { 'sep' => '-', 'oct' => '-', 'nov' => '-', - 'dec' => '-', + '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'])); + GROUP BY month ORDER BY month"); + Database::pexecute($traffic_list_stmt, array( + 'year' => (date("Y") - $years), + 'id' => $customer_name['customerid'] + )); while ($traffic_month = $traffic_list_stmt->fetch(PDO::FETCH_ASSOC)) { - $virtual_host[$months[(int)$traffic_month['month']]] = size_readable($traffic_month['traffic'], 'GiB', 'bi', '%01.'.(int)Settings::Get('panel.decimal_places').'f %s'); - $totals[$months[(int)$traffic_month['month']]] += $traffic_month['traffic']; + $virtual_host[$months[(int) $traffic_month['month']]] = \Froxlor\PhpHelper::sizeReadable($traffic_month['traffic'], 'GiB', 'bi', '%01.' . (int) Settings::Get('panel.decimal_places') . 'f %s'); + $totals[$months[(int) $traffic_month['month']]] += $traffic_month['traffic']; } - eval("\$domain_list .= sprintf(\"%s\", \"" . getTemplate("traffic/index_table_row") . "\");"); + eval("\$domain_list .= sprintf(\"%s\", \"" . \Froxlor\UI\Template::getTemplate("traffic/index_table_row") . "\");"); } // sum up totals $virtual_host = array( - 'name' => $lng['traffic']['months']['total'], + 'name' => $lng['traffic']['months']['total'] ); foreach ($totals as $month => $bytes) { - $virtual_host[$month] = ($bytes == 0 ? '-' : size_readable($bytes, 'GiB', 'bi', '%01.'.(int)Settings::Get('panel.decimal_places').'f %s')); + $virtual_host[$month] = ($bytes == 0 ? '-' : \Froxlor\PhpHelper::sizeReadable($bytes, 'GiB', 'bi', '%01.' . (int) Settings::Get('panel.decimal_places') . 'f %s')); } $customerview = 0; - eval("\$total_list = sprintf(\"%s\", \"" . getTemplate("traffic/index_table_row") . "\");"); - eval("\$stats_tables .= sprintf(\"%s\", \"" . getTemplate("traffic/index_table") . "\");"); + eval("\$total_list = sprintf(\"%s\", \"" . \Froxlor\UI\Template::getTemplate("traffic/index_table_row") . "\");"); + eval("\$stats_tables .= sprintf(\"%s\", \"" . \Froxlor\UI\Template::getTemplate("traffic/index_table") . "\");"); } - eval("echo \"" . getTemplate("traffic/index") . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("traffic/index") . "\";"); } diff --git a/admin_updates.php b/admin_updates.php index a7398b08..2b0e3420 100644 --- a/admin_updates.php +++ b/admin_updates.php @@ -14,27 +14,25 @@ * @package Panel * */ - define('AREA', 'admin'); require './lib/init.php'; +use Froxlor\Database\Database; +use Froxlor\Settings; + if ($page == 'overview') { - $log->logAction(ADM_ACTION, LOG_NOTICE, "viewed admin_updates"); + $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "viewed admin_updates"); /** * this is a dirty hack but syscp 1.4.2.1 does not * have any version/dbversion in the database (don't know why) * so we have to set them both to run a correct upgrade */ - if (!isFroxlor()) { - if (Settings::Get('panel.version') == null - || Settings::Get('panel.version') == '' - ) { + if (! \Froxlor\Froxlor::isFroxlor()) { + if (Settings::Get('panel.version') == null || Settings::Get('panel.version') == '') { Settings::Set('panel.version', '1.4.2.1'); } - if (Settings::Get('system.dbversion') == null - || Settings::Get('system.dbversion') == '' - ) { + if (Settings::Get('system.dbversion') == null || Settings::Get('system.dbversion') == '') { /** * for syscp-stable (1.4.2.1) this value has to be 0 * so the required table-fields are added correctly @@ -42,40 +40,33 @@ if ($page == 'overview') { * -> bug #54 */ $result_stmt = Database::query(" - SELECT `value` FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `varname` = 'dbversion'" - ); + SELECT `value` FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `varname` = 'dbversion'"); $result = $result_stmt->fetch(PDO::FETCH_ASSOC); if (isset($result['value'])) { - Settings::Set('system.dbversion', (int)$result['value'], false); + Settings::Set('system.dbversion', (int) $result['value'], false); } else { Settings::Set('system.dbversion', 0, false); } } } - if (hasDbUpdates($dbversion)) { + if (\Froxlor\Froxlor::hasDbUpdates() || \Froxlor\Froxlor::hasUpdates()) { $successful_update = false; $message = ''; - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { - if ((isset($_POST['update_preconfig']) - && isset($_POST['update_changesagreed']) - && intval($_POST['update_changesagreed']) != 0) - || !isset($_POST['update_preconfig']) - ) { - eval("echo \"" . getTemplate('update/update_start') . "\";"); + if (isset($_POST['send']) && $_POST['send'] == 'send') { + if ((isset($_POST['update_preconfig']) && isset($_POST['update_changesagreed']) && intval($_POST['update_changesagreed']) != 0) || ! isset($_POST['update_preconfig'])) { + eval("echo \"" . \Froxlor\UI\Template::getTemplate('update/update_start') . "\";"); - include_once './install/updatesql.php'; + include_once \Froxlor\Froxlor::getInstallDir() . 'install/updatesql.php'; $redirect_url = 'admin_index.php?s=' . $s; - eval("echo \"" . getTemplate('update/update_end') . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate('update/update_end') . "\";"); - updateCounters(); - inserttask('1'); - @chmod('./lib/userdata.inc.php', 0440); + \Froxlor\User::updateCounters(); + \Froxlor\System\Cronjob::inserttask('1'); + @chmod(\Froxlor\Froxlor::getInstallDir() . '/lib/userdata.inc.php', 0440); $successful_update = true; } else { @@ -83,27 +74,27 @@ if ($page == 'overview') { } } - if (!$successful_update) { + if (! $successful_update) { $current_version = Settings::Get('panel.version'); $current_db_version = Settings::Get('panel.db_version'); if (empty($current_db_version)) { - $current_db_version = "0"; + $current_db_version = "0"; } $new_version = $version; $new_db_version = $dbversion; $ui_text = $lng['update']['update_information']['part_a']; if ($version != $current_version) { - $ui_text = str_replace('%curversion', $current_version, $ui_text); - $ui_text = str_replace('%newversion', $new_version, $ui_text); + $ui_text = str_replace('%curversion', $current_version, $ui_text); + $ui_text = str_replace('%newversion', $new_version, $ui_text); } else { - // show db version - $ui_text = str_replace('%curversion', $current_db_version, $ui_text); - $ui_text = str_replace('%newversion', $new_db_version, $ui_text); + // show db version + $ui_text = str_replace('%curversion', $current_db_version, $ui_text); + $ui_text = str_replace('%newversion', $new_db_version, $ui_text); } $update_information = $ui_text; - include_once './install/updates/preconfig.php'; + include_once \Froxlor\Froxlor::getInstallDir() . '/install/updates/preconfig.php'; $preconfig = getPreConfig($current_version, $current_db_version); if ($preconfig != '') { $update_information .= '
' . $preconfig . $message; @@ -111,11 +102,11 @@ if ($page == 'overview') { $update_information .= $lng['update']['update_information']['part_b']; - eval("echo \"" . getTemplate('update/index') . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate('update/index') . "\";"); } } else { $success_message = $lng['update']['noupdatesavail']; $redirect_url = 'admin_index.php?s=' . $s; - eval("echo \"" . getTemplate('update/noupdatesavail') . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate('update/noupdatesavail') . "\";"); } } diff --git a/api.php b/api.php new file mode 100644 index 00000000..3409a492 --- /dev/null +++ b/api.php @@ -0,0 +1,88 @@ +xss_clean($request); + +// validate content +try { + $decoded_request = stripcslashes_deep($decoded_request); + $request = \Froxlor\Api\FroxlorRPC::validateRequest($decoded_request); + // now actually do it + $cls = "\\Froxlor\\Api\\Commands\\" . $request['command']['class']; + $method = $request['command']['method']; + $apiObj = new $cls($decoded_request['header'], $request['params']); + // call the method with the params if any + echo $apiObj->$method(); +} catch (Exception $e) { + json_response($e->getCode(), $e->getMessage()); +} + +exit(); + +/** + * output json result + * + * @param int $status + * @param string $status_message + * @param mixed $data + * + * @return void + */ +function json_response($status, $status_message = '', $data = null) +{ + if (isset($_SERVER["SERVER_PROTOCOL"]) && ! empty($_SERVER["SERVER_PROTOCOL"])) { + $resheader = $_SERVER["SERVER_PROTOCOL"] . " " . $status; + if (! empty($status_message)) { + $resheader .= ' ' . str_replace("\n", " ", $status_message); + } + header($resheader); + } + $response = array(); + $response['status'] = $status; + $response['status_message'] = $status_message; + $response['data'] = $data; + + $json_response = json_encode($response, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT); + echo $json_response; + exit(); +} + +function stripcslashes_deep($value) +{ + return is_array($value) ? array_map('stripcslashes_deep', $value) : stripcslashes($value); +} diff --git a/api_keys.php b/api_keys.php new file mode 100644 index 00000000..0c3126e5 --- /dev/null +++ b/api_keys.php @@ -0,0 +1,235 @@ + (2018-) + * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt + * @package Panel + * @since 0.10.0 + * + */ + +use Froxlor\Database\Database; + +// This file is being included in admin_index and customer_index +// and therefore does not need to require lib/init.php + +$del_stmt = Database::prepare("DELETE FROM `" . TABLE_API_KEYS . "` WHERE id = :id"); +$success_message = ""; +$id = isset($_GET['id']) ? (int) $_GET['id'] : 0; +$area = AREA; + +// do the delete and then just show a success-message and the apikeys list again +if ($action == 'delete') { + if ($id > 0) { + $chk = (AREA == 'admin' && $userinfo['customers_see_all'] == '1') ? true : false; + if (AREA == 'customer') { + $chk_stmt = Database::prepare(" + SELECT c.customerid FROM `" . TABLE_PANEL_CUSTOMERS . "` c + LEFT JOIN `" . TABLE_API_KEYS . "` ak ON ak.customerid = c.customerid + WHERE ak.`id` = :id AND c.`customerid` = :cid + "); + $chk = Database::pexecute_first($chk_stmt, array( + 'id' => $id, + 'cid' => $userinfo['customerid'] + )); + } elseif (AREA == 'admin' && $userinfo['customers_see_all'] == '0') { + $chk_stmt = Database::prepare(" + SELECT a.adminid FROM `" . TABLE_PANEL_ADMINS . "` a + LEFT JOIN `" . TABLE_API_KEYS . "` ak ON ak.adminid = a.adminid + WHERE ak.`id` = :id AND a.`adminid` = :aid + "); + $chk = Database::pexecute_first($chk_stmt, array( + 'id' => $id, + 'aid' => $userinfo['adminid'] + )); + } + if ($chk !== false) { + Database::pexecute($del_stmt, array( + 'id' => $id + )); + $success_message = sprintf($lng['apikeys']['apikey_removed'], $id); + } + } +} elseif ($action == 'add') { + $ins_stmt = Database::prepare(" + INSERT INTO `" . TABLE_API_KEYS . "` SET + `apikey` = :key, `secret` = :secret, `adminid` = :aid, `customerid` = :cid, `valid_until` = '-1', `allowed_from` = '' + "); + // customer generates for himself, admins will see a customer-select-box later + if (AREA == 'admin') { + $cid = 0; + } elseif (AREA == 'customer') { + $cid = $userinfo['customerid']; + } + $key = hash('sha256', openssl_random_pseudo_bytes(64 * 64)); + $secret = hash('sha512', openssl_random_pseudo_bytes(64 * 64 * 4)); + Database::pexecute($ins_stmt, array( + 'key' => $key, + 'secret' => $secret, + 'aid' => $userinfo['adminid'], + 'cid' => $cid + )); + $success_message = $lng['apikeys']['apikey_added']; +} elseif ($action == 'jqEditApiKey') { + $keyid = isset($_POST['id']) ? (int) $_POST['id'] : 0; + $allowed_from = isset($_POST['allowed_from']) ? $_POST['allowed_from'] : ""; + $valid_until = isset($_POST['valid_until']) ? (int) $_POST['valid_until'] : - 1; + + // validate allowed_from + if (! empty($allowed_from)) { + $ip_list = array_map('trim', explode(",", $allowed_from)); + $_check_list = $ip_list; + foreach ($_check_list as $idx => $ip) { + if (\Froxlor\Validate\Validate::validate_ip2($ip, true, 'invalidip', true, true) == false) { + unset($ip_list[$idx]); + } + } + $ip_list = array_map('inet_ntop', array_map('inet_pton', $ip_list)); + $allowed_from = implode(",", array_unique($ip_list)); + } + + if ($valid_until <= 0 || ! is_numeric($valid_until)) { + $valid_until = - 1; + } + + $upd_stmt = Database::prepare(" + UPDATE `" . TABLE_API_KEYS . "` SET + `valid_until` = :vu, `allowed_from` = :af + WHERE `id` = :keyid AND `adminid` = :aid AND `customerid` = :cid + "); + if (AREA == 'admin') { + $cid = 0; + } elseif (AREA == 'customer') { + $cid = $userinfo['customerid']; + } + Database::pexecute($upd_stmt, array( + 'keyid' => $keyid, + 'af' => $allowed_from, + 'vu' => $valid_until, + 'aid' => $userinfo['adminid'], + 'cid' => $cid + )); + echo json_encode(true); + exit(); +} + +$log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed api::api_keys"); + +// select all my (accessable) 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` + LEFT JOIN `" . TABLE_PANEL_ADMINS . "` a ON `a`.`adminid` = `ak`.`adminid` + WHERE "; + +$qry_params = array(); +if (AREA == 'admin' && $userinfo['customers_see_all'] == '0') { + // admin with only customer-specific permissions + $keys_stmt_query .= "ak.adminid = :adminid "; + $qry_params['adminid'] = $userinfo['adminid']; + $fields = array( + 'a.loginname' => $lng['login']['username'] + ); +} elseif (AREA == 'customer') { + // customer-area + $keys_stmt_query .= "ak.customerid = :cid "; + $qry_params['cid'] = $userinfo['customerid']; + $fields = array( + 'c.loginname' => $lng['login']['username'] + ); +} else { + // admin who can see all customers / reseller / admins + $keys_stmt_query .= "1 "; + $fields = array( + 'a.loginname' => $lng['login']['username'] + ); +} + +$paging = new \Froxlor\UI\Paging($userinfo, TABLE_API_KEYS, $fields); +$keys_stmt_query .= $paging->getSqlWhere(true) . " " . $paging->getSqlOrderBy() . " " . $paging->getSqlLimit(); + +$keys_stmt = Database::prepare($keys_stmt_query); +Database::pexecute($keys_stmt, $qry_params); +$all_keys = $keys_stmt->fetchAll(PDO::FETCH_ASSOC); +$apikeys = ""; + +if (count($all_keys) == 0) { + $count = 0; + $message = $lng['apikeys']['no_api_keys']; + $sortcode = ""; + $searchcode = ""; + $pagingcode = ""; + eval("\$apikeys.=\"" . \Froxlor\UI\Template::getTemplate("api_keys/keys_error", true) . "\";"); +} else { + $count = count($all_keys); + $paging->setEntries($count); + $sortcode = $paging->getHtmlSortCode($lng); + $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); + $searchcode = $paging->getHtmlSearchCode($lng); + $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); + + foreach ($all_keys as $idx => $key) { + if ($paging->checkDisplay($idx)) { + + // my own key + $isMyKey = false; + if ($key['adminid'] == $userinfo['adminid'] && ((AREA == 'admin' && $key['customerid'] == 0) || (AREA == 'customer' && $key['customerid'] == $userinfo['customerid']))) { + // this is mine + $isMyKey = true; + } + + $adminCustomerLink = ""; + if (AREA == 'admin') { + if ($isMyKey) { + $adminCustomerLink = $key['adminname']; + } else { + $adminCustomerLink = '' . (empty($key['customerid']) ? $key['adminname'] : $key['loginname']) . ''; + } + } else { + // customer do not need links + $adminCustomerLink = $key['loginname']; + } + + // escape stuff + $row = \Froxlor\PhpHelper::htmlentitiesArray($key); + + // shorten keys + $row['_apikey'] = substr($row['apikey'], 0, 20) . '...'; + $row['_secret'] = substr($row['secret'], 0, 20) . '...'; + + // check whether the api key is not valid anymore + $isValid = true; + if ($row['valid_until'] >= 0) { + if ($row['valid_until'] < time()) { + $isValid = false; + } + // format + $row['valid_until'] = date('Y-m-d', $row['valid_until']); + } else { + // infinity + $row['valid_until'] = ""; + } + eval("\$apikeys.=\"" . \Froxlor\UI\Template::getTemplate("api_keys/keys_key", true) . "\";"); + } else { + continue; + } + } +} +eval("echo \"" . \Froxlor\UI\Template::getTemplate("api_keys/keys_list", true) . "\";"); diff --git a/build.xml b/build.xml new file mode 100644 index 00000000..e489f847 --- /dev/null +++ b/build.xml @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/composer.json b/composer.json new file mode 100644 index 00000000..f05f9c02 --- /dev/null +++ b/composer.json @@ -0,0 +1,81 @@ +{ + "name": "froxlor/froxlor", + "description": "The server administration software for your needs. Developed by experienced server administrators, this panel simplifies the effort of managing your hosting platform.", + "keywords": [ + "server", + "administration", + "php" + ], + "homepage": "https://www.froxlor.org", + "license": "GPL-2.0-or-later", + "authors": [ + { + "name": "Michael Kaufmann", + "email": "team@froxlor.org", + "role": "Lead Developer" + }, + { + "name": "Robert Förster", + "email": "team@froxlor.org", + "role": "Package Maintainer" + } + ], + "support": { + "email": "team@froxlor.org", + "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", + "source": "https://github.com/Froxlor/Froxlor", + "docs": "https://github.com/Froxlor/Froxlor/wiki" + }, + "require": { + "php": ">=7.1", + "ext-session": "*", + "ext-ctype": "*", + "ext-pdo": "*", + "ext-pdo_mysql": "*", + "ext-simplexml": "*", + "ext-xml": "*", + "ext-filter": "*", + "ext-posix": "*", + "ext-mbstring": "*", + "ext-curl": "*", + "ext-json": "*", + "ext-openssl": "*", + "phpmailer/phpmailer": "~6.0", + "monolog/monolog": "^1.24", + "robthree/twofactorauth": "^1.6", + "froxlor/idna-convert-legacy": "^2.1", + "voku/anti-xss": "^4.1" + }, + "require-dev": { + "phpunit/phpunit": "8.4.1", + "php": ">=7.3", + "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" + }, + "suggest": { + "ext-bcmath": "*", + "ext-zip": "*", + "ext-apcu": "*", + "ext-readline": "*" + }, + "autoload": { + "psr-4": { + "Froxlor\\": [ + "lib/Froxlor" + ] + } + }, + "scripts": { + "post-install-cmd": "if [ -f ./vendor/bin/phpcs ]; then \"vendor/bin/phpcs\" --config-set installed_paths vendor/phpcompatibility/php-compatibility ; fi", + "post-update-cmd" : "if [ -f ./vendor/bin/phpcs ]; then \"vendor/bin/phpcs\" --config-set installed_paths vendor/phpcompatibility/php-compatibility ; fi" + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 00000000..6d5c739e --- /dev/null +++ b/composer.lock @@ -0,0 +1,4240 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "6b4d603703c6ace66f732d1abff8e2f3", + "packages": [ + { + "name": "froxlor/idna-convert-legacy", + "version": "v2.1.2", + "source": { + "type": "git", + "url": "https://github.com/Froxlor/idna-convert-legacy.git", + "reference": "09c1db623ba19e1ed8f2f9dabc15eeda9dc713b7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Froxlor/idna-convert-legacy/zipball/09c1db623ba19e1ed8f2f9dabc15eeda9dc713b7", + "reference": "09c1db623ba19e1ed8f2f9dabc15eeda9dc713b7", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "php": ">=5.6.0" + }, + "suggest": { + "ext-iconv": "Install ext/iconv for using input / output other than UTF-8 or ISO-8859-1", + "ext-mbstring": "Install ext/mbstring for using input / output other than UTF-8 or ISO-8859-1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Algo26\\IdnaConvert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1+" + ], + "authors": [ + { + "name": "Matthias Sommerfeld", + "email": "matthias.sommerfeld@algo26.de", + "role": "Developer" + }, + { + "name": "Michael Kaufmann (d00p)", + "email": "d00p@froxlor.org", + "role": "Developer" + } + ], + "description": "A library for encoding and decoding internationalized domain names", + "homepage": "http://idnaconv.net/", + "keywords": [ + "idn", + "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.26.0", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "2209ddd84e7ef1256b7af205d0717fb62cfc9c33" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/2209ddd84e7ef1256b7af205d0717fb62cfc9c33", + "reference": "2209ddd84e7ef1256b7af205d0717fb62cfc9c33", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "psr/log": "~1.0" + }, + "provide": { + "psr/log-implementation": "1.0.0" + }, + "require-dev": { + "aws/aws-sdk-php": "^2.4.9 || ^3.0", + "doctrine/couchdb": "~1.0@dev", + "graylog2/gelf-php": "~1.0", + "php-amqplib/php-amqplib": "~2.4", + "php-console/php-console": "^3.1.3", + "phpstan/phpstan": "^0.12.59", + "phpunit/phpunit": "~4.5", + "ruflin/elastica": ">=0.90 <3.0", + "sentry/sentry": "^0.13", + "swiftmailer/swiftmailer": "^5.3|^6.0" + }, + "suggest": { + "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", + "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-mongo": "Allow sending log messages to a MongoDB server", + "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", + "mongodb/mongodb": "Allow sending log messages to a MongoDB server via PHP Driver", + "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", + "php-console/php-console": "Allow sending log messages to Google Chrome", + "rollbar/rollbar": "Allow sending log messages to Rollbar", + "ruflin/elastica": "Allow sending log messages to an Elastic Search server", + "sentry/sentry": "Allow sending log messages to a Sentry server" + }, + "type": "library", + "autoload": { + "psr-4": { + "Monolog\\": "src/Monolog" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Sends your logs to files, sockets, inboxes, databases and various web services", + "homepage": "http://github.com/Seldaek/monolog", + "keywords": [ + "log", + "logging", + "psr-3" + ], + "support": { + "issues": "https://github.com/Seldaek/monolog/issues", + "source": "https://github.com/Seldaek/monolog/tree/1.26.0" + }, + "funding": [ + { + "url": "https://github.com/Seldaek", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/monolog/monolog", + "type": "tidelift" + } + ], + "time": "2020-12-14T12:56:38+00:00" + }, + { + "name": "phpmailer/phpmailer", + "version": "v6.2.0", + "source": { + "type": "git", + "url": "https://github.com/PHPMailer/PHPMailer.git", + "reference": "e38888a75c070304ca5514197d4847a59a5c853f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/e38888a75c070304ca5514197d4847a59a5c853f", + "reference": "e38888a75c070304ca5514197d4847a59a5c853f", + "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", + "phpcompatibility/php-compatibility": "^9.3.5", + "roave/security-advisories": "dev-latest", + "squizlabs/php_codesniffer": "^3.5.6", + "yoast/phpunit-polyfills": "^0.2.0" + }, + "suggest": { + "ext-mbstring": "Needed to send email in multibyte encoding charset", + "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", + "league/oauth2-google": "Needed for Google XOAUTH2 authentication", + "psr/log": "For optional PSR-3 debug logging", + "stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication", + "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHPMailer\\PHPMailer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1-only" + ], + "authors": [ + { + "name": "Marcus Bointon", + "email": "phpmailer@synchromedia.co.uk" + }, + { + "name": "Jim Jagielski", + "email": "jimjag@gmail.com" + }, + { + "name": "Andy Prevost", + "email": "codeworxtech@users.sourceforge.net" + }, + { + "name": "Brent R. Matzelle" + } + ], + "description": "PHPMailer is a full-featured email creation and transfer class for PHP", + "support": { + "issues": "https://github.com/PHPMailer/PHPMailer/issues", + "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.2.0" + }, + "funding": [ + { + "url": "https://github.com/Synchro", + "type": "github" + } + ], + "time": "2020-11-25T15:24:57+00:00" + }, + { + "name": "psr/log", + "version": "1.1.3", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc", + "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/1.1.3" + }, + "time": "2020-03-23T09:12:05+00:00" + }, + { + "name": "robthree/twofactorauth", + "version": "1.7.0", + "source": { + "type": "git", + "url": "https://github.com/RobThree/TwoFactorAuth.git", + "reference": "37983bf675c5baca09d19d6705170489d0df0002" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/RobThree/TwoFactorAuth/zipball/37983bf675c5baca09d19d6705170489d0df0002", + "reference": "37983bf675c5baca09d19d6705170489d0df0002", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "require-dev": { + "phpunit/phpunit": "@stable" + }, + "type": "library", + "autoload": { + "psr-4": { + "RobThree\\Auth\\": "lib" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Rob Janssen", + "homepage": "http://robiii.me", + "role": "Developer" + } + ], + "description": "Two Factor Authentication", + "homepage": "https://github.com/RobThree/TwoFactorAuth", + "keywords": [ + "Authentication", + "MFA", + "Multi Factor Authentication", + "Two Factor Authentication", + "authenticator", + "authy", + "php", + "tfa" + ], + "support": { + "issues": "https://github.com/RobThree/TwoFactorAuth/issues", + "source": "https://github.com/RobThree/TwoFactorAuth" + }, + "time": "2020-01-02T19:56:46+00:00" + }, + { + "name": "symfony/polyfill-iconv", + "version": "v1.20.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-iconv.git", + "reference": "c536646fdb4f29104dd26effc2fdcb9a5b085024" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/c536646fdb4f29104dd26effc2fdcb9a5b085024", + "reference": "c536646fdb4f29104dd26effc2fdcb9a5b085024", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-iconv": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.20-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.20.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": "2020-10-23T14:02:19+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.20.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "c7cf3f858ec7d70b89559d6e6eb1f7c2517d479c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/c7cf3f858ec7d70b89559d6e6eb1f7c2517d479c", + "reference": "c7cf3f858ec7d70b89559d6e6eb1f7c2517d479c", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.20-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.20.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": "2020-10-23T14:02:19+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.20.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "727d1096295d807c309fb01a851577302394c897" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/727d1096295d807c309fb01a851577302394c897", + "reference": "727d1096295d807c309fb01a851577302394c897", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.20-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.20.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": "2020-10-23T14:02:19+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.20.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "39d483bdf39be819deabf04ec872eb0b2410b531" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/39d483bdf39be819deabf04ec872eb0b2410b531", + "reference": "39d483bdf39be819deabf04ec872eb0b2410b531", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.20-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.20.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": "2020-10-23T14:02:19+00:00" + }, + { + "name": "symfony/polyfill-php72", + "version": "v1.20.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php72.git", + "reference": "cede45fcdfabdd6043b3592e83678e42ec69e930" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/cede45fcdfabdd6043b3592e83678e42ec69e930", + "reference": "cede45fcdfabdd6043b3592e83678e42ec69e930", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.20-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.20.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": "2020-10-23T14:02:19+00:00" + }, + { + "name": "voku/anti-xss", + "version": "4.1.31", + "source": { + "type": "git", + "url": "https://github.com/voku/anti-xss.git", + "reference": "22dea9be8dbffa466995ea87a12da5f3bce874bb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/voku/anti-xss/zipball/22dea9be8dbffa466995ea87a12da5f3bce874bb", + "reference": "22dea9be8dbffa466995ea87a12da5f3bce874bb", + "shasum": "" + }, + "require": { + "php": ">=7.0.0", + "voku/portable-utf8": "~5.4.51" + }, + "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": "http://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.31" + }, + "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": "2020-12-02T02:10:30+00:00" + }, + { + "name": "voku/portable-ascii", + "version": "1.5.6", + "source": { + "type": "git", + "url": "https://github.com/voku/portable-ascii.git", + "reference": "80953678b19901e5165c56752d087fc11526017c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/voku/portable-ascii/zipball/80953678b19901e5165c56752d087fc11526017c", + "reference": "80953678b19901e5165c56752d087fc11526017c", + "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/1.5.6" + }, + "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": "2020-11-12T00:07:28+00:00" + }, + { + "name": "voku/portable-utf8", + "version": "5.4.51", + "source": { + "type": "git", + "url": "https://github.com/voku/portable-utf8.git", + "reference": "578f5266725dc9880483d24ad0cfb39f8ce170f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/voku/portable-utf8/zipball/578f5266725dc9880483d24ad0cfb39f8ce170f7", + "reference": "578f5266725dc9880483d24ad0cfb39f8ce170f7", + "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": "~1.5.6" + }, + "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/5.4.51" + }, + "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": "2020-12-02T01:58:49+00:00" + } + ], + "packages-dev": [ + { + "name": "composer/xdebug-handler", + "version": "1.4.5", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "f28d44c286812c714741478d968104c5e604a1d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/f28d44c286812c714741478d968104c5e604a1d4", + "reference": "f28d44c286812c714741478d968104c5e604a1d4", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0", + "psr/log": "^1.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/1.4.5" + }, + "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": "2020-11-13T08:04:11+00:00" + }, + { + "name": "doctrine/instantiator", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b", + "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^8.0", + "ext-pdo": "*", + "ext-phar": "*", + "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", + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "https://ocramius.github.io/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "keywords": [ + "constructor", + "instantiate" + ], + "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.10.2", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220", + "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "replace": { + "myclabs/deep-copy": "self.version" + }, + "require-dev": { + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^7.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + }, + "files": [ + "src/DeepCopy/deep_copy.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "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.10.4", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "c6d052fc58cb876152f89f532b95a8d7907e7f0e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/c6d052fc58cb876152f89f532b95a8d7907e7f0e", + "reference": "c6d052fc58cb876152f89f532b95a8d7907e7f0e", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.10.4" + }, + "time": "2020-12-20T10:01:03+00:00" + }, + { + "name": "pdepend/pdepend", + "version": "2.8.0", + "source": { + "type": "git", + "url": "https://github.com/pdepend/pdepend.git", + "reference": "c64472f8e76ca858c79ad9a4cf1e2734b3f8cc38" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pdepend/pdepend/zipball/c64472f8e76ca858c79ad9a4cf1e2734b3f8cc38", + "reference": "c64472f8e76ca858c79ad9a4cf1e2734b3f8cc38", + "shasum": "" + }, + "require": { + "php": ">=5.3.7", + "symfony/config": "^2.3.0|^3|^4|^5", + "symfony/dependency-injection": "^2.3.0|^3|^4|^5", + "symfony/filesystem": "^2.3.0|^3|^4|^5" + }, + "require-dev": { + "easy-doc/easy-doc": "0.0.0 || ^1.2.3", + "gregwar/rst": "^1.0", + "phpunit/phpunit": "^4.8.35|^5.7", + "squizlabs/php_codesniffer": "^2.0.0" + }, + "bin": [ + "src/bin/pdepend" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "PDepend\\": "src/main/php/PDepend" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Official version of pdepend to be handled with Composer", + "support": { + "issues": "https://github.com/pdepend/pdepend/issues", + "source": "https://github.com/pdepend/pdepend/tree/master" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/pdepend/pdepend", + "type": "tidelift" + } + ], + "time": "2020-06-20T10:53:13+00:00" + }, + { + "name": "phar-io/manifest", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", + "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "phar-io/version": "^2.0", + "php": "^5.6 || ^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/master" + }, + "time": "2018-07-08T19:23:20+00:00" + }, + { + "name": "phar-io/version", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6", + "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "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" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/master" + }, + "time": "2018-07-08T19:19:57+00:00" + }, + { + "name": "phpcompatibility/php-compatibility", + "version": "9.3.5", + "source": { + "type": "git", + "url": "https://github.com/PHPCompatibility/PHPCompatibility.git", + "reference": "9fb324479acf6f39452e0655d2429cc0d3914243" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/9fb324479acf6f39452e0655d2429cc0d3914243", + "reference": "9fb324479acf6f39452e0655d2429cc0d3914243", + "shasum": "" + }, + "require": { + "php": ">=5.3", + "squizlabs/php_codesniffer": "^2.3 || ^3.0.2" + }, + "conflict": { + "squizlabs/php_codesniffer": "2.6.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.5 || ^5.0 || ^6.0 || ^7.0" + }, + "suggest": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically.", + "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." + }, + "type": "phpcodesniffer-standard", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "Wim Godden", + "homepage": "https://github.com/wimg", + "role": "lead" + }, + { + "name": "Juliette Reinders Folmer", + "homepage": "https://github.com/jrfnl", + "role": "lead" + }, + { + "name": "Contributors", + "homepage": "https://github.com/PHPCompatibility/PHPCompatibility/graphs/contributors" + } + ], + "description": "A set of sniffs for PHP_CodeSniffer that checks for PHP cross-version compatibility.", + "homepage": "http://techblog.wimgodden.be/tag/codesniffer/", + "keywords": [ + "compatibility", + "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.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "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": "5.2.2", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/069a785b2141f5bcf49f3e353548dc1cce6df556", + "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^1.3", + "webmozart/assert": "^1.9.1" + }, + "require-dev": { + "mockery/mockery": "~1.3.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "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.", + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/master" + }, + "time": "2020-09-03T19:13:55+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", + "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.0" + }, + "require-dev": { + "ext-tokenizer": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.4.0" + }, + "time": "2020-09-17T18:55:26+00:00" + }, + { + "name": "phploc/phploc", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phploc.git", + "reference": "5b714ccb7cb8ca29ccf9caf6eb1aed0131d3a884" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phploc/zipball/5b714ccb7cb8ca29ccf9caf6eb1aed0131d3a884", + "reference": "5b714ccb7cb8ca29ccf9caf6eb1aed0131d3a884", + "shasum": "" + }, + "require": { + "php": "^7.2", + "sebastian/finder-facade": "^1.1", + "sebastian/version": "^2.0", + "symfony/console": "^4.0" + }, + "bin": [ + "phploc" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.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": "A tool for quickly measuring the size of a PHP project.", + "homepage": "https://github.com/sebastianbergmann/phploc", + "support": { + "issues": "https://github.com/sebastianbergmann/phploc/issues", + "source": "https://github.com/sebastianbergmann/phploc/tree/master" + }, + "time": "2019-03-16T10:41:19+00:00" + }, + { + "name": "phpmd/phpmd", + "version": "2.9.1", + "source": { + "type": "git", + "url": "https://github.com/phpmd/phpmd.git", + "reference": "ce10831d4ddc2686c1348a98069771dd314534a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpmd/phpmd/zipball/ce10831d4ddc2686c1348a98069771dd314534a8", + "reference": "ce10831d4ddc2686c1348a98069771dd314534a8", + "shasum": "" + }, + "require": { + "composer/xdebug-handler": "^1.0", + "ext-xml": "*", + "pdepend/pdepend": "^2.7.1", + "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", + "phpunit/phpunit": "^4.8.36 || ^5.7.27", + "squizlabs/php_codesniffer": "^2.0" + }, + "bin": [ + "src/bin/phpmd" + ], + "type": "library", + "autoload": { + "psr-0": { + "PHPMD\\": "src/main/php" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Manuel Pichler", + "email": "github@manuel-pichler.de", + "homepage": "https://github.com/manuelpichler", + "role": "Project Founder" + }, + { + "name": "Marc Würth", + "email": "ravage@bluewin.ch", + "homepage": "https://github.com/ravage84", + "role": "Project Maintainer" + }, + { + "name": "Other contributors", + "homepage": "https://github.com/phpmd/phpmd/graphs/contributors", + "role": "Contributors" + } + ], + "description": "PHPMD is a spin-off project of PHP Depend and aims to be a PHP equivalent of the well known Java tool PMD.", + "homepage": "https://phpmd.org/", + "keywords": [ + "mess detection", + "mess detector", + "pdepend", + "phpmd", + "pmd" + ], + "support": { + "irc": "irc://irc.freenode.org/phpmd", + "issues": "https://github.com/phpmd/phpmd/issues", + "source": "https://github.com/phpmd/phpmd/tree/2.9.1" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/phpmd/phpmd", + "type": "tidelift" + } + ], + "time": "2020-09-23T22:06:32+00:00" + }, + { + "name": "phpspec/prophecy", + "version": "1.12.2", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "245710e971a030f42e08f4912863805570f23d39" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/245710e971a030f42e08f4912863805570f23d39", + "reference": "245710e971a030f42e08f4912863805570f23d39", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.2", + "php": "^7.2 || ~8.0, <8.1", + "phpdocumentor/reflection-docblock": "^5.2", + "sebastian/comparator": "^3.0 || ^4.0", + "sebastian/recursion-context": "^3.0 || ^4.0" + }, + "require-dev": { + "phpspec/phpspec": "^6.0", + "phpunit/phpunit": "^8.0 || ^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.11.x-dev" + } + }, + "autoload": { + "psr-4": { + "Prophecy\\": "src/Prophecy" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "support": { + "issues": "https://github.com/phpspec/prophecy/issues", + "source": "https://github.com/phpspec/prophecy/tree/1.12.2" + }, + "time": "2020-12-19T10:15:11+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "7.0.14", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "bb7c9a210c72e4709cdde67f8b7362f672f2225c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/bb7c9a210c72e4709cdde67f8b7362f672f2225c", + "reference": "bb7c9a210c72e4709cdde67f8b7362f672f2225c", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "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 || ^4.0", + "sebastian/code-unit-reverse-lookup": "^1.0.1", + "sebastian/environment": "^4.2.2", + "sebastian/version": "^2.0.1", + "theseer/tokenizer": "^1.1.3" + }, + "require-dev": { + "phpunit/phpunit": "^8.2.2" + }, + "suggest": { + "ext-xdebug": "^2.7.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.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 that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/7.0.14" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-12-02T13:39:03+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "4b49fb70f067272b659ef0174ff9ca40fdaa6357" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/4b49fb70f067272b659ef0174ff9ca40fdaa6357", + "reference": "4b49fb70f067272b659ef0174ff9ca40fdaa6357", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "phpunit/phpunit": "^8.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-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": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/2.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T08:25:21+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/1.2.1" + }, + "time": "2015-06-21T13:50:34+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "2.1.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/2454ae1765516d20c4ffe103d85a58a9a3bd5662", + "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "phpunit/phpunit": "^8.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.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": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/2.1.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T08:20:02+00:00" + }, + { + "name": "phpunit/php-token-stream", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "a853a0e183b9db7eed023d7933a858fa1c8d25a3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/a853a0e183b9db7eed023d7933a858fa1c8d25a3", + "reference": "a853a0e183b9db7eed023d7933a858fa1c8d25a3", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.3 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "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" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-token-stream/issues", + "source": "https://github.com/sebastianbergmann/php-token-stream/tree/master" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "abandoned": true, + "time": "2020-08-04T08:28:15+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "8.4.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "366a4a0f2b971fd43b7c351d621e8dd7d7131869" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/366a4a0f2b971fd43b7c351d621e8dd7d7131869", + "reference": "366a4a0f2b971fd43b7c351d621e8dd7d7131869", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.2.0", + "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" + }, + "require-dev": { + "ext-pdo": "*" + }, + "suggest": { + "ext-soap": "*", + "ext-xdebug": "*", + "phpunit/php-invoker": "^2.0.0" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "8.4-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": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "source": "https://github.com/sebastianbergmann/phpunit/tree/8.4.1" + }, + "time": "2019-10-07T12:57:41+00:00" + }, + { + "name": "psr/container", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/master" + }, + "time": "2017-02-14T16:28:37+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/1de8cd5c010cb153fcd68b8d0f64606f523f7619", + "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "phpunit/phpunit": "^8.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/1.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T08:15:22+00:00" + }, + { + "name": "sebastian/comparator", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "1071dfcef776a57013124ff35e1fc41ccd294758" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1071dfcef776a57013124ff35e1fc41ccd294758", + "reference": "1071dfcef776a57013124ff35e1fc41ccd294758", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "sebastian/diff": "^3.0", + "sebastian/exporter": "^3.1" + }, + "require-dev": { + "phpunit/phpunit": "^8.5" + }, + "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" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "source": "https://github.com/sebastianbergmann/comparator/tree/3.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T08:04:30+00:00" + }, + { + "name": "sebastian/diff", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/14f72dd46eaf2f2293cbe79c93cc0bc43161a211", + "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.5 || ^8.0", + "symfony/process": "^2 || ^3.3 || ^4" + }, + "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" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/3.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:59:04+00:00" + }, + { + "name": "sebastian/environment", + "version": "4.2.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/d47bbbad83711771f167c72d4e3f25f7fcc1f8b0", + "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.5" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/4.2.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:53:42+00:00" + }, + { + "name": "sebastian/exporter", + "version": "3.1.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "6b853149eab67d4da22291d36f5b0631c0fd856e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/6b853149eab67d4da22291d36f5b0631c0fd856e", + "reference": "6b853149eab67d4da22291d36f5b0631c0fd856e", + "shasum": "" + }, + "require": { + "php": ">=7.0", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1.x-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": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "source": "https://github.com/sebastianbergmann/exporter/tree/3.1.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:47:53+00:00" + }, + { + "name": "sebastian/finder-facade", + "version": "1.2.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/finder-facade.git", + "reference": "167c45d131f7fc3d159f56f191a0a22228765e16" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/finder-facade/zipball/167c45d131f7fc3d159f56f191a0a22228765e16", + "reference": "167c45d131f7fc3d159f56f191a0a22228765e16", + "shasum": "" + }, + "require": { + "php": "^7.1", + "symfony/finder": "^2.3|^3.0|^4.0|^5.0", + "theseer/fdomdocument": "^1.6" + }, + "type": "library", + "extra": { + "branch-alias": [] + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FinderFacade is a convenience wrapper for Symfony's Finder component.", + "homepage": "https://github.com/sebastianbergmann/finder-facade", + "support": { + "issues": "https://github.com/sebastianbergmann/finder-facade/issues", + "source": "https://github.com/sebastianbergmann/finder-facade/tree/1.2" + }, + "abandoned": true, + "time": "2020-01-16T08:08:45+00:00" + }, + { + "name": "sebastian/global-state", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "474fb9edb7ab891665d3bfc6317f42a0a150454b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/474fb9edb7ab891665d3bfc6317f42a0a150454b", + "reference": "474fb9edb7ab891665d3bfc6317f42a0a150454b", + "shasum": "" + }, + "require": { + "php": ">=7.2", + "sebastian/object-reflector": "^1.1.1", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^8.0" + }, + "suggest": { + "ext-uopz": "*" + }, + "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": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/3.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:43:24+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "3.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2", + "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2", + "shasum": "" + }, + "require": { + "php": ">=7.0", + "sebastian/object-reflector": "^1.1.1", + "sebastian/recursion-context": "^3.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": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/3.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:40:27+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "1.1.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/9b8772b9cbd456ab45d4a598d2dd1a1bced6363d", + "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d", + "shasum": "" + }, + "require": { + "php": ">=7.0" + }, + "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/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/1.1.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:37:18+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", + "support": { + "issues": "https://github.com/sebastianbergmann/phpcpd/issues", + "source": "https://github.com/sebastianbergmann/phpcpd/tree/4.1.0" + }, + "time": "2018-09-17T17:17:27+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/367dcba38d6e1977be014dc4b22f47a484dac7fb", + "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb", + "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": "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/3.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:34:24+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/31d35ca87926450c44eae7e2611d45a7a65ea8b3", + "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.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/2.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:30:19+00:00" + }, + { + "name": "sebastian/type", + "version": "1.1.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "0150cfbc4495ed2df3872fb31b26781e4e077eb4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/0150cfbc4495ed2df3872fb31b26781e4e077eb4", + "reference": "0150cfbc4495ed2df3872fb31b26781e4e077eb4", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.2" + }, + "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", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/1.1.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:25:11+00:00" + }, + { + "name": "sebastian/version", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-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 that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/master" + }, + "time": "2016-10-03T07:35:21+00:00" + }, + { + "name": "squizlabs/php_codesniffer", + "version": "3.5.8", + "source": { + "type": "git", + "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", + "reference": "9d583721a7157ee997f235f327de038e7ea6dac4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/9d583721a7157ee997f235f327de038e7ea6dac4", + "reference": "9d583721a7157ee997f235f327de038e7ea6dac4", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "bin": [ + "bin/phpcs", + "bin/phpcbf" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Greg Sherwood", + "role": "lead" + } + ], + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", + "keywords": [ + "phpcs", + "standards" + ], + "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": "2020-10-23T02:01:07+00:00" + }, + { + "name": "symfony/config", + "version": "v5.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/config.git", + "reference": "d0a82d965296083fe463d655a3644cbe49cbaa80" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/config/zipball/d0a82d965296083fe463d655a3644cbe49cbaa80", + "reference": "d0a82d965296083fe463d655a3644cbe49cbaa80", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1", + "symfony/filesystem": "^4.4|^5.0", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-php80": "^1.15" + }, + "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" + }, + "suggest": { + "symfony/yaml": "To use the yaml reference dumper" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Config\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Config Component", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/config/tree/v5.2.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-12-09T18:54:12+00:00" + }, + { + "name": "symfony/console", + "version": "v4.4.18", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "12e071278e396cc3e1c149857337e9e192deca0b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/12e071278e396cc3e1c149857337e9e192deca0b", + "reference": "12e071278e396cc3e1c149857337e9e192deca0b", + "shasum": "" + }, + "require": { + "php": ">=7.1.3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php73": "^1.8", + "symfony/polyfill-php80": "^1.15", + "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", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Console Component", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/console/tree/v4.4.18" + }, + "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": "2020-12-18T07:41:31+00:00" + }, + { + "name": "symfony/dependency-injection", + "version": "v5.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/dependency-injection.git", + "reference": "7f8a9e9eff0581a33e20f6c5d41096fe22832d25" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/7f8a9e9eff0581a33e20f6c5d41096fe22832d25", + "reference": "7f8a9e9eff0581a33e20f6c5d41096fe22832d25", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/container": "^1.0", + "symfony/deprecation-contracts": "^2.1", + "symfony/polyfill-php80": "^1.15", + "symfony/service-contracts": "^1.1.6|^2" + }, + "conflict": { + "symfony/config": "<5.1", + "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" + }, + "require-dev": { + "symfony/config": "^5.1", + "symfony/expression-language": "^4.4|^5.0", + "symfony/yaml": "^4.4|^5.0" + }, + "suggest": { + "symfony/config": "", + "symfony/expression-language": "For using expressions in service container configuration", + "symfony/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required", + "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", + "symfony/yaml": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\DependencyInjection\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony DependencyInjection Component", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/dependency-injection/tree/v5.2.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-12-18T08:03:05+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v2.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "5fa56b4074d1ae755beb55617ddafe6f5d78f665" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5fa56b4074d1ae755beb55617ddafe6f5d78f665", + "reference": "5fa56b4074d1ae755beb55617ddafe6f5d78f665", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2-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/master" + }, + "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": "2020-09-07T11:33:47+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v5.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "fa8f8cab6b65e2d99a118e082935344c5ba8c60d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/fa8f8cab6b65e2d99a118e082935344c5ba8c60d", + "reference": "fa8f8cab6b65e2d99a118e082935344c5ba8c60d", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-ctype": "~1.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Filesystem Component", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v5.2.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-11-30T17:05:38+00:00" + }, + { + "name": "symfony/finder", + "version": "v5.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "0b9231a5922fd7287ba5b411893c0ecd2733e5ba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/0b9231a5922fd7287ba5b411893c0ecd2733e5ba", + "reference": "0b9231a5922fd7287ba5b411893c0ecd2733e5ba", + "shasum": "" + }, + "require": { + "php": ">=7.2.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Finder Component", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v5.2.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-12-08T17:02:38+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.20.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/f4ba089a5b6366e453971d3aad5fe8e897b37f41", + "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.20-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.20.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": "2020-10-23T14:02:19+00:00" + }, + { + "name": "symfony/polyfill-php73", + "version": "v1.20.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php73.git", + "reference": "8ff431c517be11c78c48a39a66d37431e26a6bed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/8ff431c517be11c78c48a39a66d37431e26a6bed", + "reference": "8ff431c517be11c78c48a39a66d37431e26a6bed", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.20-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php73\\": "" + }, + "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 backporting some PHP 7.3+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php73/tree/v1.20.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": "2020-10-23T14:02:19+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.20.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "e70aa8b064c5b72d3df2abd5ab1e90464ad009de" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/e70aa8b064c5b72d3df2abd5ab1e90464ad009de", + "reference": "e70aa8b064c5b72d3df2abd5ab1e90464ad009de", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.20-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.20.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": "2020-10-23T14:02:19+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v2.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d15da7ba4957ffb8f1747218be9e1a121fd298a1", + "reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/container": "^1.0" + }, + "suggest": { + "symfony/service-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/master" + }, + "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": "2020-09-07T11:33:47+00:00" + }, + { + "name": "theseer/directoryscanner", + "version": "1.3.2", + "source": { + "type": "git", + "url": "https://github.com/theseer/DirectoryScanner.git", + "reference": "549aa9fdbc47d50365db42d9ade35fdef65f854c" + }, + "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": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A recursive directory scanner and filter", + "support": { + "issues": "https://github.com/theseer/DirectoryScanner/issues", + "source": "https://github.com/theseer/DirectoryScanner/tree/master" + }, + "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": [ + { + "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", + "support": { + "issues": "https://github.com/theseer/fDOMDocument/issues", + "source": "https://github.com/theseer/fDOMDocument/tree/master" + }, + "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": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "An XSL wrapper / extension to the PHP 5.x XSLTProcessor with Exception and extended Callback support", + "support": { + "issues": "https://github.com/theseer/fXSL/issues", + "source": "https://github.com/theseer/fXSL/tree/master" + }, + "abandoned": true, + "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", + "support": { + "issues": "https://github.com/theseer/phpdox/issues", + "source": "https://github.com/theseer/phpdox/tree/master" + }, + "time": "2019-03-13T09:34:17+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "75a63c33a8577608444246075ea0af0d052e452a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/75a63c33a8577608444246075ea0af0d052e452a", + "reference": "75a63c33a8577608444246075ea0af0d052e452a", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "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 small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/master" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2020-07-12T23:59:07+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.9.1", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", + "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0 || ^8.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<3.9.1" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.36 || ^7.5.13" + }, + "type": "library", + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozart/assert/issues", + "source": "https://github.com/webmozart/assert/tree/master" + }, + "time": "2020-07-08T17:02:28+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=7.1", + "ext-session": "*", + "ext-ctype": "*", + "ext-pdo": "*", + "ext-pdo_mysql": "*", + "ext-simplexml": "*", + "ext-xml": "*", + "ext-filter": "*", + "ext-posix": "*", + "ext-mbstring": "*", + "ext-curl": "*", + "ext-json": "*", + "ext-openssl": "*" + }, + "platform-dev": { + "php": ">=7.3", + "ext-pcntl": "*" + }, + "plugin-api-version": "2.0.0" +} diff --git a/css/images/ui-bg_diagonals-thick_18_b81900_40x40.png b/css/images/ui-bg_diagonals-thick_18_b81900_40x40.png deleted file mode 100644 index cc1e486a..00000000 Binary files a/css/images/ui-bg_diagonals-thick_18_b81900_40x40.png and /dev/null differ diff --git a/css/images/ui-bg_diagonals-thick_20_666666_40x40.png b/css/images/ui-bg_diagonals-thick_20_666666_40x40.png deleted file mode 100644 index 7bc8a928..00000000 Binary files a/css/images/ui-bg_diagonals-thick_20_666666_40x40.png and /dev/null differ diff --git a/css/images/ui-bg_flat_10_000000_40x100.png b/css/images/ui-bg_flat_10_000000_40x100.png deleted file mode 100644 index c5d10e65..00000000 Binary files a/css/images/ui-bg_flat_10_000000_40x100.png and /dev/null differ diff --git a/css/images/ui-bg_glass_100_f6f6f6_1x400.png b/css/images/ui-bg_glass_100_f6f6f6_1x400.png deleted file mode 100644 index cc405328..00000000 Binary files a/css/images/ui-bg_glass_100_f6f6f6_1x400.png and /dev/null differ diff --git a/css/images/ui-bg_glass_100_fdf5ce_1x400.png b/css/images/ui-bg_glass_100_fdf5ce_1x400.png deleted file mode 100644 index c1662cec..00000000 Binary files a/css/images/ui-bg_glass_100_fdf5ce_1x400.png and /dev/null differ diff --git a/css/images/ui-bg_glass_65_ffffff_1x400.png b/css/images/ui-bg_glass_65_ffffff_1x400.png deleted file mode 100644 index b559b14a..00000000 Binary files a/css/images/ui-bg_glass_65_ffffff_1x400.png and /dev/null differ diff --git a/css/images/ui-bg_gloss-wave_35_f6a828_500x100.png b/css/images/ui-bg_gloss-wave_35_f6a828_500x100.png deleted file mode 100644 index 50e4fd03..00000000 Binary files a/css/images/ui-bg_gloss-wave_35_f6a828_500x100.png and /dev/null differ diff --git a/css/images/ui-bg_highlight-soft_100_eeeeee_1x100.png b/css/images/ui-bg_highlight-soft_100_eeeeee_1x100.png deleted file mode 100644 index 7581036d..00000000 Binary files a/css/images/ui-bg_highlight-soft_100_eeeeee_1x100.png and /dev/null differ diff --git a/css/images/ui-bg_highlight-soft_75_ffe45c_1x100.png b/css/images/ui-bg_highlight-soft_75_ffe45c_1x100.png deleted file mode 100644 index 087a3827..00000000 Binary files a/css/images/ui-bg_highlight-soft_75_ffe45c_1x100.png and /dev/null differ diff --git a/css/images/ui-icons_222222_256x240.png b/css/images/ui-icons_222222_256x240.png deleted file mode 100644 index 1d00d73a..00000000 Binary files a/css/images/ui-icons_222222_256x240.png and /dev/null differ diff --git a/css/images/ui-icons_228ef1_256x240.png b/css/images/ui-icons_228ef1_256x240.png deleted file mode 100644 index fe17e2f0..00000000 Binary files a/css/images/ui-icons_228ef1_256x240.png and /dev/null differ diff --git a/css/images/ui-icons_444444_256x240.png b/css/images/ui-icons_444444_256x240.png new file mode 100644 index 00000000..19f664d9 Binary files /dev/null and b/css/images/ui-icons_444444_256x240.png differ diff --git a/css/images/ui-icons_555555_256x240.png b/css/images/ui-icons_555555_256x240.png new file mode 100644 index 00000000..e965f6d9 Binary files /dev/null and b/css/images/ui-icons_555555_256x240.png differ diff --git a/css/images/ui-icons_777620_256x240.png b/css/images/ui-icons_777620_256x240.png new file mode 100644 index 00000000..9785948a Binary files /dev/null and b/css/images/ui-icons_777620_256x240.png differ diff --git a/css/images/ui-icons_777777_256x240.png b/css/images/ui-icons_777777_256x240.png new file mode 100644 index 00000000..323c4564 Binary files /dev/null and b/css/images/ui-icons_777777_256x240.png differ diff --git a/css/images/ui-icons_cc0000_256x240.png b/css/images/ui-icons_cc0000_256x240.png new file mode 100644 index 00000000..45ac7787 Binary files /dev/null and b/css/images/ui-icons_cc0000_256x240.png differ diff --git a/css/images/ui-icons_ef8c08_256x240.png b/css/images/ui-icons_ef8c08_256x240.png deleted file mode 100644 index 60eb071e..00000000 Binary files a/css/images/ui-icons_ef8c08_256x240.png and /dev/null differ diff --git a/css/images/ui-icons_ffd27a_256x240.png b/css/images/ui-icons_ffd27a_256x240.png deleted file mode 100644 index 4cece816..00000000 Binary files a/css/images/ui-icons_ffd27a_256x240.png and /dev/null differ diff --git a/css/images/ui-icons_ffffff_256x240.png b/css/images/ui-icons_ffffff_256x240.png index 32141c8e..fe41d2d0 100644 Binary files a/css/images/ui-icons_ffffff_256x240.png and b/css/images/ui-icons_ffffff_256x240.png differ diff --git a/css/jquery-ui.min.css b/css/jquery-ui.min.css index 3c6d34c0..dc84872d 100644 --- a/css/jquery-ui.min.css +++ b/css/jquery-ui.min.css @@ -1,7 +1,1893 @@ -/*! jQuery UI - v1.10.4 - 2014-04-02 +/*! jQuery UI - v1.12.1 - 2018-06-17 * http://jqueryui.com -* Includes: jquery.ui.core.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css, jquery.ui.theme.css -* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS%2CTahoma%2CVerdana%2CArial%2Csans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=f6a828&bgTextureHeader=gloss_wave&bgImgOpacityHeader=35&borderColorHeader=e78f08&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=highlight_soft&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=glass&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=1c94c4&iconColorDefault=ef8c08&bgColorHover=fdf5ce&bgTextureHover=glass&bgImgOpacityHover=100&borderColorHover=fbcb09&fcHover=c77405&iconColorHover=ef8c08&bgColorActive=ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=fbd850&fcActive=eb8f00&iconColorActive=ef8c08&bgColorHighlight=ffe45c&bgTextureHighlight=highlight_soft&bgImgOpacityHighlight=75&borderColorHighlight=fed22f&fcHighlight=363636&iconColorHighlight=228ef1&bgColorError=b81900&bgTextureError=diagonals_thick&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=diagonals_thick&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=flat&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px -* Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */ +* Includes: draggable.css, core.css, resizable.css, selectable.css, sortable.css, accordion.css, autocomplete.css, menu.css, button.css, controlgroup.css, checkboxradio.css, datepicker.css, dialog.css, progressbar.css, selectmenu.css, slider.css, spinner.css, tabs.css, tooltip.css, theme.css +* To view and modify this theme, visit http://jqueryui.com/themeroller/?scope=&folderName=base&cornerRadiusShadow=8px&offsetLeftShadow=0px&offsetTopShadow=0px&thicknessShadow=5px&opacityShadow=30&bgImgOpacityShadow=0&bgTextureShadow=flat&bgColorShadow=666666&opacityOverlay=30&bgImgOpacityOverlay=0&bgTextureOverlay=flat&bgColorOverlay=aaaaaa&iconColorError=cc0000&fcError=5f3f3f&borderColorError=f1a899&bgTextureError=flat&bgColorError=fddfdf&iconColorHighlight=777620&fcHighlight=777620&borderColorHighlight=dad55e&bgTextureHighlight=flat&bgColorHighlight=fffa90&iconColorActive=ffffff&fcActive=ffffff&borderColorActive=003eff&bgTextureActive=flat&bgColorActive=007fff&iconColorHover=555555&fcHover=2b2b2b&borderColorHover=cccccc&bgTextureHover=flat&bgColorHover=ededed&iconColorDefault=777777&fcDefault=454545&borderColorDefault=c5c5c5&bgTextureDefault=flat&bgColorDefault=f6f6f6&iconColorContent=444444&fcContent=333333&borderColorContent=dddddd&bgTextureContent=flat&bgColorContent=ffffff&iconColorHeader=444444&fcHeader=333333&borderColorHeader=dddddd&bgTextureHeader=flat&bgColorHeader=e9e9e9&cornerRadius=3px&fwDefault=normal&fsDefault=1em&ffDefault=Arial%2CHelvetica%2Csans-serif +* Copyright jQuery Foundation and other contributors; Licensed MIT */ +.ui-draggable-handle { + -ms-touch-action: none; + touch-action: none +} -.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{min-height:0}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-accordion .ui-accordion-header{display:block;cursor:pointer;position:relative;margin-top:2px;padding:.5em .5em .5em .7em;min-height:0}.ui-accordion .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-noicons{padding-left:.7em}.ui-accordion .ui-accordion-icons .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-header .ui-accordion-header-icon{position:absolute;left:.5em;top:50%;margin-top:-8px}.ui-accordion .ui-accordion-content{padding:1em 2.2em;border-top:0;overflow:auto}.ui-autocomplete{position:absolute;top:0;left:0;cursor:default}.ui-button{display:inline-block;position:relative;padding:0;line-height:normal;margin-right:.1em;cursor:pointer;vertical-align:middle;text-align:center;overflow:visible}.ui-button,.ui-button:link,.ui-button:visited,.ui-button:hover,.ui-button:active{text-decoration:none}.ui-button-icon-only{width:2.2em}button.ui-button-icon-only{width:2.4em}.ui-button-icons-only{width:3.4em}button.ui-button-icons-only{width:3.7em}.ui-button .ui-button-text{display:block;line-height:normal}.ui-button-text-only .ui-button-text{padding:.4em 1em}.ui-button-icon-only .ui-button-text,.ui-button-icons-only .ui-button-text{padding:.4em;text-indent:-9999999px}.ui-button-text-icon-primary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 1em .4em 2.1em}.ui-button-text-icon-secondary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 2.1em .4em 1em}.ui-button-text-icons .ui-button-text{padding-left:2.1em;padding-right:2.1em}input.ui-button{padding:.4em 1em}.ui-button-icon-only .ui-icon,.ui-button-text-icon-primary .ui-icon,.ui-button-text-icon-secondary .ui-icon,.ui-button-text-icons .ui-icon,.ui-button-icons-only .ui-icon{position:absolute;top:50%;margin-top:-8px}.ui-button-icon-only .ui-icon{left:50%;margin-left:-8px}.ui-button-text-icon-primary .ui-button-icon-primary,.ui-button-text-icons .ui-button-icon-primary,.ui-button-icons-only .ui-button-icon-primary{left:.5em}.ui-button-text-icon-secondary .ui-button-icon-secondary,.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em}.ui-buttonset{margin-right:7px}.ui-buttonset .ui-button{margin-left:0;margin-right:-.3em}input.ui-button::-moz-focus-inner,button.ui-button::-moz-focus-inner{border:0;padding:0}.ui-datepicker{width:17em;padding:.2em .2em 0;display:none}.ui-datepicker .ui-datepicker-header{position:relative;padding:.2em 0}.ui-datepicker .ui-datepicker-prev,.ui-datepicker .ui-datepicker-next{position:absolute;top:2px;width:1.8em;height:1.8em}.ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:1px}.ui-datepicker .ui-datepicker-prev{left:2px}.ui-datepicker .ui-datepicker-next{right:2px}.ui-datepicker .ui-datepicker-prev-hover{left:1px}.ui-datepicker .ui-datepicker-next-hover{right:1px}.ui-datepicker .ui-datepicker-prev span,.ui-datepicker .ui-datepicker-next span{display:block;position:absolute;left:50%;margin-left:-8px;top:50%;margin-top:-8px}.ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center}.ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0}.ui-datepicker select.ui-datepicker-month,.ui-datepicker select.ui-datepicker-year{width:49%}.ui-datepicker table{width:100%;font-size:.9em;border-collapse:collapse;margin:0 0 .4em}.ui-datepicker th{padding:.7em .3em;text-align:center;font-weight:bold;border:0}.ui-datepicker td{border:0;padding:1px}.ui-datepicker td span,.ui-datepicker td a{display:block;padding:.2em;text-align:right;text-decoration:none}.ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:.7em 0 0 0;padding:0 .2em;border-left:0;border-right:0;border-bottom:0}.ui-datepicker .ui-datepicker-buttonpane button{float:right;margin:.5em .2em .4em;cursor:pointer;padding:.2em .6em .3em .6em;width:auto;overflow:visible}.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left}.ui-datepicker.ui-datepicker-multi{width:auto}.ui-datepicker-multi .ui-datepicker-group{float:left}.ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em}.ui-datepicker-multi-2 .ui-datepicker-group{width:50%}.ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%}.ui-datepicker-multi-4 .ui-datepicker-group{width:25%}.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0}.ui-datepicker-multi .ui-datepicker-buttonpane{clear:left}.ui-datepicker-row-break{clear:both;width:100%;font-size:0}.ui-datepicker-rtl{direction:rtl}.ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto}.ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto}.ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto}.ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto}.ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right}.ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left}.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,.ui-datepicker-rtl .ui-datepicker-group{float:right}.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header{border-right-width:0;border-left-width:1px}.ui-dialog{overflow:hidden;position:absolute;top:0;left:0;padding:.2em;outline:0}.ui-dialog .ui-dialog-titlebar{padding:.4em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 0;white-space:nowrap;width:90%;overflow:hidden;text-overflow:ellipsis}.ui-dialog .ui-dialog-titlebar-close{position:absolute;right:.3em;top:50%;width:20px;margin:-10px 0 0 0;padding:1px;height:20px}.ui-dialog .ui-dialog-content{position:relative;border:0;padding:.5em 1em;background:none;overflow:auto}.ui-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;margin-top:.5em;padding:.3em 1em .5em .4em}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right}.ui-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer}.ui-dialog .ui-resizable-se{width:12px;height:12px;right:-5px;bottom:-5px;background-position:16px 16px}.ui-draggable .ui-dialog-titlebar{cursor:move}.ui-menu{list-style:none;padding:2px;margin:0;display:block;outline:none}.ui-menu .ui-menu{margin-top:-3px;position:absolute}.ui-menu .ui-menu-item{margin:0;padding:0;width:100%;list-style-image:url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)}.ui-menu .ui-menu-divider{margin:5px -2px 5px -2px;height:0;font-size:0;line-height:0;border-width:1px 0 0 0}.ui-menu .ui-menu-item a{text-decoration:none;display:block;padding:2px .4em;line-height:1.5;min-height:0;font-weight:normal}.ui-menu .ui-menu-item a.ui-state-focus,.ui-menu .ui-menu-item a.ui-state-active{font-weight:normal;margin:-1px}.ui-menu .ui-state-disabled{font-weight:normal;margin:.4em 0 .2em;line-height:1.5}.ui-menu .ui-state-disabled a{cursor:default}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item a{position:relative;padding-left:2em}.ui-menu .ui-icon{position:absolute;top:.2em;left:.2em}.ui-menu .ui-menu-icon{position:static;float:right}.ui-progressbar{height:2em;text-align:left;overflow:hidden}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%}.ui-progressbar .ui-progressbar-overlay{background:url("images/animated-overlay.gif");height:100%;filter:alpha(opacity=25);opacity:0.25}.ui-progressbar-indeterminate .ui-progressbar-value{background-image:none}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;display:block}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black}.ui-slider{position:relative;text-align:left}.ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1.2em;height:1.2em;cursor:default}.ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;background-position:0 0}.ui-slider.ui-state-disabled .ui-slider-handle,.ui-slider.ui-state-disabled .ui-slider-range{filter:inherit}.ui-slider-horizontal{height:.8em}.ui-slider-horizontal .ui-slider-handle{top:-.3em;margin-left:-.6em}.ui-slider-horizontal .ui-slider-range{top:0;height:100%}.ui-slider-horizontal .ui-slider-range-min{left:0}.ui-slider-horizontal .ui-slider-range-max{right:0}.ui-slider-vertical{width:.8em;height:100px}.ui-slider-vertical .ui-slider-handle{left:-.3em;margin-left:0;margin-bottom:-.6em}.ui-slider-vertical .ui-slider-range{left:0;width:100%}.ui-slider-vertical .ui-slider-range-min{bottom:0}.ui-slider-vertical .ui-slider-range-max{top:0}.ui-spinner{position:relative;display:inline-block;overflow:hidden;padding:0;vertical-align:middle}.ui-spinner-input{border:none;background:none;color:inherit;padding:0;margin:.2em 0;vertical-align:middle;margin-left:.4em;margin-right:22px}.ui-spinner-button{width:16px;height:50%;font-size:.5em;padding:0;margin:0;text-align:center;position:absolute;cursor:default;display:block;overflow:hidden;right:0}.ui-spinner a.ui-spinner-button{border-top:none;border-bottom:none;border-right:none}.ui-spinner .ui-icon{position:absolute;margin-top:-8px;top:50%;left:0}.ui-spinner-up{top:0}.ui-spinner-down{bottom:0}.ui-spinner .ui-icon-triangle-1-s{background-position:-65px -16px}.ui-tabs{position:relative;padding:.2em}.ui-tabs .ui-tabs-nav{margin:0;padding:.2em .2em 0}.ui-tabs .ui-tabs-nav li{list-style:none;float:left;position:relative;top:0;margin:1px .2em 0 0;border-bottom-width:0;padding:0;white-space:nowrap}.ui-tabs .ui-tabs-nav .ui-tabs-anchor{float:left;padding:.5em 1em;text-decoration:none}.ui-tabs .ui-tabs-nav li.ui-tabs-active{margin-bottom:-1px;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor{cursor:text}.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:none}.ui-tooltip{padding:8px;position:absolute;z-index:9999;max-width:300px;-webkit-box-shadow:0 0 5px #aaa;box-shadow:0 0 5px #aaa}body .ui-tooltip{border-width:2px}.ui-widget{font-family:Trebuchet MS,Tahoma,Verdana,Arial,sans-serif;font-size:1.1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Trebuchet MS,Tahoma,Verdana,Arial,sans-serif;font-size:1em}.ui-widget-content{border:1px solid #ddd;background:#eee url("images/ui-bg_highlight-soft_100_eeeeee_1x100.png") 50% top repeat-x;color:#333}.ui-widget-content a{color:#333}.ui-widget-header{border:1px solid #e78f08;background:#f6a828 url("images/ui-bg_gloss-wave_35_f6a828_500x100.png") 50% 50% repeat-x;color:#fff;font-weight:bold}.ui-widget-header a{color:#fff}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #ccc;background:#f6f6f6 url("images/ui-bg_glass_100_f6f6f6_1x400.png") 50% 50% repeat-x;font-weight:bold;color:#1c94c4}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#1c94c4;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{border:1px solid #fbcb09;background:#fdf5ce url("images/ui-bg_glass_100_fdf5ce_1x400.png") 50% 50% repeat-x;font-weight:bold;color:#c77405}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited,.ui-state-focus a,.ui-state-focus a:hover,.ui-state-focus a:link,.ui-state-focus a:visited{color:#c77405;text-decoration:none}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:1px solid #fbd850;background:#fff url("images/ui-bg_glass_65_ffffff_1x400.png") 50% 50% repeat-x;font-weight:bold;color:#eb8f00}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#eb8f00;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #fed22f;background:#ffe45c url("images/ui-bg_highlight-soft_75_ffe45c_1x100.png") 50% top repeat-x;color:#363636}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#363636}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #cd0a0a;background:#b81900 url("images/ui-bg_diagonals-thick_18_b81900_40x40.png") 50% 50% repeat;color:#fff}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#fff}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#fff}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px}.ui-icon,.ui-widget-content .ui-icon{background-image:url("images/ui-icons_222222_256x240.png")}.ui-widget-header .ui-icon{background-image:url("images/ui-icons_ffffff_256x240.png")}.ui-state-default .ui-icon{background-image:url("images/ui-icons_ef8c08_256x240.png")}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url("images/ui-icons_ef8c08_256x240.png")}.ui-state-active .ui-icon{background-image:url("images/ui-icons_ef8c08_256x240.png")}.ui-state-highlight .ui-icon{background-image:url("images/ui-icons_228ef1_256x240.png")}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url("images/ui-icons_ffd27a_256x240.png")}.ui-icon-blank{background-position:16px 16px}.ui-icon-carat-1-n{background-position:0 0}.ui-icon-carat-1-ne{background-position:-16px 0}.ui-icon-carat-1-e{background-position:-32px 0}.ui-icon-carat-1-se{background-position:-48px 0}.ui-icon-carat-1-s{background-position:-64px 0}.ui-icon-carat-1-sw{background-position:-80px 0}.ui-icon-carat-1-w{background-position:-96px 0}.ui-icon-carat-1-nw{background-position:-112px 0}.ui-icon-carat-2-n-s{background-position:-128px 0}.ui-icon-carat-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-64px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-64px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:0 -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:4px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:4px}.ui-widget-overlay{background:#666 url("images/ui-bg_diagonals-thick_20_666666_40x40.png") 50% 50% repeat;opacity:.5;filter:Alpha(Opacity=50)}.ui-widget-shadow{margin:-5px 0 0 -5px;padding:5px;background:#000 url("images/ui-bg_flat_10_000000_40x100.png") 50% 50% repeat-x;opacity:.2;filter:Alpha(Opacity=20);border-radius:5px} \ No newline at end of file +.ui-helper-hidden { + display: none +} + +.ui-helper-hidden-accessible { + border: 0; + clip: rect(0, 0, 0, 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px +} + +.ui-helper-reset { + margin: 0; + padding: 0; + border: 0; + outline: 0; + line-height: 1.3; + text-decoration: none; + font-size: 100%; + list-style: none +} + +.ui-helper-clearfix:before, .ui-helper-clearfix:after { + content: ""; + display: table; + border-collapse: collapse +} + +.ui-helper-clearfix:after { + clear: both +} + +.ui-helper-zfix { + width: 100%; + height: 100%; + top: 0; + left: 0; + position: absolute; + opacity: 0; + filter: Alpha(Opacity = 0) +} + +.ui-front { + z-index: 100 +} + +.ui-state-disabled { + cursor: default !important; + pointer-events: none +} + +.ui-icon { + display: inline-block; + vertical-align: middle; + margin-top: -.25em; + position: relative; + text-indent: -99999px; + overflow: hidden; + background-repeat: no-repeat +} + +.ui-widget-icon-block { + left: 50%; + margin-left: -8px; + display: block +} + +.ui-widget-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100% +} + +.ui-resizable { + position: relative +} + +.ui-resizable-handle { + position: absolute; + font-size: 0.1px; + display: block; + -ms-touch-action: none; + touch-action: none +} + +.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle + { + display: none +} + +.ui-resizable-n { + cursor: n-resize; + height: 7px; + width: 100%; + top: -5px; + left: 0 +} + +.ui-resizable-s { + cursor: s-resize; + height: 7px; + width: 100%; + bottom: -5px; + left: 0 +} + +.ui-resizable-e { + cursor: e-resize; + width: 7px; + right: -5px; + top: 0; + height: 100% +} + +.ui-resizable-w { + cursor: w-resize; + width: 7px; + left: -5px; + top: 0; + height: 100% +} + +.ui-resizable-se { + cursor: se-resize; + width: 12px; + height: 12px; + right: 1px; + bottom: 1px +} + +.ui-resizable-sw { + cursor: sw-resize; + width: 9px; + height: 9px; + left: -5px; + bottom: -5px +} + +.ui-resizable-nw { + cursor: nw-resize; + width: 9px; + height: 9px; + left: -5px; + top: -5px +} + +.ui-resizable-ne { + cursor: ne-resize; + width: 9px; + height: 9px; + right: -5px; + top: -5px +} + +.ui-selectable { + -ms-touch-action: none; + touch-action: none +} + +.ui-selectable-helper { + position: absolute; + z-index: 100; + border: 1px dotted black +} + +.ui-sortable-handle { + -ms-touch-action: none; + touch-action: none +} + +.ui-accordion .ui-accordion-header { + display: block; + cursor: pointer; + position: relative; + margin: 2px 0 0 0; + padding: .5em .5em .5em .7em; + font-size: 100% +} + +.ui-accordion .ui-accordion-content { + padding: 1em 2.2em; + border-top: 0; + overflow: auto +} + +.ui-autocomplete { + position: absolute; + top: 0; + left: 0; + cursor: default +} + +.ui-menu { + list-style: none; + padding: 0; + margin: 0; + display: block; + outline: 0 +} + +.ui-menu .ui-menu { + position: absolute +} + +.ui-menu .ui-menu-item { + margin: 0; + cursor: pointer; + list-style-image: + url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7") +} + +.ui-menu .ui-menu-item-wrapper { + position: relative; + padding: 3px 1em 3px .4em +} + +.ui-menu .ui-menu-divider { + margin: 5px 0; + height: 0; + font-size: 0; + line-height: 0; + border-width: 1px 0 0 0 +} + +.ui-menu .ui-state-focus, .ui-menu .ui-state-active { + margin: -1px +} + +.ui-menu-icons { + position: relative +} + +.ui-menu-icons .ui-menu-item-wrapper { + padding-left: 2em +} + +.ui-menu .ui-icon { + position: absolute; + top: 0; + bottom: 0; + left: .2em; + margin: auto 0 +} + +.ui-menu .ui-menu-icon { + left: auto; + right: 0 +} + +.ui-button { + padding: .4em 1em; + display: inline-block; + position: relative; + line-height: normal; + margin-right: .1em; + cursor: pointer; + vertical-align: middle; + text-align: center; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + overflow: visible +} + +.ui-button, .ui-button:link, .ui-button:visited, .ui-button:hover, + .ui-button:active { + text-decoration: none +} + +.ui-button-icon-only { + width: 2em; + box-sizing: border-box; + text-indent: -9999px; + white-space: nowrap +} + +input.ui-button.ui-button-icon-only { + text-indent: 0 +} + +.ui-button-icon-only .ui-icon { + position: absolute; + top: 50%; + left: 50%; + margin-top: -8px; + margin-left: -8px +} + +.ui-button.ui-icon-notext .ui-icon { + padding: 0; + width: 2.1em; + height: 2.1em; + text-indent: -9999px; + white-space: nowrap +} + +input.ui-button.ui-icon-notext .ui-icon { + width: auto; + height: auto; + text-indent: 0; + white-space: normal; + padding: .4em 1em +} + +input.ui-button::-moz-focus-inner, button.ui-button::-moz-focus-inner { + border: 0; + padding: 0 +} + +.ui-controlgroup { + vertical-align: middle; + display: inline-block +} + +.ui-controlgroup>.ui-controlgroup-item { + float: left; + margin-left: 0; + margin-right: 0 +} + +.ui-controlgroup>.ui-controlgroup-item:focus, .ui-controlgroup>.ui-controlgroup-item.ui-visual-focus + { + z-index: 9999 +} + +.ui-controlgroup-vertical>.ui-controlgroup-item { + display: block; + float: none; + width: 100%; + margin-top: 0; + margin-bottom: 0; + text-align: left +} + +.ui-controlgroup-vertical .ui-controlgroup-item { + box-sizing: border-box +} + +.ui-controlgroup .ui-controlgroup-label { + padding: .4em 1em +} + +.ui-controlgroup .ui-controlgroup-label span { + font-size: 80% +} + +.ui-controlgroup-horizontal .ui-controlgroup-label+.ui-controlgroup-item + { + border-left: none +} + +.ui-controlgroup-vertical .ui-controlgroup-label+.ui-controlgroup-item { + border-top: none +} + +.ui-controlgroup-horizontal .ui-controlgroup-label.ui-widget-content { + border-right: none +} + +.ui-controlgroup-vertical .ui-controlgroup-label.ui-widget-content { + border-bottom: none +} + +.ui-controlgroup-vertical .ui-spinner-input { + width: 75%; + width: calc(100% - 2.4em) +} + +.ui-controlgroup-vertical .ui-spinner .ui-spinner-up { + border-top-style: solid +} + +.ui-checkboxradio-label .ui-icon-background { + box-shadow: inset 1px 1px 1px #ccc; + border-radius: .12em; + border: none +} + +.ui-checkboxradio-radio-label .ui-icon-background { + width: 16px; + height: 16px; + border-radius: 1em; + overflow: visible; + border: none +} + +.ui-checkboxradio-radio-label.ui-checkboxradio-checked .ui-icon, + .ui-checkboxradio-radio-label.ui-checkboxradio-checked:hover .ui-icon { + background-image: none; + width: 8px; + height: 8px; + border-width: 4px; + border-style: solid +} + +.ui-checkboxradio-disabled { + pointer-events: none +} + +.ui-datepicker { + width: 17em; + padding: .2em .2em 0; + display: none +} + +.ui-datepicker .ui-datepicker-header { + position: relative; + padding: .2em 0 +} + +.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { + position: absolute; + top: 2px; + width: 1.8em; + height: 1.8em +} + +.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover + { + top: 1px +} + +.ui-datepicker .ui-datepicker-prev { + left: 2px +} + +.ui-datepicker .ui-datepicker-next { + right: 2px +} + +.ui-datepicker .ui-datepicker-prev-hover { + left: 1px +} + +.ui-datepicker .ui-datepicker-next-hover { + right: 1px +} + +.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span + { + display: block; + position: absolute; + left: 50%; + margin-left: -8px; + top: 50%; + margin-top: -8px +} + +.ui-datepicker .ui-datepicker-title { + margin: 0 2.3em; + line-height: 1.8em; + text-align: center +} + +.ui-datepicker .ui-datepicker-title select { + font-size: 1em; + margin: 1px 0 +} + +.ui-datepicker select.ui-datepicker-month, .ui-datepicker select.ui-datepicker-year + { + width: 45% +} + +.ui-datepicker table { + width: 100%; + font-size: .9em; + border-collapse: collapse; + margin: 0 0 .4em +} + +.ui-datepicker th { + padding: .7em .3em; + text-align: center; + font-weight: bold; + border: 0 +} + +.ui-datepicker td { + border: 0; + padding: 1px +} + +.ui-datepicker td span, .ui-datepicker td a { + display: block; + padding: .2em; + text-align: right; + text-decoration: none +} + +.ui-datepicker .ui-datepicker-buttonpane { + background-image: none; + margin: .7em 0 0 0; + padding: 0 .2em; + border-left: 0; + border-right: 0; + border-bottom: 0 +} + +.ui-datepicker .ui-datepicker-buttonpane button { + float: right; + margin: .5em .2em .4em; + cursor: pointer; + padding: .2em .6em .3em .6em; + width: auto; + overflow: visible +} + +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { + float: left +} + +.ui-datepicker.ui-datepicker-multi { + width: auto +} + +.ui-datepicker-multi .ui-datepicker-group { + float: left +} + +.ui-datepicker-multi .ui-datepicker-group table { + width: 95%; + margin: 0 auto .4em +} + +.ui-datepicker-multi-2 .ui-datepicker-group { + width: 50% +} + +.ui-datepicker-multi-3 .ui-datepicker-group { + width: 33.3% +} + +.ui-datepicker-multi-4 .ui-datepicker-group { + width: 25% +} + +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header, + .ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header + { + border-left-width: 0 +} + +.ui-datepicker-multi .ui-datepicker-buttonpane { + clear: left +} + +.ui-datepicker-row-break { + clear: both; + width: 100%; + font-size: 0 +} + +.ui-datepicker-rtl { + direction: rtl +} + +.ui-datepicker-rtl .ui-datepicker-prev { + right: 2px; + left: auto +} + +.ui-datepicker-rtl .ui-datepicker-next { + left: 2px; + right: auto +} + +.ui-datepicker-rtl .ui-datepicker-prev:hover { + right: 1px; + left: auto +} + +.ui-datepicker-rtl .ui-datepicker-next:hover { + left: 1px; + right: auto +} + +.ui-datepicker-rtl .ui-datepicker-buttonpane { + clear: right +} + +.ui-datepicker-rtl .ui-datepicker-buttonpane button { + float: left +} + +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current, + .ui-datepicker-rtl .ui-datepicker-group { + float: right +} + +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header, + .ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { + border-right-width: 0; + border-left-width: 1px +} + +.ui-datepicker .ui-icon { + display: block; + text-indent: -99999px; + overflow: hidden; + background-repeat: no-repeat; + left: .5em; + top: .3em +} + +.ui-dialog { + position: absolute; + top: 0; + left: 0; + padding: .2em; + outline: 0 +} + +.ui-dialog .ui-dialog-titlebar { + padding: .4em 1em; + position: relative +} + +.ui-dialog .ui-dialog-title { + float: left; + margin: .1em 0; + white-space: nowrap; + width: 90%; + overflow: hidden; + text-overflow: ellipsis +} + +.ui-dialog .ui-dialog-titlebar-close { + position: absolute; + right: .3em; + top: 50%; + width: 20px; + margin: -10px 0 0 0; + padding: 1px; + height: 20px +} + +.ui-dialog .ui-dialog-content { + position: relative; + border: 0; + padding: .5em 1em; + background: none; + overflow: auto +} + +.ui-dialog .ui-dialog-buttonpane { + text-align: left; + border-width: 1px 0 0 0; + background-image: none; + margin-top: .5em; + padding: .3em 1em .5em .4em +} + +.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { + float: right +} + +.ui-dialog .ui-dialog-buttonpane button { + margin: .5em .4em .5em 0; + cursor: pointer +} + +.ui-dialog .ui-resizable-n { + height: 2px; + top: 0 +} + +.ui-dialog .ui-resizable-e { + width: 2px; + right: 0 +} + +.ui-dialog .ui-resizable-s { + height: 2px; + bottom: 0 +} + +.ui-dialog .ui-resizable-w { + width: 2px; + left: 0 +} + +.ui-dialog .ui-resizable-se, .ui-dialog .ui-resizable-sw, .ui-dialog .ui-resizable-ne, + .ui-dialog .ui-resizable-nw { + width: 7px; + height: 7px +} + +.ui-dialog .ui-resizable-se { + right: 0; + bottom: 0 +} + +.ui-dialog .ui-resizable-sw { + left: 0; + bottom: 0 +} + +.ui-dialog .ui-resizable-ne { + right: 0; + top: 0 +} + +.ui-dialog .ui-resizable-nw { + left: 0; + top: 0 +} + +.ui-draggable .ui-dialog-titlebar { + cursor: move +} + +.ui-progressbar { + height: 2em; + text-align: left; + overflow: hidden +} + +.ui-progressbar .ui-progressbar-value { + margin: -1px; + height: 100% +} + +.ui-progressbar .ui-progressbar-overlay { + background: + url("data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw=="); + height: 100%; + filter: alpha(opacity = 25); + opacity: 0.25 +} + +.ui-progressbar-indeterminate .ui-progressbar-value { + background-image: none +} + +.ui-selectmenu-menu { + padding: 0; + margin: 0; + position: absolute; + top: 0; + left: 0; + display: none +} + +.ui-selectmenu-menu .ui-menu { + overflow: auto; + overflow-x: hidden; + padding-bottom: 1px +} + +.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup { + font-size: 1em; + font-weight: bold; + line-height: 1.5; + padding: 2px 0.4em; + margin: 0.5em 0 0 0; + height: auto; + border: 0 +} + +.ui-selectmenu-open { + display: block +} + +.ui-selectmenu-text { + display: block; + margin-right: 20px; + overflow: hidden; + text-overflow: ellipsis +} + +.ui-selectmenu-button.ui-button { + text-align: left; + white-space: nowrap; + width: 14em +} + +.ui-selectmenu-icon.ui-icon { + float: right; + margin-top: 0 +} + +.ui-slider { + position: relative; + text-align: left +} + +.ui-slider .ui-slider-handle { + position: absolute; + z-index: 2; + width: 1.2em; + height: 1.2em; + cursor: default; + -ms-touch-action: none; + touch-action: none +} + +.ui-slider .ui-slider-range { + position: absolute; + z-index: 1; + font-size: .7em; + display: block; + border: 0; + background-position: 0 0 +} + +.ui-slider.ui-state-disabled .ui-slider-handle, .ui-slider.ui-state-disabled .ui-slider-range + { + filter: inherit +} + +.ui-slider-horizontal { + height: .8em +} + +.ui-slider-horizontal .ui-slider-handle { + top: -.3em; + margin-left: -.6em +} + +.ui-slider-horizontal .ui-slider-range { + top: 0; + height: 100% +} + +.ui-slider-horizontal .ui-slider-range-min { + left: 0 +} + +.ui-slider-horizontal .ui-slider-range-max { + right: 0 +} + +.ui-slider-vertical { + width: .8em; + height: 100px +} + +.ui-slider-vertical .ui-slider-handle { + left: -.3em; + margin-left: 0; + margin-bottom: -.6em +} + +.ui-slider-vertical .ui-slider-range { + left: 0; + width: 100% +} + +.ui-slider-vertical .ui-slider-range-min { + bottom: 0 +} + +.ui-slider-vertical .ui-slider-range-max { + top: 0 +} + +.ui-spinner { + position: relative; + display: inline-block; + overflow: hidden; + padding: 0; + vertical-align: middle +} + +.ui-spinner-input { + border: none; + background: none; + color: inherit; + padding: .222em 0; + margin: .2em 0; + vertical-align: middle; + margin-left: .4em; + margin-right: 2em +} + +.ui-spinner-button { + width: 1.6em; + height: 50%; + font-size: .5em; + padding: 0; + margin: 0; + text-align: center; + position: absolute; + cursor: default; + display: block; + overflow: hidden; + right: 0 +} + +.ui-spinner a.ui-spinner-button { + border-top-style: none; + border-bottom-style: none; + border-right-style: none +} + +.ui-spinner-up { + top: 0 +} + +.ui-spinner-down { + bottom: 0 +} + +.ui-tabs { + position: relative; + padding: .2em +} + +.ui-tabs .ui-tabs-nav { + margin: 0; + padding: .2em .2em 0 +} + +.ui-tabs .ui-tabs-nav li { + list-style: none; + float: left; + position: relative; + top: 0; + margin: 1px .2em 0 0; + border-bottom-width: 0; + padding: 0; + white-space: nowrap +} + +.ui-tabs .ui-tabs-nav .ui-tabs-anchor { + float: left; + padding: .5em 1em; + text-decoration: none +} + +.ui-tabs .ui-tabs-nav li.ui-tabs-active { + margin-bottom: -1px; + padding-bottom: 1px +} + +.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor, .ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor, + .ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor { + cursor: text +} + +.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor { + cursor: pointer +} + +.ui-tabs .ui-tabs-panel { + display: block; + border-width: 0; + padding: 1em 1.4em; + background: none +} + +.ui-tooltip { + padding: 8px; + position: absolute; + z-index: 9999; + max-width: 300px +} + +body .ui-tooltip { + border-width: 2px +} + +.ui-widget { + font-family: Arial, Helvetica, sans-serif; + font-size: 1em +} + +.ui-widget .ui-widget { + font-size: 1em +} + +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button + { + font-family: Arial, Helvetica, sans-serif; + font-size: 1em +} + +.ui-widget.ui-widget-content { + border: 1px solid #c5c5c5 +} + +.ui-widget-content { + border: 1px solid #ddd; + background: #fff; + color: #333 +} + +.ui-widget-content a { + color: #333 +} + +.ui-widget-header { + border: 1px solid #ddd; + background: #e9e9e9; + color: #333; + font-weight: bold +} + +.ui-widget-header a { + color: #333 +} + +.ui-state-default, .ui-widget-content .ui-state-default, + .ui-widget-header .ui-state-default, .ui-button, html .ui-button.ui-state-disabled:hover, + html .ui-button.ui-state-disabled:active { + border: 1px solid #c5c5c5; + background: #f6f6f6; + font-weight: normal; + color: #454545 +} + +.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited, + a.ui-button, a:link.ui-button, a:visited.ui-button, .ui-button { + color: #454545; + text-decoration: none +} + +.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, + .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus, + .ui-button:hover, .ui-button:focus { + border: 1px solid #ccc; + background: #ededed; + font-weight: normal; + color: #2b2b2b +} + +.ui-state-hover a, .ui-state-hover a:hover, .ui-state-hover a:link, + .ui-state-hover a:visited, .ui-state-focus a, .ui-state-focus a:hover, + .ui-state-focus a:link, .ui-state-focus a:visited, a.ui-button:hover, a.ui-button:focus + { + color: #2b2b2b; + text-decoration: none +} + +.ui-visual-focus { + box-shadow: 0 0 3px 1px rgb(94, 158, 214) +} + +.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active, + a.ui-button:active, .ui-button:active, .ui-button.ui-state-active:hover + { + border: 1px solid #003eff; + background: #007fff; + font-weight: normal; + color: #fff +} + +.ui-icon-background, .ui-state-active .ui-icon-background { + border: #003eff; + background-color: #fff +} + +.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited + { + color: #fff; + text-decoration: none +} + +.ui-state-highlight, .ui-widget-content .ui-state-highlight, + .ui-widget-header .ui-state-highlight { + border: 1px solid #dad55e; + background: #fffa90; + color: #777620 +} + +.ui-state-checked { + border: 1px solid #dad55e; + background: #fffa90 +} + +.ui-state-highlight a, .ui-widget-content .ui-state-highlight a, + .ui-widget-header .ui-state-highlight a { + color: #777620 +} + +.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error + { + border: 1px solid #f1a899; + background: #fddfdf; + color: #5f3f3f +} + +.ui-state-error a, .ui-widget-content .ui-state-error a, + .ui-widget-header .ui-state-error a { + color: #5f3f3f +} + +.ui-state-error-text, .ui-widget-content .ui-state-error-text, + .ui-widget-header .ui-state-error-text { + color: #5f3f3f +} + +.ui-priority-primary, .ui-widget-content .ui-priority-primary, + .ui-widget-header .ui-priority-primary { + font-weight: bold +} + +.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, + .ui-widget-header .ui-priority-secondary { + opacity: .7; + filter: Alpha(Opacity = 70); + font-weight: normal +} + +.ui-state-disabled, .ui-widget-content .ui-state-disabled, + .ui-widget-header .ui-state-disabled { + opacity: .35; + filter: Alpha(Opacity = 35); + background-image: none +} + +.ui-state-disabled .ui-icon { + filter: Alpha(Opacity = 35) +} + +.ui-icon { + width: 16px; + height: 16px +} + +.ui-icon, .ui-widget-content .ui-icon { + background-image: url("images/ui-icons_444444_256x240.png") +} + +.ui-widget-header .ui-icon { + background-image: url("images/ui-icons_444444_256x240.png") +} + +.ui-state-hover .ui-icon, .ui-state-focus .ui-icon, .ui-button:hover .ui-icon, + .ui-button:focus .ui-icon { + background-image: url("images/ui-icons_555555_256x240.png") +} + +.ui-state-active .ui-icon, .ui-button:active .ui-icon { + background-image: url("images/ui-icons_ffffff_256x240.png") +} + +.ui-state-highlight .ui-icon, .ui-button .ui-state-highlight.ui-icon { + background-image: url("images/ui-icons_777620_256x240.png") +} + +.ui-state-error .ui-icon, .ui-state-error-text .ui-icon { + background-image: url("images/ui-icons_cc0000_256x240.png") +} + +.ui-button .ui-icon { + background-image: url("images/ui-icons_777777_256x240.png") +} + +.ui-icon-blank { + background-position: 16px 16px +} + +.ui-icon-caret-1-n { + background-position: 0 0 +} + +.ui-icon-caret-1-ne { + background-position: -16px 0 +} + +.ui-icon-caret-1-e { + background-position: -32px 0 +} + +.ui-icon-caret-1-se { + background-position: -48px 0 +} + +.ui-icon-caret-1-s { + background-position: -65px 0 +} + +.ui-icon-caret-1-sw { + background-position: -80px 0 +} + +.ui-icon-caret-1-w { + background-position: -96px 0 +} + +.ui-icon-caret-1-nw { + background-position: -112px 0 +} + +.ui-icon-caret-2-n-s { + background-position: -128px 0 +} + +.ui-icon-caret-2-e-w { + background-position: -144px 0 +} + +.ui-icon-triangle-1-n { + background-position: 0 -16px +} + +.ui-icon-triangle-1-ne { + background-position: -16px -16px +} + +.ui-icon-triangle-1-e { + background-position: -32px -16px +} + +.ui-icon-triangle-1-se { + background-position: -48px -16px +} + +.ui-icon-triangle-1-s { + background-position: -65px -16px +} + +.ui-icon-triangle-1-sw { + background-position: -80px -16px +} + +.ui-icon-triangle-1-w { + background-position: -96px -16px +} + +.ui-icon-triangle-1-nw { + background-position: -112px -16px +} + +.ui-icon-triangle-2-n-s { + background-position: -128px -16px +} + +.ui-icon-triangle-2-e-w { + background-position: -144px -16px +} + +.ui-icon-arrow-1-n { + background-position: 0 -32px +} + +.ui-icon-arrow-1-ne { + background-position: -16px -32px +} + +.ui-icon-arrow-1-e { + background-position: -32px -32px +} + +.ui-icon-arrow-1-se { + background-position: -48px -32px +} + +.ui-icon-arrow-1-s { + background-position: -65px -32px +} + +.ui-icon-arrow-1-sw { + background-position: -80px -32px +} + +.ui-icon-arrow-1-w { + background-position: -96px -32px +} + +.ui-icon-arrow-1-nw { + background-position: -112px -32px +} + +.ui-icon-arrow-2-n-s { + background-position: -128px -32px +} + +.ui-icon-arrow-2-ne-sw { + background-position: -144px -32px +} + +.ui-icon-arrow-2-e-w { + background-position: -160px -32px +} + +.ui-icon-arrow-2-se-nw { + background-position: -176px -32px +} + +.ui-icon-arrowstop-1-n { + background-position: -192px -32px +} + +.ui-icon-arrowstop-1-e { + background-position: -208px -32px +} + +.ui-icon-arrowstop-1-s { + background-position: -224px -32px +} + +.ui-icon-arrowstop-1-w { + background-position: -240px -32px +} + +.ui-icon-arrowthick-1-n { + background-position: 1px -48px +} + +.ui-icon-arrowthick-1-ne { + background-position: -16px -48px +} + +.ui-icon-arrowthick-1-e { + background-position: -32px -48px +} + +.ui-icon-arrowthick-1-se { + background-position: -48px -48px +} + +.ui-icon-arrowthick-1-s { + background-position: -64px -48px +} + +.ui-icon-arrowthick-1-sw { + background-position: -80px -48px +} + +.ui-icon-arrowthick-1-w { + background-position: -96px -48px +} + +.ui-icon-arrowthick-1-nw { + background-position: -112px -48px +} + +.ui-icon-arrowthick-2-n-s { + background-position: -128px -48px +} + +.ui-icon-arrowthick-2-ne-sw { + background-position: -144px -48px +} + +.ui-icon-arrowthick-2-e-w { + background-position: -160px -48px +} + +.ui-icon-arrowthick-2-se-nw { + background-position: -176px -48px +} + +.ui-icon-arrowthickstop-1-n { + background-position: -192px -48px +} + +.ui-icon-arrowthickstop-1-e { + background-position: -208px -48px +} + +.ui-icon-arrowthickstop-1-s { + background-position: -224px -48px +} + +.ui-icon-arrowthickstop-1-w { + background-position: -240px -48px +} + +.ui-icon-arrowreturnthick-1-w { + background-position: 0 -64px +} + +.ui-icon-arrowreturnthick-1-n { + background-position: -16px -64px +} + +.ui-icon-arrowreturnthick-1-e { + background-position: -32px -64px +} + +.ui-icon-arrowreturnthick-1-s { + background-position: -48px -64px +} + +.ui-icon-arrowreturn-1-w { + background-position: -64px -64px +} + +.ui-icon-arrowreturn-1-n { + background-position: -80px -64px +} + +.ui-icon-arrowreturn-1-e { + background-position: -96px -64px +} + +.ui-icon-arrowreturn-1-s { + background-position: -112px -64px +} + +.ui-icon-arrowrefresh-1-w { + background-position: -128px -64px +} + +.ui-icon-arrowrefresh-1-n { + background-position: -144px -64px +} + +.ui-icon-arrowrefresh-1-e { + background-position: -160px -64px +} + +.ui-icon-arrowrefresh-1-s { + background-position: -176px -64px +} + +.ui-icon-arrow-4 { + background-position: 0 -80px +} + +.ui-icon-arrow-4-diag { + background-position: -16px -80px +} + +.ui-icon-extlink { + background-position: -32px -80px +} + +.ui-icon-newwin { + background-position: -48px -80px +} + +.ui-icon-refresh { + background-position: -64px -80px +} + +.ui-icon-shuffle { + background-position: -80px -80px +} + +.ui-icon-transfer-e-w { + background-position: -96px -80px +} + +.ui-icon-transferthick-e-w { + background-position: -112px -80px +} + +.ui-icon-folder-collapsed { + background-position: 0 -96px +} + +.ui-icon-folder-open { + background-position: -16px -96px +} + +.ui-icon-document { + background-position: -32px -96px +} + +.ui-icon-document-b { + background-position: -48px -96px +} + +.ui-icon-note { + background-position: -64px -96px +} + +.ui-icon-mail-closed { + background-position: -80px -96px +} + +.ui-icon-mail-open { + background-position: -96px -96px +} + +.ui-icon-suitcase { + background-position: -112px -96px +} + +.ui-icon-comment { + background-position: -128px -96px +} + +.ui-icon-person { + background-position: -144px -96px +} + +.ui-icon-print { + background-position: -160px -96px +} + +.ui-icon-trash { + background-position: -176px -96px +} + +.ui-icon-locked { + background-position: -192px -96px +} + +.ui-icon-unlocked { + background-position: -208px -96px +} + +.ui-icon-bookmark { + background-position: -224px -96px +} + +.ui-icon-tag { + background-position: -240px -96px +} + +.ui-icon-home { + background-position: 0 -112px +} + +.ui-icon-flag { + background-position: -16px -112px +} + +.ui-icon-calendar { + background-position: -32px -112px +} + +.ui-icon-cart { + background-position: -48px -112px +} + +.ui-icon-pencil { + background-position: -64px -112px +} + +.ui-icon-clock { + background-position: -80px -112px +} + +.ui-icon-disk { + background-position: -96px -112px +} + +.ui-icon-calculator { + background-position: -112px -112px +} + +.ui-icon-zoomin { + background-position: -128px -112px +} + +.ui-icon-zoomout { + background-position: -144px -112px +} + +.ui-icon-search { + background-position: -160px -112px +} + +.ui-icon-wrench { + background-position: -176px -112px +} + +.ui-icon-gear { + background-position: -192px -112px +} + +.ui-icon-heart { + background-position: -208px -112px +} + +.ui-icon-star { + background-position: -224px -112px +} + +.ui-icon-link { + background-position: -240px -112px +} + +.ui-icon-cancel { + background-position: 0 -128px +} + +.ui-icon-plus { + background-position: -16px -128px +} + +.ui-icon-plusthick { + background-position: -32px -128px +} + +.ui-icon-minus { + background-position: -48px -128px +} + +.ui-icon-minusthick { + background-position: -64px -128px +} + +.ui-icon-close { + background-position: -80px -128px +} + +.ui-icon-closethick { + background-position: -96px -128px +} + +.ui-icon-key { + background-position: -112px -128px +} + +.ui-icon-lightbulb { + background-position: -128px -128px +} + +.ui-icon-scissors { + background-position: -144px -128px +} + +.ui-icon-clipboard { + background-position: -160px -128px +} + +.ui-icon-copy { + background-position: -176px -128px +} + +.ui-icon-contact { + background-position: -192px -128px +} + +.ui-icon-image { + background-position: -208px -128px +} + +.ui-icon-video { + background-position: -224px -128px +} + +.ui-icon-script { + background-position: -240px -128px +} + +.ui-icon-alert { + background-position: 0 -144px +} + +.ui-icon-info { + background-position: -16px -144px +} + +.ui-icon-notice { + background-position: -32px -144px +} + +.ui-icon-help { + background-position: -48px -144px +} + +.ui-icon-check { + background-position: -64px -144px +} + +.ui-icon-bullet { + background-position: -80px -144px +} + +.ui-icon-radio-on { + background-position: -96px -144px +} + +.ui-icon-radio-off { + background-position: -112px -144px +} + +.ui-icon-pin-w { + background-position: -128px -144px +} + +.ui-icon-pin-s { + background-position: -144px -144px +} + +.ui-icon-play { + background-position: 0 -160px +} + +.ui-icon-pause { + background-position: -16px -160px +} + +.ui-icon-seek-next { + background-position: -32px -160px +} + +.ui-icon-seek-prev { + background-position: -48px -160px +} + +.ui-icon-seek-end { + background-position: -64px -160px +} + +.ui-icon-seek-start { + background-position: -80px -160px +} + +.ui-icon-seek-first { + background-position: -80px -160px +} + +.ui-icon-stop { + background-position: -96px -160px +} + +.ui-icon-eject { + background-position: -112px -160px +} + +.ui-icon-volume-off { + background-position: -128px -160px +} + +.ui-icon-volume-on { + background-position: -144px -160px +} + +.ui-icon-power { + background-position: 0 -176px +} + +.ui-icon-signal-diag { + background-position: -16px -176px +} + +.ui-icon-signal { + background-position: -32px -176px +} + +.ui-icon-battery-0 { + background-position: -48px -176px +} + +.ui-icon-battery-1 { + background-position: -64px -176px +} + +.ui-icon-battery-2 { + background-position: -80px -176px +} + +.ui-icon-battery-3 { + background-position: -96px -176px +} + +.ui-icon-circle-plus { + background-position: 0 -192px +} + +.ui-icon-circle-minus { + background-position: -16px -192px +} + +.ui-icon-circle-close { + background-position: -32px -192px +} + +.ui-icon-circle-triangle-e { + background-position: -48px -192px +} + +.ui-icon-circle-triangle-s { + background-position: -64px -192px +} + +.ui-icon-circle-triangle-w { + background-position: -80px -192px +} + +.ui-icon-circle-triangle-n { + background-position: -96px -192px +} + +.ui-icon-circle-arrow-e { + background-position: -112px -192px +} + +.ui-icon-circle-arrow-s { + background-position: -128px -192px +} + +.ui-icon-circle-arrow-w { + background-position: -144px -192px +} + +.ui-icon-circle-arrow-n { + background-position: -160px -192px +} + +.ui-icon-circle-zoomin { + background-position: -176px -192px +} + +.ui-icon-circle-zoomout { + background-position: -192px -192px +} + +.ui-icon-circle-check { + background-position: -208px -192px +} + +.ui-icon-circlesmall-plus { + background-position: 0 -208px +} + +.ui-icon-circlesmall-minus { + background-position: -16px -208px +} + +.ui-icon-circlesmall-close { + background-position: -32px -208px +} + +.ui-icon-squaresmall-plus { + background-position: -48px -208px +} + +.ui-icon-squaresmall-minus { + background-position: -64px -208px +} + +.ui-icon-squaresmall-close { + background-position: -80px -208px +} + +.ui-icon-grip-dotted-vertical { + background-position: 0 -224px +} + +.ui-icon-grip-dotted-horizontal { + background-position: -16px -224px +} + +.ui-icon-grip-solid-vertical { + background-position: -32px -224px +} + +.ui-icon-grip-solid-horizontal { + background-position: -48px -224px +} + +.ui-icon-gripsmall-diagonal-se { + background-position: -64px -224px +} + +.ui-icon-grip-diagonal-se { + background-position: -80px -224px +} + +.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { + border-top-left-radius: 3px +} + +.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { + border-top-right-radius: 3px +} + +.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { + border-bottom-left-radius: 3px +} + +.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { + border-bottom-right-radius: 3px +} + +.ui-widget-overlay { + background: #aaa; + opacity: .3; + filter: Alpha(Opacity = 30) +} + +.ui-widget-shadow { + -webkit-box-shadow: 0 0 5px #666; + box-shadow: 0 0 5px #666 +} \ No newline at end of file diff --git a/customer_domains.php b/customer_domains.php index de18a20c..26fe3833 100644 --- a/customer_domains.php +++ b/customer_domains.php @@ -16,10 +16,19 @@ * @package Panel * */ - define('AREA', 'customer'); require './lib/init.php'; +use Froxlor\Database\Database; +use Froxlor\Settings; +use Froxlor\Api\Commands\SubDomains as SubDomains; +use Froxlor\Api\Commands\Certificates as Certificates; + +// redirect if this customer page is hidden via settings +if (Settings::IsInList('panel.customer_hide_options', 'domains')) { + \Froxlor\UI\Response::redirectTo('customer_index.php'); +} + if (isset($_POST['id'])) { $id = intval($_POST['id']); } elseif (isset($_GET['id'])) { @@ -27,438 +36,139 @@ if (isset($_POST['id'])) { } if ($page == 'overview') { - $log->logAction(USR_ACTION, LOG_NOTICE, "viewed customer_domains"); - eval("echo \"" . getTemplate("domains/domains") . "\";"); + $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed customer_domains"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("domains/domains") . "\";"); } elseif ($page == 'domains') { if ($action == '') { - $log->logAction(USR_ACTION, LOG_NOTICE, "viewed customer_domains::domains"); + $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'] ); - $paging = new paging($userinfo, TABLE_PANEL_DOMAINS, $fields); - $domains_stmt = Database::prepare("SELECT `d`.`id`, `d`.`customerid`, `d`.`domain`, `d`.`documentroot`, `d`.`isemaildomain`, `d`.`caneditdomain`, `d`.`iswildcarddomain`, `d`.`parentdomainid`, `d`.`letsencrypt`, `d`.`termination_date`, `ad`.`id` AS `aliasdomainid`, `ad`.`domain` AS `aliasdomain`, `da`.`id` AS `domainaliasid`, `da`.`domain` AS `domainalias` FROM `" . TABLE_PANEL_DOMAINS . "` `d` - LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` `ad` ON `d`.`aliasdomain`=`ad`.`id` - LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` `da` ON `da`.`aliasdomain`=`d`.`id` - WHERE `d`.`customerid`= :customerid - AND `d`.`email_only`='0' - AND `d`.`id` <> :standardsubdomain " . $paging->getSqlWhere(true) . " " . $paging->getSqlOrderBy() . " " . $paging->getSqlLimit() - ); - Database::pexecute($domains_stmt, array("customerid" => $userinfo['customerid'], "standardsubdomain" => $userinfo['standardsubdomain'])); - $paging->setEntries(Database::num_rows()); + try { + // get total count + $json_result = SubDomains::getLocal($userinfo)->listingCount(); + $result = json_decode($json_result, true)['data']; + // initialize pagination and filtering + $paging = new \Froxlor\UI\Pagination($userinfo, $fields, $result); + // get list + $json_result = SubDomains::getLocal($userinfo, $paging->getApiCommandParams())->listing(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; + $sortcode = $paging->getHtmlSortCode($lng); $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); $searchcode = $paging->getHtmlSearchCode($lng); $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); $domains = ''; $parentdomains_count = 0; - $domains_count = 0; + $domains_count = $paging->getEntries(); $domain_array = array(); - while ($row = $domains_stmt->fetch(PDO::FETCH_ASSOC)) { - $row['domain'] = $idna_convert->decode($row['domain']); - $row['aliasdomain'] = $idna_convert->decode($row['aliasdomain']); - $row['domainalias'] = $idna_convert->decode($row['domainalias']); - + foreach ($result['list'] as $row) { + formatDomainEntry($row, $idna_convert); if ($row['parentdomainid'] == '0' && $row['caneditdomain'] == '1') { - $parentdomains_count++; + $parentdomains_count ++; } + $domain_array[$row['parentdomainname']][] = $row; + } - /** - * check for set ssl-certs to show different state-icons - */ - // nothing (ssl_global) - $row['domain_hascert'] = 0; - $ssl_stmt = Database::prepare("SELECT * FROM `".TABLE_PANEL_DOMAIN_SSL_SETTINGS."` WHERE `domainid` = :domainid"); - Database::pexecute($ssl_stmt, array("domainid" => $row['id'])); - $ssl_result = $ssl_stmt->fetch(PDO::FETCH_ASSOC); - if (is_array($ssl_result) && isset($ssl_result['ssl_cert_file']) && $ssl_result['ssl_cert_file'] != '') { - // own certificate (ssl_customer_green) - $row['domain_hascert'] = 1; + foreach ($domain_array as $parentdomain => $sdomains) { + // PARENTDOMAIN + if (Settings::Get('system.awstats_enabled') == '1') { + $statsapp = 'awstats'; } else { - // check if it's parent has one set (shared) - if ($row['parentdomainid'] != 0) { - $ssl_stmt = Database::prepare("SELECT * FROM `".TABLE_PANEL_DOMAIN_SSL_SETTINGS."` WHERE `domainid` = :domainid"); - Database::pexecute($ssl_stmt, array("domainid" => $row['parentdomainid'])); - $ssl_result = $ssl_stmt->fetch(PDO::FETCH_ASSOC); - if (is_array($ssl_result) && isset($ssl_result['ssl_cert_file']) && $ssl_result['ssl_cert_file'] != '') { - // parent has a certificate (ssl_shared) - $row['domain_hascert'] = 2; - } - } + $statsapp = 'webalizer'; } + $row = [ + 'domain' => $idna_convert->decode($parentdomain) + ]; + eval("\$domains.=\"" . \Froxlor\UI\Template::getTemplate("domains/domains_delimiter") . "\";"); - $row['termination_date'] = str_replace("0000-00-00", "", $row['termination_date']); - if($row['termination_date'] != "") { - $cdate = strtotime($row['termination_date'] . " 23:59:59"); - $today = time(); + foreach ($sdomains as $domain) { + $row = \Froxlor\PhpHelper::htmlentitiesArray($domain); - if($cdate < $today) { - $row['termination_css'] = 'domain-expired'; - } else { - $row['termination_css'] = 'domain-canceled'; + // show docroot nicely + if (strpos($row['documentroot'], $userinfo['documentroot']) === 0) { + $row['documentroot'] = \Froxlor\FileDir::makeCorrectDir(str_replace($userinfo['documentroot'], "/", $row['documentroot'])); } - } - - $domains_count++; - $domain_array[$row['domain']] = $row; - } - - ksort($domain_array); - $domain_id_array = array(); - foreach ($domain_array as $sortkey => $row) { - $domain_id_array[$row['id']] = $sortkey; - } - - $domain_sort_array = array(); - foreach ($domain_array as $sortkey => $row) { - if ($row['parentdomainid'] == 0) { - $domain_sort_array[$sortkey][$sortkey] = $row; - } else { - // when searching and the results are subdomains only, we need to get - // the parent domain to this subdomain - if (!isset($domain_id_array[$row['parentdomainid']])) { - $domain_id_array[$row['parentdomainid']] = "[parent-domain]"; + // get ssl-ips if activated + $show_ssledit = false; + if (Settings::Get('system.use_ssl') == '1' && \Froxlor\Domain\Domain::domainHasSslIpPort($row['id']) && $row['caneditdomain'] == '1' && $row['letsencrypt'] == 0) { + $show_ssledit = true; } - $domain_sort_array[$domain_id_array[$row['parentdomainid']]][$sortkey] = $row; + eval("\$domains.=\"" . \Froxlor\UI\Template::getTemplate("domains/domains_domain") . "\";"); } } - $domain_array = array(); - - if ($paging->sortfield == 'd.domain' && $paging->sortorder == 'asc') { - ksort($domain_sort_array); - } elseif ($paging->sortfield == 'd.domain' && $paging->sortorder == 'desc') { - krsort($domain_sort_array); - } - - $i = 0; - foreach ($domain_sort_array as $sortkey => $domain_array) { - if ($paging->checkDisplay($i)) { - - if (isset($domain_array[$sortkey])) { - $row = htmlentities_array($domain_array[$sortkey]); - if (Settings::Get('system.awstats_enabled') == '1') { - $statsapp = 'awstats'; - } else { - $statsapp = 'webalizer'; - } - eval("\$domains.=\"" . getTemplate("domains/domains_delimiter") . "\";"); - } - - if ($paging->sortfield == 'd.domain' && $paging->sortorder == 'asc') { - ksort($domain_array); - } elseif ($paging->sortfield == 'd.domain' && $paging->sortorder == 'desc') { - krsort($domain_array); - } - - foreach ($domain_array as $row) { - if (strpos($row['documentroot'], $userinfo['documentroot']) === 0) { - $row['documentroot'] = makeCorrectDir(str_replace($userinfo['documentroot'], "/", $row['documentroot'])); - } - - // get ssl-ips if activated - $show_ssledit = false; - if (Settings::Get('system.use_ssl') == '1' && domainHasSslIpPort($row['id']) && $row['caneditdomain'] == '1' && $row['letsencrypt'] == 0) { - $show_ssledit = true; - } - $row = htmlentities_array($row); - eval("\$domains.=\"" . getTemplate("domains/domains_domain") . "\";"); - } - } - - $i+= count($domain_array); - } - - eval("echo \"" . getTemplate("domains/domainlist") . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("domains/domainlist") . "\";"); } elseif ($action == 'delete' && $id != 0) { - $stmt = Database::prepare("SELECT `id`, `customerid`, `domain`, `documentroot`, `isemaildomain`, `parentdomainid` FROM `" . TABLE_PANEL_DOMAINS . "` - WHERE `customerid` = :customerid - AND `id` = :id" - ); - Database::pexecute($stmt, array("customerid" => $userinfo['customerid'], "id" => $id)); - $result = $stmt->fetch(PDO::FETCH_ASSOC); + try { + $json_result = SubDomains::getLocal($userinfo, array( + 'id' => $id + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; $alias_stmt = Database::prepare("SELECT COUNT(`id`) AS `count` FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `aliasdomain` = :aliasdomain"); - Database::pexecute($alias_stmt, array("aliasdomain" => $id)); - $alias_check = $alias_stmt->fetch(PDO::FETCH_ASSOC); + $alias_check = Database::pexecute_first($alias_stmt, array( + "aliasdomain" => $id + )); if (isset($result['parentdomainid']) && $result['parentdomainid'] != '0' && $alias_check['count'] == 0) { if (isset($_POST['send']) && $_POST['send'] == 'send') { - if ($result['isemaildomain'] == '1') { - $emails_stmt = Database::prepare("SELECT COUNT(`id`) AS `count` FROM `" . TABLE_MAIL_VIRTUAL . "` - WHERE `customerid` = :customerid - AND `domainid` = :domainid" - ); - Database::pexecute($emails_stmt, array("customerid" => $userinfo['customerid'], "domainid" => $id)); - $emails = $emails_stmt->fetch(PDO::FETCH_ASSOC); - - if ($emails['count'] != '0') { - standard_error('domains_cantdeletedomainwithemail'); - } + try { + SubDomains::getLocal($userinfo, $_POST)->delete(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } - - $log->logAction(USR_ACTION, LOG_INFO, "deleted subdomain '" . $idna_convert->decode($result['domain']) . "'"); - $stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_DOMAINS . "` WHERE - `customerid` = :customerid - AND `id` = :id" - ); - Database::pexecute($stmt, array("customerid" => $userinfo['customerid'], "id" => $id)); - - $stmt = Database::prepare("UPDATE `" . TABLE_PANEL_CUSTOMERS . "` - SET `subdomains_used` = `subdomains_used` - 1 - WHERE `customerid` = :customerid" - ); - Database::pexecute($stmt, array("customerid" => $userinfo['customerid'])); - - // remove connections to ips and domainredirects - $del_stmt = Database::prepare(" - DELETE FROM `" . TABLE_DOMAINTOIP . "` - WHERE `id_domain` = :domainid" - ); - Database::pexecute($del_stmt, array('domainid' => $id)); - - $del_stmt = Database::prepare(" - DELETE FROM `" . TABLE_PANEL_DOMAINREDIRECTS . "` - WHERE `did` = :domainid" - ); - Database::pexecute($del_stmt, array('domainid' => $id)); - - // remove certificate from domain_ssl_settings, fixes #1596 - $del_stmt = Database::prepare(" - DELETE FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` - WHERE `domainid` = :domainid" - ); - Database::pexecute($del_stmt, array('domainid' => $id)); - - inserttask('1'); - - // Using nameserver, insert a task which rebuilds the server config - inserttask('4'); - - redirectTo($filename, array('page' => $page, 's' => $s)); + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); } else { - ask_yesno('domains_reallydelete', $filename, array('id' => $id, 'page' => $page, 'action' => $action), $idna_convert->decode($result['domain'])); + \Froxlor\UI\HTML::askYesNo('domains_reallydelete', $filename, array( + 'id' => $id, + 'page' => $page, + 'action' => $action + ), $idna_convert->decode($result['domain'])); } } else { - standard_error('domains_cantdeletemaindomain'); + \Froxlor\UI\Response::standard_error('domains_cantdeletemaindomain'); } } elseif ($action == 'add') { if ($userinfo['subdomains_used'] < $userinfo['subdomains'] || $userinfo['subdomains'] == '-1') { if (isset($_POST['send']) && $_POST['send'] == 'send') { - $subdomain = $idna_convert->encode(preg_replace(array('/\:(\d)+$/', '/^https?\:\/\//'), '', validate($_POST['subdomain'], 'subdomain', '', 'subdomainiswrong'))); - $domain = $idna_convert->encode($_POST['domain']); - $domain_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_DOMAINS . "` - WHERE `domain` = :domain - AND `customerid` = :customerid - AND `parentdomainid` = '0' - AND `email_only` = '0' - AND `caneditdomain` = '1'" - ); - $domain_check = Database::pexecute_first($domain_stmt, array("domain" => $domain, "customerid" => $userinfo['customerid'])); - - $completedomain = $subdomain . '.' . $domain; - - if ($completedomain == Settings::Get('system.hostname')) { - standard_error('admin_domain_emailsystemhostname'); - } - - $completedomain_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_DOMAINS . "` - WHERE `domain` = :domain - AND `customerid` = :customerid - AND `email_only` = '0' - AND `caneditdomain` = '1'" - ); - $completedomain_check = Database::pexecute_first($completedomain_stmt, array("domain" => $completedomain, "customerid" => $userinfo['customerid'])); - - $aliasdomain = intval($_POST['alias']); - $aliasdomain_check = array('id' => 0); - $_doredirect = false; - - if ($aliasdomain != 0) { - // also check ip/port combination to be the same, #176 - $aliasdomain_stmt = Database::prepare("SELECT `d`.`id` FROM `" . TABLE_PANEL_DOMAINS . "` `d` , `" . TABLE_PANEL_CUSTOMERS . "` `c` , `".TABLE_DOMAINTOIP."` `dip` - WHERE `d`.`aliasdomain` IS NULL - AND `d`.`id` = :id - AND `c`.`standardsubdomain` <> `d`.`id` - AND `d`.`customerid` = :customerid - AND `c`.`customerid` = `d`.`customerid` - AND `d`.`id` = `dip`.`id_domain` - AND `dip`.`id_ipandports` - IN (SELECT `id_ipandports` FROM `".TABLE_DOMAINTOIP."` - WHERE `id_domain` = :id ) - GROUP BY `d`.`domain` - ORDER BY `d`.`domain` ASC;" - ); - $aliasdomain_check = Database::pexecute_first($aliasdomain_stmt, array("id" => $aliasdomain, "customerid" => $userinfo['customerid'])); - } - - if (isset($_POST['url']) && $_POST['url'] != '' && validateUrl($idna_convert->encode($_POST['url']))) { - $path = $_POST['url']; - $_doredirect = true; - } else { - $path = validate($_POST['path'], 'path'); - } - - if (!preg_match('/^https?\:\/\//', $path) || !validateUrl($idna_convert->encode($path))) { - // If path is empty or '/' and 'Use domain name as default value for DocumentRoot path' is enabled in settings, - // set default path to subdomain or domain name - if ((($path == '') || ($path == '/')) && Settings::Get('system.documentroot_use_default_value') == 1) { - $path = makeCorrectDir($userinfo['documentroot'] . '/' . $completedomain); - } else { - $path = makeCorrectDir($userinfo['documentroot'] . '/' . $path); - } - if (strstr($path, ":") !== FALSE) { - standard_error('pathmaynotcontaincolon'); - } - } else { - $_doredirect = true; - } - - $openbasedir_path = '0'; - if (isset($_POST['openbasedir_path']) && $_POST['openbasedir_path'] == '1') { - $openbasedir_path = '1'; - } - - $ssl_redirect = '0'; - if (isset($_POST['ssl_redirect']) && $_POST['ssl_redirect'] == '1') { - // a ssl-redirect only works if there actually is a - // ssl ip/port assigned to the domain - if (domainHasSslIpPort($domain_check['id']) == true) { - $ssl_redirect = '1'; - $_doredirect = true; - } else { - standard_error('sslredirectonlypossiblewithsslipport'); - } - } - - $letsencrypt = '0'; - if (isset($_POST['letsencrypt']) && $_POST['letsencrypt'] == '1') { - // let's encrypt only works if there actually is a - // ssl ip/port assigned to the domain - if (domainHasSslIpPort($domain_check['id']) == true) { - $letsencrypt = '1'; - } else { - standard_error('letsencryptonlypossiblewithsslipport'); - } - } - - if ($aliasdomain != 0 && $letsencrypt != 0) - { - standard_error('letsencryptdoesnotworkwithaliasdomains'); - } - - // Temporarily deactivate ssl_redirect until Let's Encrypt certificate was generated - if ($ssl_redirect > 0 && $letsencrypt == 1) { - $ssl_redirect = 2; - } - - if ($path == '') { - standard_error('patherror'); - } elseif ($subdomain == '') { - standard_error(array('stringisempty', 'domainname')); - } elseif ($subdomain == 'www' && $domain_check['wwwserveralias'] == '1') { - standard_error('wwwnotallowed'); - } elseif ($domain == '') { - standard_error('domaincantbeempty'); - } elseif (strtolower($completedomain_check['domain']) == strtolower($completedomain)) { - standard_error('domainexistalready', $completedomain); - } elseif (strtolower($domain_check['domain']) != strtolower($domain)) { - standard_error('maindomainnonexist', $domain); - } elseif ($aliasdomain_check['id'] != $aliasdomain) { - standard_error('domainisaliasorothercustomer'); - } else { - // get the phpsettingid from parentdomain, #107 - $phpsid_stmt = Database::prepare("SELECT `phpsettingid` FROM `".TABLE_PANEL_DOMAINS."` - WHERE `id` = :id" - ); - Database::pexecute($phpsid_stmt, array("id" => $domain_check['id'])); - $phpsid_result = $phpsid_stmt->fetch(PDO::FETCH_ASSOC); - - if (!isset($phpsid_result['phpsettingid']) || (int)$phpsid_result['phpsettingid'] <= 0) { - // assign default config - $phpsid_result['phpsettingid'] = 1; - } - - $stmt = Database::prepare("INSERT INTO `" . TABLE_PANEL_DOMAINS . "` SET - `customerid` = :customerid, - `domain` = :domain, - `documentroot` = :documentroot, - `aliasdomain` = :aliasdomain, - `parentdomainid` = :parentdomainid, - `wwwserveralias` = :wwwserveralias, - `isemaildomain` = :isemaildomain, - `iswildcarddomain` = :iswildcarddomain, - `openbasedir` = :openbasedir, - `openbasedir_path` = :openbasedir_path, - `speciallogfile` = :speciallogfile, - `specialsettings` = :specialsettings, - `ssl_redirect` = :ssl_redirect, - `phpsettingid` = :phpsettingid, - `letsencrypt` = :letsencrypt" - ); - $params = array( - "customerid" => $userinfo['customerid'], - "domain" => $completedomain, - "documentroot" => $path, - "aliasdomain" => $aliasdomain != 0 ? $aliasdomain : null, - "parentdomainid" => $domain_check['id'], - "wwwserveralias" => $domain_check['wwwserveralias'] == '1' ? '1' : '0', - "iswildcarddomain" => $domain_check['iswildcarddomain'] == '1' ? '1' : '0', - "isemaildomain" => $domain_check['subcanemaildomain'] == '3' ? '1' : '0', - "openbasedir" => $domain_check['openbasedir'], - "openbasedir_path" => $openbasedir_path, - "speciallogfile" => $domain_check['speciallogfile'], - "specialsettings" => $domain_check['specialsettings'], - "ssl_redirect" => $ssl_redirect, - "phpsettingid" => $phpsid_result['phpsettingid'], - "letsencrypt" => $letsencrypt - ); - Database::pexecute($stmt, $params); - - if ($_doredirect) { - $did = Database::lastInsertId(); - $redirect = isset($_POST['redirectcode']) ? (int)$_POST['redirectcode'] : Settings::Get('customredirect.default'); - addRedirectToDomain($did, $redirect); - } - - $stmt = Database::prepare("INSERT INTO `".TABLE_DOMAINTOIP."` - (`id_domain`, `id_ipandports`) - SELECT LAST_INSERT_ID(), `id_ipandports` - FROM `".TABLE_DOMAINTOIP."` - WHERE `id_domain` = :id_domain" - ); - Database::pexecute($stmt, array("id_domain" => $domain_check['id'])); - - $stmt = Database::prepare("UPDATE `" . TABLE_PANEL_CUSTOMERS . "` - SET `subdomains_used` = `subdomains_used` + 1 - WHERE `customerid` = :customerid" - ); - Database::pexecute($stmt, array("customerid" => $userinfo['customerid'])); - - $log->logAction(USR_ACTION, LOG_INFO, "added subdomain '" . $completedomain . "'"); - inserttask('1'); - - // Using nameserver, insert a task which rebuilds the server config - inserttask('4'); - - redirectTo($filename, array('page' => $page, 's' => $s)); + try { + SubDomains::getLocal($userinfo, $_POST)->add(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); } else { $stmt = Database::prepare("SELECT `id`, `domain`, `documentroot`, `ssl_redirect`,`isemaildomain`,`letsencrypt` FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `customerid` = :customerid AND `parentdomainid` = '0' AND `email_only` = '0' AND `caneditdomain` = '1' - ORDER BY `domain` ASC" - ); - Database::pexecute($stmt, array("customerid" => $userinfo['customerid'])); + ORDER BY `domain` ASC"); + Database::pexecute($stmt, array( + "customerid" => $userinfo['customerid'] + )); $domains = ''; while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { - $domains .= makeoption($idna_convert->decode($row['domain']), $row['domain']); + $domains .= \Froxlor\UI\HTML::makeoption($idna_convert->decode($row['domain']), $row['domain']); } - $aliasdomains = makeoption($lng['domains']['noaliasdomain'], 0, NULL, true); + $aliasdomains = \Froxlor\UI\HTML::makeoption($lng['domains']['noaliasdomain'], 0, NULL, true); $domains_stmt = Database::prepare("SELECT `d`.`id`, `d`.`domain` FROM `" . TABLE_PANEL_DOMAINS . "` `d`, `" . TABLE_PANEL_CUSTOMERS . "` `c` WHERE `d`.`aliasdomain` IS NULL AND `d`.`id` <> `c`.`standardsubdomain` @@ -466,232 +176,97 @@ if ($page == 'overview') { AND `d`.`customerid`=`c`.`customerid` AND `d`.`email_only`='0' AND `d`.`customerid`= :customerid - ORDER BY `d`.`domain` ASC" - ); - Database::pexecute($domains_stmt, array("customerid" => $userinfo['customerid'])); + ORDER BY `d`.`domain` ASC"); + Database::pexecute($domains_stmt, array( + "customerid" => $userinfo['customerid'] + )); while ($row_domain = $domains_stmt->fetch(PDO::FETCH_ASSOC)) { - $aliasdomains .= makeoption($idna_convert->decode($row_domain['domain']), $row_domain['id']); + $aliasdomains .= \Froxlor\UI\HTML::makeoption($idna_convert->decode($row_domain['domain']), $row_domain['id']); } $redirectcode = ''; if (Settings::Get('customredirect.enabled') == '1') { - $codes = getRedirectCodesArray(); + $codes = \Froxlor\Domain\Domain::getRedirectCodesArray(); foreach ($codes as $rc) { - $redirectcode .= makeoption($rc['code']. ' ('.$lng['redirect_desc'][$rc['desc']].')', $rc['id']); + $redirectcode .= \Froxlor\UI\HTML::makeoption($rc['code'] . ' (' . $lng['redirect_desc'][$rc['desc']] . ')', $rc['id']); } } // check if we at least have one ssl-ip/port, #1179 $ssl_ipsandports = ''; - $ssl_ip_stmt = Database::prepare("SELECT COUNT(*) as countSSL FROM `panel_ipsandports` WHERE `ssl`='1'"); + $ssl_ip_stmt = Database::prepare(" + SELECT COUNT(*) as countSSL + FROM `" . TABLE_PANEL_IPSANDPORTS . "` pip + LEFT JOIN `" . TABLE_DOMAINTOIP . "` dti ON dti.id_ipandports = pip.id + WHERE pip.`ssl`='1' + "); Database::pexecute($ssl_ip_stmt); $resultX = $ssl_ip_stmt->fetch(PDO::FETCH_ASSOC); - if (isset($resultX['countSSL']) && (int)$resultX['countSSL'] > 0) { + if (isset($resultX['countSSL']) && (int) $resultX['countSSL'] > 0) { $ssl_ipsandports = 'notempty'; } - $openbasedir = makeoption($lng['domain']['docroot'], 0, NULL, true) . makeoption($lng['domain']['homedir'], 1, NULL, true); - $pathSelect = makePathfield($userinfo['documentroot'], $userinfo['guid'], $userinfo['guid']); + $openbasedir = \Froxlor\UI\HTML::makeoption($lng['domain']['docroot'], 0, NULL, true) . \Froxlor\UI\HTML::makeoption($lng['domain']['homedir'], 1, NULL, true); + $pathSelect = \Froxlor\FileDir::makePathfield($userinfo['documentroot'], $userinfo['guid'], $userinfo['guid']); - $subdomain_add_data = include_once dirname(__FILE__).'/lib/formfields/customer/domains/formfield.domains_add.php'; - $subdomain_add_form = htmlform::genHTMLForm($subdomain_add_data); + $phpconfigs = ''; + $has_phpconfigs = false; + if (isset($userinfo['allowed_phpconfigs']) && ! empty($userinfo['allowed_phpconfigs'])) { + $has_phpconfigs = true; + $allowed_cfg = json_decode($userinfo['allowed_phpconfigs'], JSON_OBJECT_AS_ARRAY); + $phpconfigs_result_stmt = Database::query(" + SELECT c.*, fc.description as interpreter + FROM `" . TABLE_PANEL_PHPCONFIGS . "` c + LEFT JOIN `" . TABLE_PANEL_FPMDAEMONS . "` fc ON fc.id = c.fpmsettingid + WHERE c.id IN (" . implode(", ", $allowed_cfg) . ") + "); + while ($phpconfigs_row = $phpconfigs_result_stmt->fetch(PDO::FETCH_ASSOC)) { + if ((int) Settings::Get('phpfpm.enabled') == 1) { + $phpconfigs .= \Froxlor\UI\HTML::makeoption($phpconfigs_row['description'] . " [" . $phpconfigs_row['interpreter'] . "]", $phpconfigs_row['id'], Settings::Get('phpfpm.defaultini'), true, true); + } else { + $phpconfigs .= \Froxlor\UI\HTML::makeoption($phpconfigs_row['description'], $phpconfigs_row['id'], Settings::Get('system.mod_fcgid_defaultini'), true, true); + } + } + } + + $subdomain_add_data = include_once dirname(__FILE__) . '/lib/formfields/customer/domains/formfield.domains_add.php'; + $subdomain_add_form = \Froxlor\UI\HtmlForm::genHTMLForm($subdomain_add_data); $title = $subdomain_add_data['domain_add']['title']; $image = $subdomain_add_data['domain_add']['image']; - eval("echo \"" . getTemplate("domains/domains_add") . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("domains/domains_add") . "\";"); } } } elseif ($action == 'edit' && $id != 0) { - $stmt = Database::prepare("SELECT `d`.`id`, `d`.`customerid`, `d`.`domain`, `d`.`documentroot`, `d`.`isemaildomain`, `d`.`wwwserveralias`, `d`.`iswildcarddomain`, - `d`.`parentdomainid`, `d`.`ssl_redirect`, `d`.`aliasdomain`, `d`.`openbasedir`, `d`.`openbasedir_path`, `d`.`letsencrypt`, `pd`.`subcanemaildomain` - FROM `" . TABLE_PANEL_DOMAINS . "` `d`, `" . TABLE_PANEL_DOMAINS . "` `pd` - WHERE `d`.`customerid` = :customerid - AND `d`.`id` = :id - AND ((`d`.`parentdomainid`!='0' - AND `pd`.`id` = `d`.`parentdomainid`) - OR (`d`.`parentdomainid`='0' - AND `pd`.`id` = `d`.`id`)) - AND `d`.`caneditdomain`='1'"); - $result = Database::pexecute_first($stmt, array("customerid" => $userinfo['customerid'], "id" => $id)); - - $alias_stmt = Database::prepare("SELECT COUNT(`id`) AS count FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `aliasdomain`= :aliasdomain"); - $alias_check = Database::pexecute_first($alias_stmt, array("aliasdomain" => $result['id'])); - $alias_check = $alias_check['count']; - $_doredirect = false; + try { + $json_result = SubDomains::getLocal($userinfo, array( + 'id' => $id + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; if (isset($result['customerid']) && $result['customerid'] == $userinfo['customerid']) { if (isset($_POST['send']) && $_POST['send'] == 'send') { - if (isset($_POST['url']) && $_POST['url'] != '' && validateUrl($idna_convert->encode($_POST['url']))) { - $path = $_POST['url']; - $_doredirect = true; - } else { - $path = validate($_POST['path'], 'path'); - } - - if (!preg_match('/^https?\:\/\//', $path) || !validateUrl($idna_convert->encode($path))) { - // If path is empty or '/' and 'Use domain name as default value for DocumentRoot path' is enabled in settings, - // set default path to subdomain or domain name - if ((($path == '') || ($path == '/')) && Settings::Get('system.documentroot_use_default_value') == 1) { - $path = makeCorrectDir($userinfo['documentroot'] . '/' . $result['domain']); - } else { - $path = makeCorrectDir($userinfo['documentroot'] . '/' . $path); - } - if (strstr($path, ":") !== FALSE) { - standard_error('pathmaynotcontaincolon'); - } - } else { - $_doredirect = true; - } - - $aliasdomain = intval($_POST['alias']); - - if (isset($_POST['selectserveralias'])) { - $iswildcarddomain = ($_POST['selectserveralias'] == '0') ? '1' : '0'; - $wwwserveralias = ($_POST['selectserveralias'] == '1') ? '1' : '0'; - } else { - $iswildcarddomain = $result['iswildcarddomain']; - $wwwserveralias = $result['wwwserveralias']; - } - - if ($result['parentdomainid'] != '0' && ($result['subcanemaildomain'] == '1' || $result['subcanemaildomain'] == '2') && isset($_POST['isemaildomain'])) { - $isemaildomain = intval($_POST['isemaildomain']); - } else { - $isemaildomain = $result['isemaildomain']; - } - - $aliasdomain_check = array('id' => 0); - - if ($aliasdomain != 0) { - $aliasdomain_stmt = Database::prepare("SELECT `id` FROM `" . TABLE_PANEL_DOMAINS . "` `d`,`" . TABLE_PANEL_CUSTOMERS . "` `c` - WHERE `d`.`customerid`= :customerid - AND `d`.`aliasdomain` IS NULL - AND `d`.`id`<>`c`.`standardsubdomain` - AND `c`.`customerid`= :customerid - AND `d`.`id`= :id" - ); - $aliasdomain_check = Database::pexecute_first($aliasdomain_stmt, array("customerid" => $result['customerid'], "id" => $aliasdomain)); - } - - if ($aliasdomain_check['id'] != $aliasdomain) { - standard_error('domainisaliasorothercustomer'); - } - - if (isset($_POST['openbasedir_path']) && $_POST['openbasedir_path'] == '1') { - $openbasedir_path = '1'; - } else { - $openbasedir_path = '0'; - } - - if (isset($_POST['ssl_redirect']) && $_POST['ssl_redirect'] == '1') { - // a ssl-redirect only works if there actually is a - // ssl ip/port assigned to the domain - if (domainHasSslIpPort($id) == true) { - $ssl_redirect = '1'; - $_doredirect = true; - } else { - standard_error('sslredirectonlypossiblewithsslipport'); - } - } else { - $ssl_redirect = '0'; - } - - if (isset($_POST['letsencrypt']) && $_POST['letsencrypt'] == '1') { - // let's encrypt only works if there actually is a - // ssl ip/port assigned to the domain - if (domainHasSslIpPort($id) == true) { - $letsencrypt = '1'; - } else { - standard_error('letsencryptonlypossiblewithsslipport'); - } - } else { - $letsencrypt = '0'; - } - - if ($aliasdomain != 0 && $letsencrypt != 0) - { - standard_error('letsencryptdoesnotworkwithaliasdomains'); - } - - // We can't enable let's encrypt for wildcard - domains - if ($iswildcarddomain == '1' && $letsencrypt == '1') { - standard_error('nowildcardwithletsencrypt'); - } - - // Temporarily deactivate ssl_redirect until Let's Encrypt certificate was generated - if ($ssl_redirect > 0 && $letsencrypt == 1 && $result['letsencrypt'] != $letsencrypt) { - $ssl_redirect = 2; - } - - if ($path == '') { - standard_error('patherror'); - } else { - if (($result['isemaildomain'] == '1') && ($isemaildomain == '0')) { - $params = array("customerid" => $userinfo['customerid'], "domainid" => $id); - $stmt = Database::prepare("DELETE FROM `" . TABLE_MAIL_USERS . "` WHERE `customerid`= :customerid AND `domainid`= :domainid"); - Database::pexecute($stmt, $params); - $stmt = Database::prepare("DELETE FROM `" . TABLE_MAIL_VIRTUAL . "` WHERE `customerid`= :customerid AND `domainid`= :domainid"); - Database::pexecute($stmt, $params); - $log->logAction(USR_ACTION, LOG_NOTICE, "automatically deleted mail-table entries for '" . $idna_convert->decode($result['domain']) . "'"); - } - - if ($_doredirect) { - $redirect = isset($_POST['redirectcode']) ? (int)$_POST['redirectcode'] : false; - updateRedirectOfDomain($id, $redirect); - } - - if ($path != $result['documentroot'] - || $isemaildomain != $result['isemaildomain'] - || $wwwserveralias != $result['wwwserveralias'] - || $iswildcarddomain != $result['iswildcarddomain'] - || $aliasdomain != $result['aliasdomain'] - || $openbasedir_path != $result['openbasedir_path'] - || $ssl_redirect != $result['ssl_redirect'] - || $letsencrypt != $result['letsencrypt']) { - $log->logAction(USR_ACTION, LOG_INFO, "edited domain '" . $idna_convert->decode($result['domain']) . "'"); - - $stmt = Database::prepare("UPDATE `" . TABLE_PANEL_DOMAINS . "` SET - `documentroot`= :documentroot, - `isemaildomain`= :isemaildomain, - `wwwserveralias`= :wwwserveralias, - `iswildcarddomain`= :iswildcarddomain, - `aliasdomain`= :aliasdomain, - `openbasedir_path`= :openbasedir_path, - `ssl_redirect`= :ssl_redirect, - `letsencrypt`= :letsencrypt - WHERE `customerid`= :customerid - AND `id`= :id" - ); - $params = array( - "documentroot" => $path, - "isemaildomain" => $isemaildomain, - "wwwserveralias" => $wwwserveralias, - "iswildcarddomain" => $iswildcarddomain, - "aliasdomain" => ($aliasdomain != 0 && $alias_check == 0) ? $aliasdomain : null, - "openbasedir_path" => $openbasedir_path, - "ssl_redirect" => $ssl_redirect, - "letsencrypt" => $letsencrypt, - "customerid" => $userinfo['customerid'], - "id" => $id - ); - Database::pexecute($stmt, $params); - inserttask('1'); - - // Using nameserver, insert a task which rebuilds the server config - inserttask('4'); - - } - - redirectTo($filename, array('page' => $page, 's' => $s)); + try { + SubDomains::getLocal($userinfo, $_POST)->update(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); } else { $result['domain'] = $idna_convert->decode($result['domain']); - $domains = makeoption($lng['domains']['noaliasdomain'], 0, $result['aliasdomain'], true); + $domains = \Froxlor\UI\HTML::makeoption($lng['domains']['noaliasdomain'], 0, $result['aliasdomain'], true); // also check ip/port combination to be the same, #176 - $domains_stmt = Database::prepare("SELECT `d`.`id`, `d`.`domain` FROM `" . TABLE_PANEL_DOMAINS . "` `d` , `" . TABLE_PANEL_CUSTOMERS . "` `c` , `".TABLE_DOMAINTOIP."` `dip` + $domains_stmt = Database::prepare("SELECT `d`.`id`, `d`.`domain` FROM `" . TABLE_PANEL_DOMAINS . "` `d` , `" . TABLE_PANEL_CUSTOMERS . "` `c` , `" . TABLE_DOMAINTOIP . "` `dip` WHERE `d`.`aliasdomain` IS NULL AND `d`.`id` <> :id AND `c`.`standardsubdomain` <> `d`.`id` @@ -700,45 +275,54 @@ if ($page == 'overview') { AND `c`.`customerid` = `d`.`customerid` AND `d`.`id` = `dip`.`id_domain` AND `dip`.`id_ipandports` - IN (SELECT `id_ipandports` FROM `".TABLE_DOMAINTOIP."` + IN (SELECT `id_ipandports` FROM `" . TABLE_DOMAINTOIP . "` WHERE `id_domain` = :id) - GROUP BY `d`.`domain` - ORDER BY `d`.`domain` ASC" - ); - Database::pexecute($domains_stmt, array("id" => $result['id'], "customerid" => $userinfo['customerid'])); + GROUP BY `d`.`id`, `d`.`domain` + ORDER BY `d`.`domain` ASC"); + Database::pexecute($domains_stmt, array( + "id" => $result['id'], + "customerid" => $userinfo['customerid'] + )); while ($row_domain = $domains_stmt->fetch(PDO::FETCH_ASSOC)) { - $domains .= makeoption($idna_convert->decode($row_domain['domain']), $row_domain['id'], $result['aliasdomain']); + $domains .= \Froxlor\UI\HTML::makeoption($idna_convert->decode($row_domain['domain']), $row_domain['id'], $result['aliasdomain']); } - if (preg_match('/^https?\:\/\//', $result['documentroot']) && validateUrl($idna_convert->encode($result['documentroot']))) { + if (preg_match('/^https?\:\/\//', $result['documentroot']) && \Froxlor\Validate\Validate::validateUrl($result['documentroot'])) { if (Settings::Get('panel.pathedit') == 'Dropdown') { $urlvalue = $result['documentroot']; - $pathSelect = makePathfield($userinfo['documentroot'], $userinfo['guid'], $userinfo['guid']); + $pathSelect = \Froxlor\FileDir::makePathfield($userinfo['documentroot'], $userinfo['guid'], $userinfo['guid']); } else { $urlvalue = ''; - $pathSelect = makePathfield($userinfo['documentroot'], $userinfo['guid'], $userinfo['guid'], $result['documentroot'], true); + $pathSelect = \Froxlor\FileDir::makePathfield($userinfo['documentroot'], $userinfo['guid'], $userinfo['guid'], $result['documentroot'], true); } } else { $urlvalue = ''; - $pathSelect = makePathfield($userinfo['documentroot'], $userinfo['guid'], $userinfo['guid'], $result['documentroot']); + $pathSelect = \Froxlor\FileDir::makePathfield($userinfo['documentroot'], $userinfo['guid'], $userinfo['guid'], $result['documentroot']); } $redirectcode = ''; if (Settings::Get('customredirect.enabled') == '1') { - $def_code = getDomainRedirectId($id); - $codes = getRedirectCodesArray(); + $def_code = \Froxlor\Domain\Domain::getDomainRedirectId($id); + $codes = \Froxlor\Domain\Domain::getRedirectCodesArray(); foreach ($codes as $rc) { - $redirectcode .= makeoption($rc['code']. ' ('.$lng['redirect_desc'][$rc['desc']].')', $rc['id'], $def_code); + $redirectcode .= \Froxlor\UI\HTML::makeoption($rc['code'] . ' (' . $lng['redirect_desc'][$rc['desc']] . ')', $rc['id'], $def_code); } } // check if we at least have one ssl-ip/port, #1179 $ssl_ipsandports = ''; - $ssl_ip_stmt = Database::prepare("SELECT COUNT(*) as countSSL FROM `panel_ipsandports` WHERE `ssl`='1'"); - Database::pexecute($ssl_ip_stmt); + $ssl_ip_stmt = Database::prepare(" + SELECT COUNT(*) as countSSL + FROM `" . TABLE_PANEL_IPSANDPORTS . "` pip + LEFT JOIN `" . TABLE_DOMAINTOIP . "` dti ON dti.id_ipandports = pip.id + WHERE `dti`.`id_domain` = :id_domain AND pip.`ssl`='1' + "); + Database::pexecute($ssl_ip_stmt, array( + "id_domain" => $result['id'] + )); $resultX = $ssl_ip_stmt->fetch(PDO::FETCH_ASSOC); - if (isset($resultX['countSSL']) && (int)$resultX['countSSL'] > 0) { + if (isset($resultX['countSSL']) && (int) $resultX['countSSL'] > 0) { $ssl_ipsandports = 'notempty'; } @@ -746,7 +330,7 @@ if ($page == 'overview') { $result['temporary_ssl_redirect'] = $result['ssl_redirect']; $result['ssl_redirect'] = ($result['ssl_redirect'] == 0 ? 0 : 1); - $openbasedir = makeoption($lng['domain']['docroot'], 0, $result['openbasedir_path'], true) . makeoption($lng['domain']['homedir'], 1, $result['openbasedir_path'], true); + $openbasedir = \Froxlor\UI\HTML::makeoption($lng['domain']['docroot'], 0, $result['openbasedir_path'], true) . \Froxlor\UI\HTML::makeoption($lng['domain']['homedir'], 1, $result['openbasedir_path'], true); // create serveralias options $serveraliasoptions = ""; @@ -756,135 +340,105 @@ if ($page == 'overview') { } elseif ($result['wwwserveralias'] == '1') { $_value = '1'; } - $serveraliasoptions .= makeoption($lng['domains']['serveraliasoption_wildcard'], '0', $_value, true, true); - $serveraliasoptions .= makeoption($lng['domains']['serveraliasoption_www'], '1', $_value, true, true); - $serveraliasoptions .= makeoption($lng['domains']['serveraliasoption_none'], '2', $_value, true, true); + $serveraliasoptions .= \Froxlor\UI\HTML::makeoption($lng['domains']['serveraliasoption_wildcard'], '0', $_value, true, true); + $serveraliasoptions .= \Froxlor\UI\HTML::makeoption($lng['domains']['serveraliasoption_www'], '1', $_value, true, true); + $serveraliasoptions .= \Froxlor\UI\HTML::makeoption($lng['domains']['serveraliasoption_none'], '2', $_value, true, true); - $ips_stmt = Database::prepare("SELECT `p`.`ip` AS `ip` FROM `".TABLE_PANEL_IPSANDPORTS."` `p` - LEFT JOIN `".TABLE_DOMAINTOIP."` `dip` + $ips_stmt = Database::prepare("SELECT `p`.`ip` AS `ip` FROM `" . TABLE_PANEL_IPSANDPORTS . "` `p` + LEFT JOIN `" . TABLE_DOMAINTOIP . "` `dip` ON ( `dip`.`id_ipandports` = `p`.`id` ) WHERE `dip`.`id_domain` = :id_domain - GROUP BY `p`.`ip`" - ); - Database::pexecute($ips_stmt, array("id_domain" => $result['id'])); + GROUP BY `p`.`ip`"); + Database::pexecute($ips_stmt, array( + "id_domain" => $result['id'] + )); $result_ipandport['ip'] = ''; while ($rowip = $ips_stmt->fetch(PDO::FETCH_ASSOC)) { $result_ipandport['ip'] .= $rowip['ip'] . "
"; } - $domainip = $result_ipandport['ip']; - $result = htmlentities_array($result); + $phpconfigs = ''; + $has_phpconfigs = false; + if (isset($userinfo['allowed_phpconfigs']) && ! empty($userinfo['allowed_phpconfigs'])) { + $has_phpconfigs = true; + $allowed_cfg = json_decode($userinfo['allowed_phpconfigs'], JSON_OBJECT_AS_ARRAY); + $phpconfigs_result_stmt = Database::query(" + SELECT c.*, fc.description as interpreter + FROM `" . TABLE_PANEL_PHPCONFIGS . "` c + LEFT JOIN `" . TABLE_PANEL_FPMDAEMONS . "` fc ON fc.id = c.fpmsettingid + WHERE c.id IN (" . implode(", ", $allowed_cfg) . ") + "); + while ($phpconfigs_row = $phpconfigs_result_stmt->fetch(PDO::FETCH_ASSOC)) { + if ((int) Settings::Get('phpfpm.enabled') == 1) { + $phpconfigs .= \Froxlor\UI\HTML::makeoption($phpconfigs_row['description'] . " [" . $phpconfigs_row['interpreter'] . "]", $phpconfigs_row['id'], $result['phpsettingid'], true, true); + } else { + $phpconfigs .= \Froxlor\UI\HTML::makeoption($phpconfigs_row['description'], $phpconfigs_row['id'], $result['phpsettingid'], true, true); + } + } + } - $subdomain_edit_data = include_once dirname(__FILE__).'/lib/formfields/customer/domains/formfield.domains_edit.php'; - $subdomain_edit_form = htmlform::genHTMLForm($subdomain_edit_data); + $alias_stmt = Database::prepare("SELECT COUNT(`id`) AS count FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `aliasdomain`= :aliasdomain"); + $alias_check = Database::pexecute_first($alias_stmt, array( + "aliasdomain" => $result['id'] + )); + $alias_check = $alias_check['count']; + + $domainip = $result_ipandport['ip']; + $result = \Froxlor\PhpHelper::htmlentitiesArray($result); + + $subdomain_edit_data = include_once dirname(__FILE__) . '/lib/formfields/customer/domains/formfield.domains_edit.php'; + $subdomain_edit_form = \Froxlor\UI\HtmlForm::genHTMLForm($subdomain_edit_data); $title = $subdomain_edit_data['domain_edit']['title']; $image = $subdomain_edit_data['domain_edit']['image']; - eval("echo \"" . getTemplate("domains/domains_edit") . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("domains/domains_edit") . "\";"); } } else { - standard_error('domains_canteditdomain'); + \Froxlor\UI\Response::standard_error('domains_canteditdomain'); } } } elseif ($page == 'domainssleditor') { if ($action == '' || $action == 'view') { + + // get domain + try { + $json_result = SubDomains::getLocal($userinfo, array( + 'id' => $id + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result_domain = json_decode($json_result, true)['data']; + if (isset($_POST['send']) && $_POST['send'] == 'send') { - - $ssl_cert_file = isset($_POST['ssl_cert_file']) ? $_POST['ssl_cert_file'] : ''; - $ssl_key_file = isset($_POST['ssl_key_file']) ? $_POST['ssl_key_file'] : ''; - $ssl_ca_file = isset($_POST['ssl_ca_file']) ? $_POST['ssl_ca_file'] : ''; - $ssl_cert_chainfile = isset($_POST['ssl_cert_chainfile']) ? $_POST['ssl_cert_chainfile'] : ''; $do_insert = isset($_POST['do_insert']) ? (($_POST['do_insert'] == 1) ? true : false) : false; - - if ($ssl_cert_file != '' && $ssl_key_file == '') { - standard_error('sslcertificateismissingprivatekey'); - } - - $do_verify = true; - - // no cert-file given -> forget everything - if ($ssl_cert_file == '') { - $ssl_key_file = ''; - $ssl_ca_file = ''; - $ssl_cert_chainfile = ''; - $do_verify = false; - } - - // verify certificate content - if ($do_verify) { - // array openssl_x509_parse ( mixed $x509cert [, bool $shortnames = true ] ) - // openssl_x509_parse() returns information about the supplied x509cert, including fields such as - // subject name, issuer name, purposes, valid from and valid to dates etc. - $cert_content = openssl_x509_parse($ssl_cert_file); - - if (is_array($cert_content) && isset($cert_content['subject']) && isset($cert_content['subject']['CN'])) { - // bool openssl_x509_check_private_key ( mixed $cert , mixed $key ) - // Checks whether the given key is the private key that corresponds to cert. - if (openssl_x509_check_private_key($ssl_cert_file, $ssl_key_file) === false) { - standard_error('sslcertificateinvalidcertkeypair'); - } - - // check optional stuff - if ($ssl_ca_file != '') { - $ca_content = openssl_x509_parse($ssl_ca_file); - if (!is_array($ca_content)) { - // invalid - standard_error('sslcertificateinvalidca'); - } - } - if ($ssl_cert_chainfile != '') { - $chain_content = openssl_x509_parse($ssl_cert_chainfile); - if (!is_array($chain_content)) { - // invalid - standard_error('sslcertificateinvalidchain'); - } - } + try { + if ($do_insert) { + Certificates::getLocal($userinfo, $_POST)->add(); } else { - standard_error('sslcertificateinvalidcert'); + Certificates::getLocal($userinfo, $_POST)->update(); } + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } - - // Add/Update database entry - $qrystart = "UPDATE "; - $qrywhere = "WHERE "; - if ($do_insert) { - $qrystart = "INSERT INTO "; - $qrywhere = ", "; - } - $stmt = Database::prepare($qrystart." `".TABLE_PANEL_DOMAIN_SSL_SETTINGS."` SET - `ssl_cert_file` = :ssl_cert_file, - `ssl_key_file` = :ssl_key_file, - `ssl_ca_file` = :ssl_ca_file, - `ssl_cert_chainfile` = :ssl_cert_chainfile - ".$qrywhere." `domainid`= :domainid" - ); - $params = array( - "ssl_cert_file" => $ssl_cert_file, - "ssl_key_file" => $ssl_key_file, - "ssl_ca_file" => $ssl_ca_file, - "ssl_cert_chainfile" => $ssl_cert_chainfile, - "domainid" => $id - ); - Database::pexecute($stmt, $params); - - // insert task to re-generate webserver-configs (#1260) - inserttask('1'); - // back to domain overview - redirectTo($filename, array('page' => 'domains', 's' => $s)); + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => 'domains', + 's' => $s + )); } - $stmt = Database::prepare("SELECT * FROM `".TABLE_PANEL_DOMAIN_SSL_SETTINGS."` - WHERE `domainid`= :domainid" - ); - Database::pexecute($stmt, array("domainid" => $id)); - $result = $stmt->fetch(PDO::FETCH_ASSOC); + $stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` + WHERE `domainid`= :domainid"); + $result = Database::pexecute_first($stmt, array( + "domainid" => $id + )); $do_insert = false; // if no entry can be found, behave like we have empty values - if (!is_array($result) || !isset($result['ssl_cert_file'])) { + if (! is_array($result) || ! isset($result['ssl_cert_file'])) { $result = array( 'ssl_cert_file' => '', 'ssl_key_file' => '', @@ -894,14 +448,73 @@ if ($page == 'overview') { $do_insert = true; } - $result = htmlentities_array($result); + $result = \Froxlor\PhpHelper::htmlentitiesArray($result); - $ssleditor_data = include_once dirname(__FILE__).'/lib/formfields/customer/domains/formfield.domain_ssleditor.php'; - $ssleditor_form = htmlform::genHTMLForm($ssleditor_data); + $ssleditor_data = include_once dirname(__FILE__) . '/lib/formfields/customer/domains/formfield.domain_ssleditor.php'; + $ssleditor_form = \Froxlor\UI\HtmlForm::genHTMLForm($ssleditor_data); $title = $ssleditor_data['domain_ssleditor']['title']; $image = $ssleditor_data['domain_ssleditor']['image']; - eval("echo \"" . getTemplate("domains/domain_ssleditor") . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("domains/domain_ssleditor") . "\";"); + } +} elseif ($page == 'domaindnseditor' && $userinfo['dnsenabled'] == '1' && Settings::Get('system.dnsenabled') == '1') { + + require_once __DIR__ . '/dns_editor.php'; +} elseif ($page == 'sslcertificates') { + + require_once __DIR__ . '/ssl_certificates.php'; +} elseif ($page == 'logfiles') { + + require_once __DIR__ . '/logfiles_viewer.php'; +} + +function formatDomainEntry(&$row, &$idna_convert) +{ + $row['domain'] = $idna_convert->decode($row['domain']); + $row['aliasdomain'] = $idna_convert->decode($row['aliasdomain']); + $row['domainalias'] = $idna_convert->decode($row['domainalias']); + + /** + * check for set ssl-certs to show different state-icons + */ + // nothing (ssl_global) + $row['domain_hascert'] = 0; + $ssl_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` WHERE `domainid` = :domainid"); + Database::pexecute($ssl_stmt, array( + "domainid" => $row['id'] + )); + $ssl_result = $ssl_stmt->fetch(PDO::FETCH_ASSOC); + if (is_array($ssl_result) && isset($ssl_result['ssl_cert_file']) && $ssl_result['ssl_cert_file'] != '') { + // own certificate (ssl_customer_green) + $row['domain_hascert'] = 1; + } else { + // check if it's parent has one set (shared) + if ($row['parentdomainid'] != 0) { + $ssl_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` WHERE `domainid` = :domainid"); + Database::pexecute($ssl_stmt, array( + "domainid" => $row['parentdomainid'] + )); + $ssl_result = $ssl_stmt->fetch(PDO::FETCH_ASSOC); + if (is_array($ssl_result) && isset($ssl_result['ssl_cert_file']) && $ssl_result['ssl_cert_file'] != '') { + // parent has a certificate (ssl_shared) + $row['domain_hascert'] = 2; + } + } + } + + $row['termination_date'] = str_replace("0000-00-00", "", $row['termination_date']); + + $row['termination_css'] = ""; + if ($row['termination_date'] != "") { + $cdate = strtotime($row['termination_date'] . " 23:59:59"); + $today = time(); + + if ($cdate < $today) { + $row['termination_css'] = 'domain-expired'; + } else { + $row['termination_css'] = 'domain-canceled'; + } } } + diff --git a/customer_email.php b/customer_email.php index 2ace4ad5..33ba1b04 100644 --- a/customer_email.php +++ b/customer_email.php @@ -16,10 +16,20 @@ * @package Panel * */ - define('AREA', 'customer'); require './lib/init.php'; +use Froxlor\Database\Database; +use Froxlor\Settings; +use Froxlor\Api\Commands\Emails as Emails; +use Froxlor\Api\Commands\EmailAccounts as EmailAccounts; +use Froxlor\Api\Commands\EmailForwarders as EmailForwarders; + +// redirect if this customer page is hidden via settings +if (Settings::IsInList('panel.customer_hide_options', 'email')) { + \Froxlor\UI\Response::redirectTo('customer_index.php'); +} + if (isset($_POST['id'])) { $id = intval($_POST['id']); } elseif (isset($_GET['id'])) { @@ -27,46 +37,50 @@ if (isset($_POST['id'])) { } if ($page == 'overview') { - $log->logAction(USR_ACTION, LOG_NOTICE, "viewed customer_email"); - eval("echo \"" . getTemplate("email/email") . "\";"); + $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed customer_email"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("email/email") . "\";"); } elseif ($page == 'emails') { if ($action == '') { - $log->logAction(USR_ACTION, LOG_NOTICE, "viewed customer_email::emails"); + $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'] ); - $paging = new paging($userinfo, TABLE_MAIL_VIRTUAL, $fields); - $result_stmt = Database::prepare('SELECT `m`.`id`, `m`.`domainid`, `m`.`email`, `m`.`email_full`, `m`.`iscatchall`, `u`.`quota`, `m`.`destination`, `m`.`popaccountid`, `d`.`domain`, `u`.`mboxsize` FROM `' . TABLE_MAIL_VIRTUAL . '` `m` - LEFT JOIN `' . TABLE_PANEL_DOMAINS . '` `d` ON (`m`.`domainid` = `d`.`id`) - LEFT JOIN `' . TABLE_MAIL_USERS . '` `u` ON (`m`.`popaccountid` = `u`.`id`) - WHERE `m`.`customerid`= :customerid ' . $paging->getSqlWhere(true) . " " . $paging->getSqlOrderBy() . " " . $paging->getSqlLimit() - ); - Database::pexecute($result_stmt, array("customerid" => $userinfo['customerid'])); - $emailscount = Database::num_rows(); - $paging->setEntries($emailscount); + try { + // get total count + $json_result = Emails::getLocal($userinfo)->listingCount(); + $result = json_decode($json_result, true)['data']; + // initialize pagination and filtering + $paging = new \Froxlor\UI\Pagination($userinfo, $fields, $result); + // get list + $json_result = Emails::getLocal($userinfo, $paging->getApiCommandParams())->listing(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; + $sortcode = $paging->getHtmlSortCode($lng); $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); $searchcode = $paging->getHtmlSearchCode($lng); $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); $emails = array(); + $emailscount = $paging->getEntries(); - while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { - if (!isset($emails[$row['domain']]) || !is_array($emails[$row['domain']])) { + foreach ($result['list'] as $row) { + if (! isset($emails[$row['domain']]) || ! is_array($emails[$row['domain']])) { $emails[$row['domain']] = array(); } $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); } - $i = 0; $count = 0; $accounts = ''; $emails_count = 0; @@ -79,235 +93,145 @@ if ($page == 'overview') { } foreach ($emailaddresses as $row) { - if ($paging->checkDisplay($i)) { - if ($domainname != $idna_convert->decode($row['domain'])) { - $domainname = $idna_convert->decode($row['domain']); - eval("\$accounts.=\"" . getTemplate("email/emails_domain") . "\";"); - } - - $emails_count++; - $row['email'] = $idna_convert->decode($row['email']); - $row['email_full'] = $idna_convert->decode($row['email_full']); - $row['destination'] = explode(' ', $row['destination']); - uasort($row['destination'], 'strcasecmp'); - - while (list($dest_id, $destination) = each($row['destination'])) { - $row['destination'][$dest_id] = $idna_convert->decode($row['destination'][$dest_id]); - - if ($row['destination'][$dest_id] == $row['email_full']) { - unset($row['destination'][$dest_id]); - } - } - - $destinations_count = count($row['destination']); - $row['destination'] = implode(', ', $row['destination']); - - if (strlen($row['destination']) > 35) { - $row['destination'] = substr($row['destination'], 0, 32) . '... (' . $destinations_count . ')'; - } - - $row['mboxsize'] = size_readable($row['mboxsize'], 'GiB', 'bi', '%01.' . (int)Settings::Get('panel.decimal_places') . 'f %s'); - - $row = htmlentities_array($row); - eval("\$accounts.=\"" . getTemplate("email/emails_email") . "\";"); - $count++; + if ($domainname != $idna_convert->decode($row['domain'])) { + $domainname = $idna_convert->decode($row['domain']); + eval("\$accounts.=\"" . \Froxlor\UI\Template::getTemplate("email/emails_domain") . "\";"); } - $i++; + $emails_count ++; + $row['email'] = $idna_convert->decode($row['email']); + $row['email_full'] = $idna_convert->decode($row['email_full']); + $row['destination'] = explode(' ', $row['destination']); + uasort($row['destination'], 'strcasecmp'); + + $dest_list = $row['destination']; + foreach ($dest_list as $dest_id => $destination) { + $row['destination'][$dest_id] = $idna_convert->decode($row['destination'][$dest_id]); + + if ($row['destination'][$dest_id] == $row['email_full']) { + unset($row['destination'][$dest_id]); + } + } + + $destinations_count = count($row['destination']); + $row['destination'] = implode(', ', $row['destination']); + + if (strlen($row['destination']) > 35) { + $row['destination'] = substr($row['destination'], 0, 32) . '... (' . $destinations_count . ')'; + } + + $row['mboxsize'] = \Froxlor\PhpHelper::sizeReadable($row['mboxsize'], 'GiB', 'bi', '%01.' . (int) Settings::Get('panel.decimal_places') . 'f %s'); + + $row = \Froxlor\PhpHelper::htmlentitiesArray($row); + eval("\$accounts.=\"" . \Froxlor\UI\Template::getTemplate("email/emails_email") . "\";"); + $count ++; } } - $emaildomains_count_stmt = Database::prepare("SELECT COUNT(`id`) AS `count` FROM `" . TABLE_PANEL_DOMAINS . "` - WHERE `customerid`= :customerid - AND `isemaildomain`='1' ORDER BY `domain` ASC" - ); - Database::pexecute($emaildomains_count_stmt, array("customerid" => $userinfo['customerid'])); - $emaildomains_count = $emaildomains_count_stmt->fetch(PDO::FETCH_ASSOC); - $emaildomains_count = $emaildomains_count['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 \"" . getTemplate("email/emails") . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("email/emails") . "\";"); } elseif ($action == 'delete' && $id != 0) { - $stmt = Database::prepare("SELECT `id`, `email`, `email_full`, `iscatchall`, `destination`, `customerid`, `popaccountid` FROM `" . TABLE_MAIL_VIRTUAL . "` - WHERE `customerid`= :customerid - AND `id`= :id" - ); - $result = Database::pexecute_first($stmt, array("customerid" => $userinfo['customerid'], "id" => $id)); + try { + $json_result = Emails::getLocal($userinfo, array( + 'id' => $id + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; if (isset($result['email']) && $result['email'] != '') { if (isset($_POST['send']) && $_POST['send'] == 'send') { - $update_users_query_addon = ''; - - if ($result['destination'] != '') { - $result['destination'] = explode(' ', $result['destination']); - $number_forwarders = count($result['destination']); - - if ($result['popaccountid'] != 0) { - // Free the Quota used by the email account - if (Settings::Get('system.mail_quota_enabled') == 1) { - $stmt = Database::prepare("SELECT `quota` FROM `" . TABLE_MAIL_USERS . "` - WHERE `customerid`= :customerid - AND `id`= :id" - ); - $res_quota = Database::pexecute_first($stmt, array("customerid" => $userinfo['customerid'], "id" => $result['popaccountid'])); - $update_users_query_addon.= " , `email_quota_used` = `email_quota_used` - " . (int)$res_quota['quota'] . " "; - } - - $stmt = Database::prepare("DELETE FROM `" . TABLE_MAIL_USERS . "` - WHERE `customerid`= :customerid - AND `id`= :id" - ); - Database::pexecute($stmt, array("customerid" => $userinfo['customerid'], "id" => $result['popaccountid'])); - $update_users_query_addon .= " , `email_accounts_used` = `email_accounts_used` - 1 "; - $number_forwarders-= 1; - $log->logAction(USR_ACTION, LOG_NOTICE, "deleted forwarder for email address '" . $result['email'] . "'"); - } - } else { - $number_forwarders = 0; + try { + Emails::getLocal($userinfo, array( + 'id' => $id, + 'delete_userfiles' => ($_POST['delete_userfiles'] ?? 0) + ))->delete(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } - - if (isset($_POST['delete_userfiles']) - && (int)$_POST['delete_userfiles'] == 1 - ) { - inserttask('7', $userinfo['loginname'], $result['email_full']); - } - - $stmt = Database::prepare("DELETE FROM `" . TABLE_MAIL_VIRTUAL . "` - WHERE `customerid`= :customerid - AND `id`= :id" - ); - Database::pexecute($stmt, array("customerid" => $userinfo['customerid'], "id" => $id)); - - $stmt = Database::prepare("UPDATE `" . TABLE_PANEL_CUSTOMERS . "` - SET `emails_used`=`emails_used` - 1 , - `email_forwarders_used` = `email_forwarders_used` - :nforwarders - $update_users_query_addon - WHERE `customerid`= :customerid" - ); - Database::pexecute($stmt, array("nforwarders" => $number_forwarders, "customerid" => $userinfo['customerid'])); - - $log->logAction(USR_ACTION, LOG_INFO, "deleted email address '" . $result['email'] . "'"); - redirectTo($filename, array('page' => $page, 's' => $s)); + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); } else { if ($result['popaccountid'] != '0') { $show_checkbox = true; } else { $show_checkbox = false; } - ask_yesno_withcheckbox('email_reallydelete', 'admin_customer_alsoremovemail', $filename, array('id' => $id, 'page' => $page, 'action' => $action), $idna_convert->decode($result['email_full']), $show_checkbox); + \Froxlor\UI\HTML::askYesNoWithCheckbox('email_reallydelete', 'admin_customer_alsoremovemail', $filename, array( + 'id' => $id, + 'page' => $page, + 'action' => $action + ), $idna_convert->decode($result['email_full']), $show_checkbox); } } } elseif ($action == 'add') { if ($userinfo['emails_used'] < $userinfo['emails'] || $userinfo['emails'] == '-1') { if (isset($_POST['send']) && $_POST['send'] == 'send') { - $email_part = $_POST['email_part']; - $domain = $idna_convert->encode(validate($_POST['domain'], 'domain')); - $stmt = Database::prepare("SELECT `id`, `domain`, `customerid` FROM `" . TABLE_PANEL_DOMAINS . "` - WHERE `domain`= :domain - AND `customerid`= :customerid - AND `isemaildomain`='1' " - ); - $domain_check = Database::pexecute_first($stmt, array("domain" => $domain, "customerid" => $userinfo['customerid'])); - - if (isset($_POST['iscatchall']) && $_POST['iscatchall'] == '1') { - $iscatchall = '1'; - $email = '@' . $domain; - } else { - $iscatchall = '0'; - $email = $email_part . '@' . $domain; - } - - $email_full = $email_part . '@' . $domain; - - if (!validateEmail($email_full)) { - standard_error('emailiswrong', $email_full); - } - - $stmt = Database::prepare("SELECT `id`, `email`, `email_full`, `iscatchall`, `destination`, `customerid` FROM `" . TABLE_MAIL_VIRTUAL . "` - WHERE (`email` = :email - OR `email_full` = :emailfull ) - AND `customerid`= :cid" - ); - $params = array( - "email" => $email, - "emailfull" => $email_full, - "cid" => $userinfo['customerid'] - ); - $email_check = Database::pexecute_first($stmt, $params); - - if ($email == '' || $email_full == '' || $email_part == '') { - standard_error(array('stringisempty', 'emailadd')); - } elseif ($domain == '') { - standard_error('domaincantbeempty'); - } elseif ($domain_check['domain'] != $domain) { - standard_error('maindomainnonexist', $domain); - } elseif (strtolower($email_check['email_full']) == strtolower($email_full)) { - standard_error('emailexistalready', $email_full); - } elseif ($email_check['email'] == $email) { - standard_error('youhavealreadyacatchallforthisdomain'); - } else { - $stmt = Database::prepare("INSERT INTO `" . TABLE_MAIL_VIRTUAL . "` - (`customerid`, `email`, `email_full`, `iscatchall`, `domainid`) - VALUES (:cid, :email, :email_full, :iscatchall, :domainid)" - ); - $params = array( - "cid" => $userinfo['customerid'], - "email" => $email, - "email_full" => $email_full, - "iscatchall" => $iscatchall, - "domainid" => $domain_check['id'] - ); - Database::pexecute($stmt, $params); - - $address_id = Database::lastInsertId(); - $stmt = Database::prepare("UPDATE " . TABLE_PANEL_CUSTOMERS . " - SET `emails_used` = `emails_used` + 1 - WHERE `customerid`= :cid" - ); - Database::pexecute($stmt, array("cid" => $userinfo['customerid'])); - - $log->logAction(USR_ACTION, LOG_INFO, "added email address '" . $email_full . "'"); - redirectTo($filename, array('page' => $page, 'action' => 'edit', 'id' => $address_id, 's' => $s)); + try { + $json_result = Emails::getLocal($userinfo, $_POST)->add(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } + $result = json_decode($json_result, true)['data']; + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 'action' => 'edit', + 'id' => $result['id'], + 's' => $s + )); } else { $result_stmt = Database::prepare("SELECT `id`, `domain`, `customerid` FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `customerid`= :cid AND `isemaildomain`='1' - ORDER BY `domain` ASC" - ); - Database::pexecute($result_stmt, array("cid" => $userinfo['customerid'])); + ORDER BY `domain_ace` ASC"); + Database::pexecute($result_stmt, array( + "cid" => $userinfo['customerid'] + )); $domains = ''; while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { - $domains.= makeoption($idna_convert->decode($row['domain']), $row['domain']); + $domains .= \Froxlor\UI\HTML::makeoption($idna_convert->decode($row['domain']), $row['domain']); } - //$iscatchall = makeyesno('iscatchall', '1', '0', '0'); + // $iscatchall = \Froxlor\UI\HTML::makeyesno('iscatchall', '1', '0', '0'); - $email_add_data = include_once dirname(__FILE__).'/lib/formfields/customer/email/formfield.emails_add.php'; + $email_add_data = include_once dirname(__FILE__) . '/lib/formfields/customer/email/formfield.emails_add.php'; if (Settings::Get('catchall.catchall_enabled') != '1') { unset($email_add_data['emails_add']['sections']['section_a']['fields']['iscatchall']); } - $email_add_form = htmlform::genHTMLForm($email_add_data); + $email_add_form = \Froxlor\UI\HtmlForm::genHTMLForm($email_add_data); $title = $email_add_data['emails_add']['title']; $image = $email_add_data['emails_add']['image']; - eval("echo \"" . getTemplate("email/emails_add") . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("email/emails_add") . "\";"); } } else { - standard_error('allresourcesused'); + \Froxlor\UI\Response::standard_error('allresourcesused'); } } elseif ($action == 'edit' && $id != 0) { - $stmt = Database::prepare("SELECT `v`.`id`, `v`.`email`, `v`.`email_full`, `v`.`iscatchall`, `v`.`destination`, `v`.`customerid`, `v`.`popaccountid`, `u`.`quota` - FROM `" . TABLE_MAIL_VIRTUAL . "` `v` - LEFT JOIN `" . TABLE_MAIL_USERS . "` `u` - ON(`v`.`popaccountid` = `u`.`id`) - WHERE `v`.`customerid`= :cid - AND `v`.`id`= :id" - ); - $result = Database::pexecute_first($stmt, array("cid" => $userinfo['customerid'], "id" => $id)); + try { + $json_result = Emails::getLocal($userinfo, array( + 'id' => $id + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; if (isset($result['email']) && $result['email'] != '') { $result['email'] = $idna_convert->decode($result['email']); @@ -317,542 +241,262 @@ if ($page == 'overview') { $forwarders = ''; $forwarders_count = 0; - while (list($dest_id, $destination) = each($result['destination'])) { + foreach ($result['destination'] as $dest_id => $destination) { $destination = $idna_convert->decode($destination); if ($destination != $result['email_full'] && $destination != '') { - eval("\$forwarders.=\"" . getTemplate("email/emails_edit_forwarder") . "\";"); - $forwarders_count++; + eval("\$forwarders.=\"" . \Froxlor\UI\Template::getTemplate("email/emails_edit_forwarder") . "\";"); + $forwarders_count ++; } $result['destination'][$dest_id] = $destination; } $destinations_count = count($result['destination']); - $result = htmlentities_array($result); + $result = \Froxlor\PhpHelper::htmlentitiesArray($result); - $email_edit_data = include_once dirname(__FILE__).'/lib/formfields/customer/email/formfield.emails_edit.php'; + $email_edit_data = include_once dirname(__FILE__) . '/lib/formfields/customer/email/formfield.emails_edit.php'; if (Settings::Get('catchall.catchall_enabled') != '1') { unset($email_edit_data['emails_edit']['sections']['section_a']['fields']['mail_catchall']); } - $email_edit_form = htmlform::genHTMLForm($email_edit_data); + $email_edit_form = \Froxlor\UI\HtmlForm::genHTMLForm($email_edit_data); $title = $email_edit_data['emails_edit']['title']; $image = $email_edit_data['emails_edit']['image']; - eval("echo \"" . getTemplate("email/emails_edit") . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("email/emails_edit") . "\";"); } } elseif ($action == 'togglecatchall' && $id != 0) { - if (Settings::Get('catchall.catchall_enabled') == '1') { - $stmt = Database::prepare("SELECT `id`, `email`, `email_full`, `iscatchall`, `destination`, `customerid`, `popaccountid` FROM `" . TABLE_MAIL_VIRTUAL . "` - WHERE `customerid`= :cid - AND `id`= :id" - ); - $result = Database::pexecute_first($stmt, array("cid" => $userinfo['customerid'], "id" => $id)); - - if (isset($result['email']) && $result['email'] != '') { - if ($result['iscatchall'] == '1') { - $stmt = Database::prepare("UPDATE `" . TABLE_MAIL_VIRTUAL . "` - SET `email` = :email, `iscatchall` = '0' - WHERE `customerid`= :cid - AND `id`= :id" - ); - $params = array( - "email" => $result['email_full'], - "cid" => $userinfo['customerid'], - "id" => $id - ); - Database::pexecute($stmt, $params); - } else { - $email_parts = explode('@', $result['email_full']); - $email = '@' . $email_parts[1]; - $stmt = Database::prepare("SELECT `id`, `email`, `email_full`, `iscatchall`, `destination`, `customerid` FROM `" . TABLE_MAIL_VIRTUAL . "` - WHERE `email`= :email - AND `customerid`= :cid" - ); - $email_check = Database::pexecute_first($stmt, array("email" => $email, "cid" => $userinfo['customerid'])); - - if ($email_check['email'] == $email) { - standard_error('youhavealreadyacatchallforthisdomain'); - } else { - $stmt = Database::prepare("UPDATE `" . TABLE_MAIL_VIRTUAL . "` - SET `email` = :email , `iscatchall` = '1' - WHERE `customerid`= :cid - AND `id`= :id" - ); - $params = array( - "email" => $email, - "cid" => $userinfo['customerid'], - "id" => $id - ); - Database::pexecute($stmt, $params); - $log->logAction(USR_ACTION, LOG_INFO, "edited email address '" . $email . "'"); - } - } - - redirectTo($filename, array('page' => $page, 'action' => 'edit', 'id' => $id, 's' => $s)); - } - } else { - standard_error(array('operationnotpermitted', 'featureisdisabled'), 'Catchall'); + try { + $json_result = Emails::getLocal($userinfo, array( + 'id' => $id + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } + $result = json_decode($json_result, true)['data']; + + try { + Emails::getLocal($userinfo, array( + 'id' => $id, + 'iscatchall' => ($result['iscatchall'] == '1' ? 0 : 1) + ))->update(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 'action' => 'edit', + 'id' => $id, + 's' => $s + )); } } elseif ($page == 'accounts') { if ($action == 'add' && $id != 0) { - // ensure the int is a positive one - if (isset($_POST['email_quota'])) { - $quota = validate($_POST['email_quota'], 'email_quota', '/^\d+$/', 'vmailquotawrong'); - } - if ($userinfo['email_accounts'] == '-1' || ($userinfo['email_accounts_used'] < $userinfo['email_accounts'])) { - - // check for imap||pop3 == 1, see #1298 - if ($userinfo['imap'] != '1' && $userinfo['pop3'] != '1') { - standard_error('notallowedtouseaccounts'); + try { + $json_result = Emails::getLocal($userinfo, array( + 'id' => $id + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } + $result = json_decode($json_result, true)['data']; - $stmt = Database::prepare(" - SELECT `id`, `email`, `email_full`, `iscatchall`, `destination`, `customerid`, `popaccountid`, `domainid` - FROM `" . TABLE_MAIL_VIRTUAL . "` - WHERE `customerid`= :cid AND `id`= :id - "); - $result = Database::pexecute_first($stmt, array("cid" => $userinfo['customerid'], "id" => $id)); - - if (isset($result['email']) && $result['email'] != '' && $result['popaccountid'] == '0') { - if (isset($_POST['send']) && $_POST['send'] == 'send') { - $email_full = $result['email_full']; - $username = $idna_convert->decode($email_full); - $password = validate($_POST['email_password'], 'password'); - $password = validatePassword($password); - - if (Settings::Get('panel.sendalternativemail') == 1) { - $alternative_email = $idna_convert->encode(validate($_POST['alternative_email'], 'alternative_email')); - } else { - $alternative_email = ''; - } - - if (Settings::Get('system.mail_quota_enabled') == 1) { - if ($userinfo['email_quota'] != '-1' && ($quota == 0 || ($quota + $userinfo['email_quota_used']) > $userinfo['email_quota'])) { - standard_error('allocatetoomuchquota', $quota); - } - } else { - $quota = 0; - } - - if ($email_full == '') { - standard_error(array('stringisempty', 'emailadd')); - } - elseif ($password == '' && !(Settings::Get('panel.sendalternativemail') == 1 && validateEmail($alternative_email))) { - standard_error(array('stringisempty', 'mypassword')); - } - elseif ($password == $email_full) { - standard_error('passwordshouldnotbeusername'); - } else { - if ($password == '') { - $password = generatePassword(); - } - - $cryptPassword = makeCryptPassword($password); - - $email_user=substr($email_full,0,strrpos($email_full,"@")); - $email_domain=substr($email_full,strrpos($email_full,"@")+1); - $maildirname=trim(Settings::Get('system.vmail_maildirname')); - // Add trailing slash to Maildir if needed - $maildirpath=$maildirname; - if (!empty($maildirname) && substr($maildirname,-1) != "/") { - $maildirpath.="/"; - } - - $stmt = Database::prepare("INSERT INTO `" . TABLE_MAIL_USERS . "` - (`customerid`, `email`, `username`, " . (Settings::Get('system.mailpwcleartext') == '1' ? '`password`, ' : '') . " `password_enc`, `homedir`, `maildir`, `uid`, `gid`, `domainid`, `postfix`, `quota`, `imap`, `pop3`) ". - "VALUES (:cid, :email, :username, " . (Settings::Get('system.mailpwcleartext') == '1' ? ":password, " : '') . ":password_enc, :homedir, :maildir, :uid, :gid, :domainid, 'y', :quota, :imap, :pop3)" - ); - $params = array( - "cid" => $userinfo['customerid'], - "email" => $email_full, - "username" => $username, - "password_enc" => $cryptPassword, - "homedir" => Settings::Get('system.vmail_homedir'), - "maildir" => $userinfo['loginname'] . '/' . $email_domain . "/" . $email_user . "/" . $maildirpath, - "uid" => Settings::Get('system.vmail_uid'), - "gid" => Settings::Get('system.vmail_gid'), - "domainid" => $result['domainid'], - "quota" => $quota, - "imap" => $userinfo['imap'], - "pop3" => $userinfo['pop3'] - ); - if (Settings::Get('system.mailpwcleartext') == '1') { $params["password"] = $password; } - Database::pexecute($stmt, $params); - - $popaccountid = Database::lastInsertId(); - $result['destination'].= ' ' . $email_full; - $stmt = Database::prepare("UPDATE `" . TABLE_MAIL_VIRTUAL . "` - SET `destination` = :destination, - `popaccountid` = :popaccountid - WHERE `customerid`= :cid - AND `id`= :id" - ); - $params = array( - "destination" => makeCorrectDestination($result['destination']), - "popaccountid" => $popaccountid, - "cid" => $userinfo['customerid'], - "id" => $id - ); - Database::pexecute($stmt, $params); - - $stmt = Database::prepare("UPDATE `" . TABLE_PANEL_CUSTOMERS . "` - SET `email_accounts_used`=`email_accounts_used`+1, - `email_quota_used`=`email_quota_used`+ :quota - WHERE `customerid`= :cid" - ); - Database::pexecute($stmt, array("quota" => $quota, "cid" => $userinfo['customerid'])); - - $log->logAction(USR_ACTION, LOG_INFO, "added email account for '" . $email_full . "'"); - $replace_arr = array( - 'EMAIL' => $email_full, - 'USERNAME' => $username, - 'PASSWORD' => $password - ); - - $stmt = Database::prepare("SELECT `name`, `email` FROM `" . TABLE_PANEL_ADMINS . "` WHERE `adminid`= :adminid"); - $admin = Database::pexecute_first($stmt, array("adminid" => $userinfo['adminid'])); - - $stmt = Database::prepare("SELECT `value` FROM `" . TABLE_PANEL_TEMPLATES . "` - WHERE `adminid`= :adminid - AND `language`= :lang - AND `templategroup`= 'mails' - AND `varname`= 'pop_success_subject'" - ); - $result = Database::pexecute_first($stmt, array("adminid" => $userinfo['adminid'], "lang" => $userinfo['def_language'])); - $mail_subject = html_entity_decode(replace_variables((($result['value'] != '') ? $result['value'] : $lng['mails']['pop_success']['subject']), $replace_arr)); - - $stmt = Database::prepare("SELECT `value` FROM `" . TABLE_PANEL_TEMPLATES . "` - WHERE `adminid`= :adminid - AND `language`= :lang - AND `templategroup`= 'mails' - AND `varname`= 'pop_success_mailbody'" - ); - $result = Database::pexecute_first($stmt, array("adminid" => $userinfo['adminid'], "lang" => $userinfo['def_language'])); - $mail_body = html_entity_decode(replace_variables((($result['value'] != '') ? $result['value'] : $lng['mails']['pop_success']['mailbody']), $replace_arr)); - - $_mailerror = false; - try { - $mail->SetFrom($admin['email'], getCorrectUserSalutation($admin)); - $mail->Subject = $mail_subject; - $mail->AltBody = $mail_body; - $mail->MsgHTML(str_replace("\n", "
", $mail_body)); - $mail->AddAddress($email_full); - $mail->Send(); - } catch(phpmailerException $e) { - $mailerr_msg = $e->errorMessage(); - $_mailerror = true; - } catch (Exception $e) { - $mailerr_msg = $e->getMessage(); - $_mailerror = true; - } - - if ($_mailerror) { - $log->logAction(USR_ACTION, LOG_ERR, "Error sending mail: " . $mailerr_msg); - standard_error('errorsendingmail', $email_full); - } - - $mail->ClearAddresses(); - - if (validateEmail($alternative_email) && Settings::Get('panel.sendalternativemail') == 1) { - $stmt = Database::prepare("SELECT `value` FROM `" . TABLE_PANEL_TEMPLATES . "` - WHERE `adminid`= :adminid - AND `language`= :lang - AND `templategroup`= 'mails' - AND `varname`= 'pop_success_alternative_subject'" - ); - $result = Database::pexecute_first($stmt, array("adminid" => $userinfo['adminid'], "lang" => $userinfo['def_language'])); - $mail_subject = replace_variables((($result['value'] != '') ? $result['value'] : $lng['mails']['pop_success_alternative']['subject']), $replace_arr); - - $stmt = Database::prepare("SELECT `value` FROM `" . TABLE_PANEL_TEMPLATES . "` - WHERE `adminid`= :adminid - AND `language`= :lang - AND `templategroup`= 'mails' - AND `varname`= 'pop_success_alternative_mailbody'" - ); - $result = Database::pexecute_first($stmt, array("adminid" => $userinfo['adminid'], "lang" => $userinfo['def_language'])); - $mail_body = replace_variables((($result['value'] != '') ? $result['value'] : $lng['mails']['pop_success_alternative']['mailbody']), $replace_arr); - - $_mailerror = false; - try { - $mail->SetFrom($admin['email'], getCorrectUserSalutation($admin)); - $mail->Subject = $mail_subject; - $mail->AltBody = $mail_body; - $mail->MsgHTML(str_replace("\n", "
", $mail_body)); - $mail->AddAddress($idna_convert->encode($alternative_email), getCorrectUserSalutation($userinfo)); - $mail->Send(); - } catch(phpmailerException $e) { - $mailerr_msg = $e->errorMessage(); - $_mailerror = true; - } catch (Exception $e) { - $mailerr_msg = $e->getMessage(); - $_mailerror = true; - } - - if ($_mailerror) { - $log->logAction(USR_ACTION, LOG_ERR, "Error sending mail: " . $mailerr_msg); - standard_error(array('errorsendingmail'), $alternative_email); - } - - $mail->ClearAddresses(); - } - - redirectTo($filename, array('page' => 'emails', 'action' => 'edit', 'id' => $id, 's' => $s)); - } - } else { - - if (checkMailAccDeletionState($result['email_full'])) { - standard_error(array('mailaccistobedeleted'), $result['email_full']); - } - - $result['email_full'] = $idna_convert->decode($result['email_full']); - $result = htmlentities_array($result); - $quota = Settings::Get('system.mail_quota'); - - $account_add_data = include_once dirname(__FILE__) . '/lib/formfields/customer/email/formfield.emails_addaccount.php'; - $account_add_form = htmlform::genHTMLForm($account_add_data); - - $title = $account_add_data['emails_addaccount']['title']; - $image = $account_add_data['emails_addaccount']['image']; - - eval("echo \"" . getTemplate("email/account_add") . "\";"); + if (isset($_POST['send']) && $_POST['send'] == 'send') { + try { + EmailAccounts::getLocal($userinfo, $_POST)->add(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => 'emails', + 'action' => 'edit', + 'id' => $id, + 's' => $s + )); + } else { + + if (\Froxlor\Validate\Check::checkMailAccDeletionState($result['email_full'])) { + \Froxlor\UI\Response::standard_error(array( + 'mailaccistobedeleted' + ), $result['email_full']); + } + + $result['email_full'] = $idna_convert->decode($result['email_full']); + $result = \Froxlor\PhpHelper::htmlentitiesArray($result); + $quota = Settings::Get('system.mail_quota'); + + $account_add_data = include_once dirname(__FILE__) . '/lib/formfields/customer/email/formfield.emails_addaccount.php'; + $account_add_form = \Froxlor\UI\HtmlForm::genHTMLForm($account_add_data); + + $title = $account_add_data['emails_addaccount']['title']; + $image = $account_add_data['emails_addaccount']['image']; + + eval("echo \"" . \Froxlor\UI\Template::getTemplate("email/account_add") . "\";"); } } else { - standard_error(array('allresourcesused', 'allocatetoomuchquota'), $quota); + \Froxlor\UI\Response::standard_error(array( + 'allresourcesused', + 'allocatetoomuchquota' + ), $quota); } } elseif ($action == 'changepw' && $id != 0) { - $stmt = Database::prepare("SELECT `id`, `email`, `email_full`, `iscatchall`, `destination`, `customerid`, `popaccountid` FROM `" . TABLE_MAIL_VIRTUAL . "` - WHERE `customerid`= :cid - AND `id`= :id" - ); - $result = Database::pexecute_first($stmt, array("cid" => $userinfo['customerid'], "id" => $id)); + try { + $json_result = Emails::getLocal($userinfo, array( + 'id' => $id + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; if (isset($result['popaccountid']) && $result['popaccountid'] != '') { if (isset($_POST['send']) && $_POST['send'] == 'send') { - $password = validate($_POST['email_password'], 'password'); - - if ($password == '') { - standard_error(array('stringisempty', 'mypassword')); + try { + EmailAccounts::getLocal($userinfo, $_POST)->update(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } - elseif ($password == $result['email_full']) { - standard_error('passwordshouldnotbeusername'); - } - - $password = validatePassword($password); - - $log->logAction(USR_ACTION, LOG_NOTICE, "changed email password for '" . $result['email_full'] . "'"); - $cryptPassword = makeCryptPassword($password); - $stmt = Database::prepare("UPDATE `" . TABLE_MAIL_USERS . "` - SET " . (Settings::Get('system.mailpwcleartext') == '1' ? "`password` = :password, " : '') . " - `password_enc`= :password_enc - WHERE `customerid`= :cid - AND `id`= :id" - ); - $params = array( - "password_enc" => $cryptPassword, - "cid" => $userinfo['customerid'], - "id" => $result['popaccountid'] - ); - if (Settings::Get('system.mailpwcleartext') == '1') { $params["password"] = $password; } - Database::pexecute($stmt, $params); - - redirectTo($filename, array('page' => 'emails', 'action' => 'edit', 'id' => $id, 's' => $s)); + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => 'emails', + 'action' => 'edit', + 'id' => $id, + 's' => $s + )); } else { $result['email_full'] = $idna_convert->decode($result['email_full']); - $result = htmlentities_array($result); + $result = \Froxlor\PhpHelper::htmlentitiesArray($result); - $account_changepw_data = include_once dirname(__FILE__).'/lib/formfields/customer/email/formfield.emails_accountchangepasswd.php'; - $account_changepw_form = htmlform::genHTMLForm($account_changepw_data); + $account_changepw_data = include_once dirname(__FILE__) . '/lib/formfields/customer/email/formfield.emails_accountchangepasswd.php'; + $account_changepw_form = \Froxlor\UI\HtmlForm::genHTMLForm($account_changepw_data); $title = $account_changepw_data['emails_accountchangepasswd']['title']; $image = $account_changepw_data['emails_accountchangepasswd']['image']; - eval("echo \"" . getTemplate("email/account_changepw") . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("email/account_changepw") . "\";"); } } } elseif ($action == 'changequota' && Settings::Get('system.mail_quota_enabled') == '1' && $id != 0) { - $stmt = Database::prepare("SELECT `v`.`id`, `v`.`email`, `v`.`email_full`, `v`.`iscatchall`, `v`.`destination`, `v`.`customerid`, `v`.`popaccountid`, `u`.`quota` - FROM `" . TABLE_MAIL_VIRTUAL . "` `v` - LEFT JOIN `" . TABLE_MAIL_USERS . "` `u` - ON(`v`.`popaccountid` = `u`.`id`) - WHERE `v`.`customerid`= :cid - AND `v`.`id`= :id" - ); - $result = Database::pexecute_first($stmt, array("cid" => $userinfo['customerid'], "id" => $id)); + try { + $json_result = Emails::getLocal($userinfo, array( + 'id' => $id + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; if (isset($result['popaccountid']) && $result['popaccountid'] != '') { if (isset($_POST['send']) && $_POST['send'] == 'send') { - $quota = (int)validate($_POST['email_quota'], 'email_quota', '/^\d+$/', 'vmailquotawrong'); - - if ($userinfo['email_quota'] != '-1' && ($quota == 0 || ($quota + $userinfo['email_quota_used'] - $result['quota']) > $userinfo['email_quota'])) { - standard_error('allocatetoomuchquota', $quota); - } else { - $log->logAction(USR_ACTION, LOG_NOTICE, "updated quota for email address '" . $result['email'] . "' to " . $quota . " MB"); - $stmt = Database::prepare("UPDATE `" . TABLE_MAIL_USERS . "` - SET `quota` = :quota - WHERE `id` = :id - AND `customerid`= :cid" - ); - $params = array( - "quota" => $quota, - "id" => $result['popaccountid'], - "cid" => $userinfo['customerid'] - ); - Database::pexecute($stmt, $params); - - if ($userinfo['email_quota'] != '-1') { - $new_used_quota = $userinfo['email_quota_used'] + ($quota - $result['quota']); - $stmt = Database::prepare("UPDATE `" . TABLE_PANEL_CUSTOMERS . "` - SET `email_quota_used` = :used - WHERE `customerid` = :cid" - ); - Database::pexecute($stmt, array("used" => $new_used_quota, "cid" => $userinfo['customerid'])); - } - - redirectTo($filename, array('page' => 'emails', 'action' => 'edit', 'id' => $id, 's' => $s)); + try { + EmailAccounts::getLocal($userinfo, $_POST)->update(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => 'emails', + 'action' => 'edit', + 'id' => $id, + 's' => $s + )); } else { $result['email_full'] = $idna_convert->decode($result['email_full']); - $result = htmlentities_array($result); + $result = \Froxlor\PhpHelper::htmlentitiesArray($result); - $quota_edit_data = include_once dirname(__FILE__).'/lib/formfields/customer/email/formfield.emails_accountchangequota.php'; - $quota_edit_form = htmlform::genHTMLForm($quota_edit_data); + $quota_edit_data = include_once dirname(__FILE__) . '/lib/formfields/customer/email/formfield.emails_accountchangequota.php'; + $quota_edit_form = \Froxlor\UI\HtmlForm::genHTMLForm($quota_edit_data); $title = $quota_edit_data['emails_accountchangequota']['title']; $image = $quota_edit_data['emails_accountchangequota']['image']; - eval("echo \"" . getTemplate("email/account_changequota") . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("email/account_changequota") . "\";"); } } } elseif ($action == 'delete' && $id != 0) { - $stmt = Database::prepare("SELECT `v`.`id`, `v`.`email`, `v`.`email_full`, `v`.`iscatchall`, `v`.`destination`, `v`.`customerid`, `v`.`popaccountid`, `u`.`quota` - FROM `" . TABLE_MAIL_VIRTUAL . "` `v` - LEFT JOIN `" . TABLE_MAIL_USERS . "` `u` - ON(`v`.`popaccountid` = `u`.`id`) - WHERE `v`.`customerid`='" . (int)$userinfo['customerid'] . "' - AND `v`.`id`='" . (int)$id . "'" - ); - $result = Database::pexecute_first($stmt, array("cid" => $userinfo['customerid'], "id" => $id)); + try { + $json_result = Emails::getLocal($userinfo, array( + 'id' => $id + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; if (isset($result['popaccountid']) && $result['popaccountid'] != '') { if (isset($_POST['send']) && $_POST['send'] == 'send') { - $stmt = Database::prepare("DELETE FROM `" . TABLE_MAIL_USERS . "` - WHERE `customerid`= :cid - AND `id`= :id" - ); - Database::pexecute($stmt, array("cid" => $userinfo['customerid'], "id" => $result['popaccountid'])); - $result['destination'] = str_replace($result['email_full'], '', $result['destination']); - - $stmt = Database::prepare("UPDATE `" . TABLE_MAIL_VIRTUAL . "` - SET `destination` = :dest, - `popaccountid` = '0' - WHERE `customerid`= :cid - AND `id`= :id" - ); - $params = array( - "dest" => makeCorrectDestination($result['destination']), - "cid" => $userinfo['customerid'], - "id" => $id - ); - Database::pexecute($stmt, $params); - - if (Settings::Get('system.mail_quota_enabled') == '1' && $userinfo['email_quota'] != '-1') { - $quota = (int)$result['quota']; - } else { - $quota = 0; + try { + EmailAccounts::getLocal($userinfo, $_POST)->delete(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } - - if (isset($_POST['delete_userfiles']) && (int)$_POST['delete_userfiles'] == 1) { - inserttask('7', $userinfo['loginname'], $result['email_full']); - } - - $stmt = Database::prepare("UPDATE `" . TABLE_PANEL_CUSTOMERS . "` - SET `email_accounts_used` = `email_accounts_used` - 1, - `email_quota_used` = `email_quota_used` - :quota - WHERE `customerid`= :cid" - ); - Database::pexecute($stmt, array("quota" => $quota, "cid" => $userinfo['customerid'])); - - $log->logAction(USR_ACTION, LOG_INFO, "deleted email account for '" . $result['email_full'] . "'"); - redirectTo($filename, array('page' => 'emails', 'action' => 'edit', 'id' => $id, 's' => $s)); + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => 'emails', + 'action' => 'edit', + 'id' => $id, + 's' => $s + )); } else { - ask_yesno_withcheckbox('email_reallydelete_account', 'admin_customer_alsoremovemail', $filename, array('id' => $id, 'page' => $page, 'action' => $action), $idna_convert->decode($result['email_full'])); + \Froxlor\UI\HTML::askYesNoWithCheckbox('email_reallydelete_account', 'admin_customer_alsoremovemail', $filename, array( + 'id' => $id, + 'page' => $page, + 'action' => $action + ), $idna_convert->decode($result['email_full'])); } } } } elseif ($page == 'forwarders') { if ($action == 'add' && $id != 0) { if ($userinfo['email_forwarders_used'] < $userinfo['email_forwarders'] || $userinfo['email_forwarders'] == '-1') { - $stmt = Database::prepare("SELECT `id`, `email`, `email_full`, `iscatchall`, `destination`, `customerid`, `popaccountid`, `domainid` FROM `" . TABLE_MAIL_VIRTUAL . "` - WHERE `customerid`= :cid - AND `id`= :id" - ); - $result = Database::pexecute_first($stmt, array("cid" => $userinfo['customerid'], "id" => $id)); + try { + $json_result = Emails::getLocal($userinfo, array( + 'id' => $id + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; if (isset($result['email']) && $result['email'] != '') { if (isset($_POST['send']) && $_POST['send'] == 'send') { - $destination = $idna_convert->encode($_POST['destination']); - $result['destination_array'] = explode(' ', $result['destination']); - - if ($destination == '') { - standard_error('destinationnonexist'); - } elseif (!validateEmail($destination)) { - standard_error('destinationiswrong', $destination); - } elseif ($destination == $result['email']) { - standard_error('destinationalreadyexistasmail', $destination); - } elseif (in_array($destination, $result['destination_array'])) { - standard_error('destinationalreadyexist', $destination); - } else { - $result['destination'].= ' ' . $destination; - $stmt = Database::prepare("UPDATE `" . TABLE_MAIL_VIRTUAL . "` - SET `destination` = :dest - WHERE `customerid`= :cid - AND `id`= :id" - ); - $params = array( - "dest" => makeCorrectDestination($result['destination']), - "cid" => $userinfo['customerid'], - "id" => $id - ); - Database::pexecute($stmt, $params); - - $stmt = Database::prepare("UPDATE `" . TABLE_PANEL_CUSTOMERS . "` - SET `email_forwarders_used` = `email_forwarders_used` + 1 - WHERE `customerid`= :cid" - ); - Database::pexecute($stmt, array("cid" => $userinfo['customerid'])); - - $log->logAction(USR_ACTION, LOG_NOTICE, "added email forwarder for '" . $result['email_full'] . "'"); - redirectTo($filename, array('page' => 'emails', 'action' => 'edit', 'id' => $id, 's' => $s)); + try { + EmailForwarders::getLocal($userinfo, $_POST)->add(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => 'emails', + 'action' => 'edit', + 'id' => $id, + 's' => $s + )); } else { $result['email_full'] = $idna_convert->decode($result['email_full']); - $result = htmlentities_array($result); + $result = \Froxlor\PhpHelper::htmlentitiesArray($result); - $forwarder_add_data = include_once dirname(__FILE__).'/lib/formfields/customer/email/formfield.emails_addforwarder.php'; - $forwarder_add_form = htmlform::genHTMLForm($forwarder_add_data); + $forwarder_add_data = include_once dirname(__FILE__) . '/lib/formfields/customer/email/formfield.emails_addforwarder.php'; + $forwarder_add_form = \Froxlor\UI\HtmlForm::genHTMLForm($forwarder_add_data); $title = $forwarder_add_data['emails_addforwarder']['title']; $image = $forwarder_add_data['emails_addforwarder']['image']; - eval("echo \"" . getTemplate("email/forwarder_add") . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("email/forwarder_add") . "\";"); } } } else { - standard_error('allresourcesused'); + \Froxlor\UI\Response::standard_error('allresourcesused'); } } elseif ($action == 'delete' && $id != 0) { - $stmt = Database::prepare("SELECT `id`, `email`, `email_full`, `iscatchall`, `destination`, `customerid`, `popaccountid` FROM `" . TABLE_MAIL_VIRTUAL . "` - WHERE `customerid`='" . (int)$userinfo['customerid'] . "' - AND `id`='" . (int)$id . "'" - ); - $result = Database::pexecute_first($stmt, array("cid" => $userinfo['customerid'])); + try { + $json_result = Emails::getLocal($userinfo, array( + 'id' => $id + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; if (isset($result['destination']) && $result['destination'] != '') { if (isset($_POST['forwarderid'])) { @@ -869,30 +513,24 @@ if ($page == 'overview') { $forwarder = $result['destination'][$forwarderid]; if (isset($_POST['send']) && $_POST['send'] == 'send') { - unset($result['destination'][$forwarderid]); - $result['destination'] = implode(' ', $result['destination']); - $stmt = Database::prepare("UPDATE `" . TABLE_MAIL_VIRTUAL . "` - SET `destination` = :dest - WHERE `customerid`= :cid - AND `id`= :id" - ); - $params = array( - "dest" => makeCorrectDestination($result['destination']), - "cid" => $userinfo['customerid'], - "id" => $id - ); - Database::pexecute($stmt, $params); - - $stmt = Database::prepare("UPDATE `" . TABLE_PANEL_CUSTOMERS . "` - SET `email_forwarders_used` = `email_forwarders_used` - 1 - WHERE `customerid`= :cid" - ); - Database::pexecute($stmt, array("cid" => $userinfo['customerid'])); - - $log->logAction(USR_ACTION, LOG_NOTICE, "deleted email forwarder for '" . $result['email_full'] . "'"); - redirectTo($filename, array('page' => 'emails', 'action' => 'edit', 'id' => $id, 's' => $s)); + try { + EmailForwarders::getLocal($userinfo, $_POST)->delete(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => 'emails', + 'action' => 'edit', + 'id' => $id, + 's' => $s + )); } else { - ask_yesno('email_reallydelete_forwarder', $filename, array('id' => $id, 'forwarderid' => $forwarderid, 'page' => $page, 'action' => $action), $idna_convert->decode($result['email_full']) . ' -> ' . $idna_convert->decode($forwarder)); + \Froxlor\UI\HTML::askYesNo('email_reallydelete_forwarder', $filename, array( + 'id' => $id, + 'forwarderid' => $forwarderid, + 'page' => $page, + 'action' => $action + ), $idna_convert->decode($result['email_full']) . ' -> ' . $idna_convert->decode($forwarder)); } } } diff --git a/customer_extras.php b/customer_extras.php index 9d85f1f9..87db5b3d 100644 --- a/customer_extras.php +++ b/customer_extras.php @@ -16,10 +16,19 @@ * @package Panel * */ - define('AREA', 'customer'); require './lib/init.php'; +use Froxlor\Settings; +use Froxlor\Api\Commands\DirOptions as DirOptions; +use Froxlor\Api\Commands\DirProtections as DirProtections; +use Froxlor\Api\Commands\CustomerBackups as CustomerBackups; + +// redirect if this customer page is hidden via settings +if (Settings::IsInList('panel.customer_hide_options', 'extras')) { + \Froxlor\UI\Response::redirectTo('customer_index.php'); +} + if (isset($_POST['id'])) { $id = intval($_POST['id']); } elseif (isset($_GET['id'])) { @@ -27,221 +36,154 @@ if (isset($_POST['id'])) { } if ($page == 'overview') { - $log->logAction(USR_ACTION, LOG_NOTICE, "viewed customer_extras"); - eval("echo \"" . getTemplate("extras/extras") . "\";"); + $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed customer_extras"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("extras/extras") . "\";"); } elseif ($page == 'htpasswds') { + + // redirect if this customer sub-page is hidden via settings + if (Settings::IsInList('panel.customer_hide_options', 'extras.directoryprotection')) { + \Froxlor\UI\Response::redirectTo('customer_index.php'); + } + if ($action == '') { - $log->logAction(USR_ACTION, LOG_NOTICE, "viewed customer_extras::htpasswds"); + $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed customer_extras::htpasswds"); $fields = array( 'username' => $lng['login']['username'], 'path' => $lng['panel']['path'] ); - $paging = new paging($userinfo, TABLE_PANEL_HTPASSWDS, $fields); - $result_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_HTPASSWDS . "` - WHERE `customerid`= :customerid " . $paging->getSqlWhere(true) . " " . $paging->getSqlOrderBy() . " " . $paging->getSqlLimit() - ); - Database::pexecute($result_stmt, array("customerid" => $userinfo['customerid'])); - $paging->setEntries(Database::num_rows()); + try { + // get total count + $json_result = DirProtections::getLocal($userinfo)->listingCount(); + $result = json_decode($json_result, true)['data']; + // initialize pagination and filtering + $paging = new \Froxlor\UI\Pagination($userinfo, $fields, $result); + // get list + $json_result = DirProtections::getLocal($userinfo, $paging->getApiCommandParams())->listing(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; + $sortcode = $paging->getHtmlSortCode($lng); $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); $searchcode = $paging->getHtmlSearchCode($lng); $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); - $i = 0; $count = 0; $htpasswds = ''; - while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { - if ($paging->checkDisplay($i)) { - if (strpos($row['path'], $userinfo['documentroot']) === 0) { - $row['path'] = str_replace($userinfo['documentroot'], "/", $row['path']); - } - - $row = htmlentities_array($row); - eval("\$htpasswds.=\"" . getTemplate("extras/htpasswds_htpasswd") . "\";"); - $count++; + foreach ($result['list'] as $row) { + if (strpos($row['path'], $userinfo['documentroot']) === 0) { + $row['path'] = str_replace($userinfo['documentroot'], "/", $row['path']); } - - $i++; + $row['path'] = \Froxlor\FileDir::makeCorrectDir($row['path']); + $row = \Froxlor\PhpHelper::htmlentitiesArray($row); + eval("\$htpasswds.=\"" . \Froxlor\UI\Template::getTemplate("extras/htpasswds_htpasswd") . "\";"); + $count ++; } - eval("echo \"" . getTemplate("extras/htpasswds") . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("extras/htpasswds") . "\";"); } elseif ($action == 'delete' && $id != 0) { - $result_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_HTPASSWDS . "` - WHERE `customerid`= :customerid - AND `id`= :id" - ); - Database::pexecute($result_stmt, array("customerid" => $userinfo['customerid'], "id" => $id)); - $result = $result_stmt->fetch(PDO::FETCH_ASSOC); + try { + $json_result = DirProtections::getLocal($userinfo, array( + 'id' => $id + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; if (isset($result['username']) && $result['username'] != '') { if (isset($_POST['send']) && $_POST['send'] == 'send') { - $stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_HTPASSWDS . "` - WHERE `customerid`= :customerid - AND `id`= :id" - ); - Database::pexecute($stmt, array("customerid" => $userinfo['customerid'], "id" => $id)); - - $log->logAction(USR_ACTION, LOG_INFO, "deleted htpasswd for '" . $result['username'] . " (" . $result['path'] . ")'"); - inserttask('1'); - redirectTo($filename, array('page' => $page, 's' => $s)); - } else { - if (strpos($result['path'], $userinfo['documentroot']) === 0) { - $result['path'] = str_replace($userinfo['documentroot'], "/", $result['path']); - } - - ask_yesno('extras_reallydelete', $filename, array('id' => $id, 'page' => $page, 'action' => $action), $result['username'] . ' (' . $result['path'] . ')'); - } - } - } elseif ($action == 'add') { - if (isset($_POST['send']) && $_POST['send'] == 'send') { - $path = makeCorrectDir(validate($_POST['path'], 'path')); - $userpath = $path; - $path = makeCorrectDir($userinfo['documentroot'] . '/' . $path); - $username = validate($_POST['username'], 'username', '/^[a-zA-Z0-9][a-zA-Z0-9\-_]+\$?$/'); - $authname = validate($_POST['directory_authname'], 'directory_authname', '/^[a-zA-Z0-9][a-zA-Z0-9\-_ ]+\$?$/'); - validate($_POST['directory_password'], 'password'); - - $username_path_check_stmt = Database::prepare("SELECT `id`, `username`, `path` FROM `" . TABLE_PANEL_HTPASSWDS . "` - WHERE `username`= :username - AND `path`= :path - AND `customerid`= :customerid" - ); - $params = array( - "username" => $username, - "path" => $path, - "customerid" => $userinfo['customerid'] - ); - Database::pexecute($username_path_check_stmt, $params); - $username_path_check = $username_path_check_stmt->fetch(PDO::FETCH_ASSOC); - - if (CRYPT_STD_DES == 1) { - $saltfordescrypt = substr(md5(uniqid(microtime(), 1)), 4, 2); - $password = crypt($_POST['directory_password'], $saltfordescrypt); - } else { - $password = crypt($_POST['directory_password']); - } - - if (!$_POST['path']) { - standard_error('invalidpath'); - } - - if ($username == '') { - standard_error(array('stringisempty', 'myloginname')); - } elseif ($username_path_check['username'] == $username && $username_path_check['path'] == $path) { - standard_error('userpathcombinationdupe'); - } elseif ($_POST['directory_password'] == '') { - standard_error(array('stringisempty', 'mypassword')); - } elseif ($path == '') { - standard_error('patherror'); - } elseif ($_POST['directory_password'] == $username) { - standard_error('passwordshouldnotbeusername'); - } else { - $stmt = Database::prepare("INSERT INTO `" . TABLE_PANEL_HTPASSWDS . "` SET - `customerid` = :customerid, - `username` = :username, - `password` = :password, - `path` = :path, - `authname` = :authname" - ); - $params = array( - "customerid" => $userinfo['customerid'], - "username" => $username, - "password" => $password, - "path" => $path, - "authname" => $authname - ); - Database::pexecute($stmt, $params); - $log->logAction(USR_ACTION, LOG_INFO, "added htpasswd for '" . $username . " (" . $path . ")'"); - inserttask('1'); - redirectTo($filename, array('page' => $page, 's' => $s)); - } - } else { - $pathSelect = makePathfield($userinfo['documentroot'], $userinfo['guid'], $userinfo['guid']); - - $htpasswd_add_data = include_once dirname(__FILE__).'/lib/formfields/customer/extras/formfield.htpasswd_add.php'; - $htpasswd_add_form = htmlform::genHTMLForm($htpasswd_add_data); - - $title = $htpasswd_add_data['htpasswd_add']['title']; - $image = $htpasswd_add_data['htpasswd_add']['image']; - - eval("echo \"" . getTemplate("extras/htpasswds_add") . "\";"); - } - } elseif ($action == 'edit' && $id != 0) { - $result_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_HTPASSWDS . "` - WHERE `customerid`= :customerid - AND `id`= :id" - ); - Database::pexecute($result_stmt, array("customerid" => $userinfo['customerid'], "id" => $id)); - $result = $result_stmt->fetch(PDO::FETCH_ASSOC); - - if (isset($result['username']) && $result['username'] != '') { - if (isset($_POST['send']) && $_POST['send'] == 'send') { - validate($_POST['directory_password'], 'password'); - $authname = validate($_POST['directory_authname'], 'directory_authname', '/^[a-zA-Z0-9][a-zA-Z0-9\-_ ]+\$?$/'); - - if (CRYPT_STD_DES == 1) { - $saltfordescrypt = substr(md5(uniqid(microtime(), 1)), 4, 2); - $password = crypt($_POST['directory_password'], $saltfordescrypt); - } else { - $password = crypt($_POST['directory_password']); - } - - if ($_POST['directory_password'] == $result['username']) { - standard_error('passwordshouldnotbeusername'); - } - - $params = array( - "customerid" => $userinfo['customerid'], - "id" => $id - ); - - $pwd_sql = ''; - if ($_POST['directory_password'] != '') { - $pwd_sql = "`password`= :password "; - $params["password"] = $password; - } - - $auth_sql = ''; - if ($authname != $result['authname']) { - $auth_sql = "`authname`= :authname "; - $params["authname"] = $authname; - } - - if ($pwd_sql != '' || $auth_sql != '') { - if ($pwd_sql !='' && $auth_sql != '') { - $pwd_sql.= ', '; - } - - $stmt = Database::prepare("UPDATE `" . TABLE_PANEL_HTPASSWDS . "` - SET ".$pwd_sql.$auth_sql." - WHERE `customerid`= :customerid - AND `id`= :id" - ); - Database::pexecute($stmt, $params); - $log->logAction(USR_ACTION, LOG_INFO, "edited htpasswd for '" . $result['username'] . " (" . $result['path'] . ")'"); - inserttask('1'); - redirectTo($filename, array('page' => $page, 's' => $s)); + try { + DirProtections::getLocal($userinfo, $_POST)->delete(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); } else { if (strpos($result['path'], $userinfo['documentroot']) === 0) { $result['path'] = str_replace($userinfo['documentroot'], "/", $result['path']); } - $result = htmlentities_array($result); + \Froxlor\UI\HTML::askYesNo('extras_reallydelete', $filename, array( + 'id' => $id, + 'page' => $page, + 'action' => $action + ), $result['username'] . ' (' . $result['path'] . ')'); + } + } + } elseif ($action == 'add') { + if (isset($_POST['send']) && $_POST['send'] == 'send') { + try { + DirProtections::getLocal($userinfo, $_POST)->add(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); + } else { + $pathSelect = \Froxlor\FileDir::makePathfield($userinfo['documentroot'], $userinfo['guid'], $userinfo['guid']); - $htpasswd_edit_data = include_once dirname(__FILE__).'/lib/formfields/customer/extras/formfield.htpasswd_edit.php'; - $htpasswd_edit_form = htmlform::genHTMLForm($htpasswd_edit_data); + $htpasswd_add_data = include_once dirname(__FILE__) . '/lib/formfields/customer/extras/formfield.htpasswd_add.php'; + $htpasswd_add_form = \Froxlor\UI\HtmlForm::genHTMLForm($htpasswd_add_data); + + $title = $htpasswd_add_data['htpasswd_add']['title']; + $image = $htpasswd_add_data['htpasswd_add']['image']; + + eval("echo \"" . \Froxlor\UI\Template::getTemplate("extras/htpasswds_add") . "\";"); + } + } elseif ($action == 'edit' && $id != 0) { + try { + $json_result = DirProtections::getLocal($userinfo, array( + 'id' => $id + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; + + if (isset($result['username']) && $result['username'] != '') { + if (isset($_POST['send']) && $_POST['send'] == 'send') { + try { + DirProtections::getLocal($userinfo, $_POST)->update(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); + } else { + if (strpos($result['path'], $userinfo['documentroot']) === 0) { + $result['path'] = str_replace($userinfo['documentroot'], "/", $result['path']); + } + + $result = \Froxlor\PhpHelper::htmlentitiesArray($result); + + $htpasswd_edit_data = include_once dirname(__FILE__) . '/lib/formfields/customer/extras/formfield.htpasswd_edit.php'; + $htpasswd_edit_form = \Froxlor\UI\HtmlForm::genHTMLForm($htpasswd_edit_data); $title = $htpasswd_edit_data['htpasswd_edit']['title']; $image = $htpasswd_edit_data['htpasswd_edit']['image']; - eval("echo \"" . getTemplate("extras/htpasswds_edit") . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("extras/htpasswds_edit") . "\";"); } } } } elseif ($page == 'htaccess') { + + // redirect if this customer sub-page is hidden via settings + if (Settings::IsInList('panel.customer_hide_options', 'extras.pathoptions')) { + \Froxlor\UI\Response::redirectTo('customer_index.php'); + } + if ($action == '') { - $log->logAction(USR_ACTION, LOG_NOTICE, "viewed customer_extras::htaccess"); + $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed customer_extras::htaccess"); $fields = array( 'path' => $lng['panel']['path'], 'options_indexes' => $lng['extras']['view_directory'], @@ -250,212 +192,116 @@ if ($page == 'overview') { 'error500path' => $lng['extras']['error500path'], 'options_cgi' => $lng['extras']['execute_perl'] ); - $paging = new paging($userinfo, TABLE_PANEL_HTACCESS, $fields); - $result_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_HTACCESS . "` - WHERE `customerid`= :customerid " . $paging->getSqlWhere(true) . " " . $paging->getSqlOrderBy() . " " . $paging->getSqlLimit() - ); - Database::pexecute($result_stmt, array("customerid" => $userinfo['customerid'])); - $paging->setEntries(Database::num_rows()); + try { + // get total count + $json_result = DirOptions::getLocal($userinfo)->listingCount(); + $result = json_decode($json_result, true)['data']; + // initialize pagination and filtering + $paging = new \Froxlor\UI\Pagination($userinfo, $fields, $result); + // get list + $json_result = DirOptions::getLocal($userinfo, $paging->getApiCommandParams())->listing(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; + $sortcode = $paging->getHtmlSortCode($lng); $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); $searchcode = $paging->getHtmlSearchCode($lng); $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); - $i = 0; $count = 0; $htaccess = ''; - $cperlenabled = customerHasPerlEnabled($userinfo['customerid']); + $cperlenabled = \Froxlor\Customer\Customer::customerHasPerlEnabled($userinfo['customerid']); - while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { - if ($paging->checkDisplay($i)) { - if (strpos($row['path'], $userinfo['documentroot']) === 0) { - $row['path'] = str_replace($userinfo['documentroot'], "/", $row['path']); - } - - $row['options_indexes'] = str_replace('1', $lng['panel']['yes'], $row['options_indexes']); - $row['options_indexes'] = str_replace('0', $lng['panel']['no'], $row['options_indexes']); - $row['options_cgi'] = str_replace('1', $lng['panel']['yes'], $row['options_cgi']); - $row['options_cgi'] = str_replace('0', $lng['panel']['no'], $row['options_cgi']); - $row = htmlentities_array($row); - eval("\$htaccess.=\"" . getTemplate("extras/htaccess_htaccess") . "\";"); - $count++; + foreach ($result['list'] as $row) { + if (strpos($row['path'], $userinfo['documentroot']) === 0) { + $row['path'] = str_replace($userinfo['documentroot'], "/", $row['path']); } - - $i++; + $row['path'] = \Froxlor\FileDir::makeCorrectDir($row['path']); + $row['options_indexes'] = str_replace('1', $lng['panel']['yes'], $row['options_indexes']); + $row['options_indexes'] = str_replace('0', $lng['panel']['no'], $row['options_indexes']); + $row['options_cgi'] = str_replace('1', $lng['panel']['yes'], $row['options_cgi']); + $row['options_cgi'] = str_replace('0', $lng['panel']['no'], $row['options_cgi']); + $row = \Froxlor\PhpHelper::htmlentitiesArray($row); + eval("\$htaccess.=\"" . \Froxlor\UI\Template::getTemplate("extras/htaccess_htaccess") . "\";"); + $count ++; } - eval("echo \"" . getTemplate("extras/htaccess") . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("extras/htaccess") . "\";"); } elseif ($action == 'delete' && $id != 0) { - $result_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_HTACCESS . "` - WHERE `customerid` = :customerid - AND `id` = :id" - ); - Database::pexecute($result_stmt, array("customerid" => $userinfo['customerid'], "id" => $id)); - $result = $result_stmt->fetch(PDO::FETCH_ASSOC); + try { + $json_result = DirOptions::getLocal($userinfo, array( + 'id' => $id + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; if (isset($result['customerid']) && $result['customerid'] != '' && $result['customerid'] == $userinfo['customerid']) { if (isset($_POST['send']) && $_POST['send'] == 'send') { - // do we have to remove the symlink and folder in suexecpath? - if ((int)Settings::Get('perl.suexecworkaround') == 1) { - $loginname = getCustomerDetail($result['customerid'], 'loginname'); - $suexecpath = makeCorrectDir(Settings::Get('perl.suexecpath').'/'.$loginname.'/'.md5($result['path']).'/'); - $perlsymlink = makeCorrectFile($result['path'].'/cgi-bin'); - // remove symlink - if (file_exists($perlsymlink)) { - safe_exec('rm -f '.escapeshellarg($perlsymlink)); - $log->logAction(USR_ACTION, LOG_DEBUG, "deleted suexecworkaround symlink '" . $perlsymlink . "'"); - } - // remove folder in suexec-path - if (file_exists($suexecpath)) { - safe_exec('rm -rf '.escapeshellarg($suexecpath)); - $log->logAction(USR_ACTION, LOG_DEBUG, "deleted suexecworkaround path '" . $suexecpath . "'"); - } + try { + DirOptions::getLocal($userinfo, $_POST)->delete(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } - $stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_HTACCESS . "` - WHERE `customerid`= :customerid - AND `id`= :id" - ); - Database::pexecute($stmt, array("customerid" => $userinfo['customerid'], "id" => $id)); - $log->logAction(USR_ACTION, LOG_INFO, "deleted htaccess for '" . str_replace($userinfo['documentroot'], '/', $result['path']) . "'"); - inserttask('1'); - redirectTo($filename, array('page' => $page, 's' => $s)); + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); } else { - ask_yesno('extras_reallydelete_pathoptions', $filename, array('id' => $id, 'page' => $page, 'action' => $action), str_replace($userinfo['documentroot'], '/', $result['path'])); + \Froxlor\UI\HTML::askYesNo('extras_reallydelete_pathoptions', $filename, array( + 'id' => $id, + 'page' => $page, + 'action' => $action + ), str_replace($userinfo['documentroot'], '/', $result['path'])); } } } elseif ($action == 'add') { if (isset($_POST['send']) && $_POST['send'] == 'send') { - $path = makeCorrectDir(validate($_POST['path'], 'path')); - $userpath = $path; - $path = makeCorrectDir($userinfo['documentroot'] . '/' . $path); - $path_dupe_check_stmt = Database::prepare("SELECT `id`, `path` FROM `" . TABLE_PANEL_HTACCESS . "` - WHERE `path`= :path - AND `customerid`= :customerid" - ); - Database::pexecute($path_dupe_check_stmt, array("path" => $path, "customerid" => $userinfo['customerid'])); - $path_dupe_check = $path_dupe_check_stmt->fetch(PDO::FETCH_ASSOC); - - if (!$_POST['path']) { - standard_error('invalidpath'); - } - - if (isset($_POST['options_cgi']) && (int)$_POST['options_cgi'] != 0) { - $options_cgi = '1'; - } else { - $options_cgi = '0'; - } - - $error404path = ''; - if (isset($_POST['error404path'])) { - $error404path = correctErrorDocument($_POST['error404path']); - } - - $error403path = ''; - if (isset($_POST['error403path'])) { - $error403path = correctErrorDocument($_POST['error403path']); - } - - $error500path = ''; - if (isset($_POST['error500path'])) { - $error500path = correctErrorDocument($_POST['error500path']); - } - - if ($path_dupe_check['path'] == $path) { - standard_error('errordocpathdupe', $userpath); - } elseif ($path == '') { - standard_error('patherror'); - } else { - $stmt = Database::prepare('INSERT INTO `' . TABLE_PANEL_HTACCESS . '` SET - `customerid` = :customerid, - `path` = :path, - `options_indexes` = :options_indexes, - `error404path` = :error404path, - `error403path` = :error403path, - `error500path` = :error500path, - `options_cgi` = :options_cgi' - ); - $params = array( - "customerid" => $userinfo['customerid'], - "path" => $path, - "options_indexes" => $_POST['options_indexes'] == '1' ? '1' : '0', - "error403path" => $error403path, - "error404path" => $error404path, - "error500path" => $error500path, - "options_cgi" => $options_cgi - ); - Database::pexecute($stmt, $params); - - $log->logAction(USR_ACTION, LOG_INFO, "added htaccess for '" . $path . "'"); - inserttask('1'); - redirectTo($filename, array('page' => $page, 's' => $s)); + try { + DirOptions::getLocal($userinfo, $_POST)->add(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); } else { - $pathSelect = makePathfield($userinfo['documentroot'], $userinfo['guid'], $userinfo['guid']); - $cperlenabled = customerHasPerlEnabled($userinfo['customerid']); + $pathSelect = \Froxlor\FileDir::makePathfield($userinfo['documentroot'], $userinfo['guid'], $userinfo['guid']); + $cperlenabled = \Froxlor\Customer\Customer::customerHasPerlEnabled($userinfo['customerid']); - $htaccess_add_data = include_once dirname(__FILE__).'/lib/formfields/customer/extras/formfield.htaccess_add.php'; - $htaccess_add_form = htmlform::genHTMLForm($htaccess_add_data); + $htaccess_add_data = include_once dirname(__FILE__) . '/lib/formfields/customer/extras/formfield.htaccess_add.php'; + $htaccess_add_form = \Froxlor\UI\HtmlForm::genHTMLForm($htaccess_add_data); $title = $htaccess_add_data['htaccess_add']['title']; $image = $htaccess_add_data['htaccess_add']['image']; - eval("echo \"" . getTemplate("extras/htaccess_add") . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("extras/htaccess_add") . "\";"); } } elseif (($action == 'edit') && ($id != 0)) { - $result_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_HTACCESS . "` - WHERE `customerid` = :customerid - AND `id` = :id" - ); - Database::pexecute($result_stmt, array("customerid" => $userinfo['customerid'], "id" => $id)); - $result = $result_stmt->fetch(PDO::FETCH_ASSOC); + try { + $json_result = DirOptions::getLocal($userinfo, array( + 'id' => $id + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; if ((isset($result['customerid'])) && ($result['customerid'] != '') && ($result['customerid'] == $userinfo['customerid'])) { if (isset($_POST['send']) && $_POST['send'] == 'send') { - $option_indexes = intval($_POST['options_indexes']); - $options_cgi = isset($_POST['options_cgi']) ? intval($_POST['options_cgi']) : 0; - - if ($option_indexes != '1') { - $option_indexes = '0'; + try { + DirOptions::getLocal($userinfo, $_POST)->update(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } - - if ($options_cgi != '1') { - $options_cgi = '0'; - } - - $error404path = correctErrorDocument($_POST['error404path']); - $error403path = correctErrorDocument($_POST['error403path']); - $error500path = correctErrorDocument($_POST['error500path']); - - if (($option_indexes != $result['options_indexes']) - || ($error404path != $result['error404path']) - || ($error403path != $result['error403path']) - || ($error500path != $result['error500path']) - || ($options_cgi != $result['options_cgi']) - ) { - inserttask('1'); - $stmt = Database::prepare("UPDATE `" . TABLE_PANEL_HTACCESS . "` - SET `options_indexes` = :options_indexes, - `error404path` = :error404path, - `error403path` = :error403path, - `error500path` = :error500path, - `options_cgi` = :options_cgi - WHERE `customerid` = :customerid - AND `id` = :id" - ); - $params = array( - "customerid" => $userinfo['customerid'], - "options_indexes" => $_POST['options_indexes'] == '1' ? '1' : '0', - "error403path" => $error403path, - "error404path" => $error404path, - "error500path" => $error500path, - "options_cgi" => $options_cgi, - "id" => $id - ); - Database::pexecute($stmt, $params); - $log->logAction(USR_ACTION, LOG_INFO, "edited htaccess for '" . str_replace($userinfo['documentroot'], '/', $result['path']) . "'"); - } - - redirectTo($filename, array('page' => $page, 's' => $s)); + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); } else { if (strpos($result['path'], $userinfo['documentroot']) === 0) { $result['path'] = str_replace($userinfo['documentroot'], "/", $result['path']); @@ -464,21 +310,92 @@ if ($page == 'overview') { $result['error404path'] = $result['error404path']; $result['error403path'] = $result['error403path']; $result['error500path'] = $result['error500path']; - $cperlenabled = customerHasPerlEnabled($userinfo['customerid']); + $cperlenabled = \Froxlor\Customer\Customer::customerHasPerlEnabled($userinfo['customerid']); /* - $options_indexes = makeyesno('options_indexes', '1', '0', $result['options_indexes']); - $options_cgi = makeyesno('options_cgi', '1', '0', $result['options_cgi']); - */ - $result = htmlentities_array($result); + * $options_indexes = \Froxlor\UI\HTML::makeyesno('options_indexes', '1', '0', $result['options_indexes']); + * $options_cgi = \Froxlor\UI\HTML::makeyesno('options_cgi', '1', '0', $result['options_cgi']); + */ + $result = \Froxlor\PhpHelper::htmlentitiesArray($result); - $htaccess_edit_data = include_once dirname(__FILE__).'/lib/formfields/customer/extras/formfield.htaccess_edit.php'; - $htaccess_edit_form = htmlform::genHTMLForm($htaccess_edit_data); + $htaccess_edit_data = include_once dirname(__FILE__) . '/lib/formfields/customer/extras/formfield.htaccess_edit.php'; + $htaccess_edit_form = \Froxlor\UI\HtmlForm::genHTMLForm($htaccess_edit_data); $title = $htaccess_edit_data['htaccess_edit']['title']; $image = $htaccess_edit_data['htaccess_edit']['image']; - eval("echo \"" . getTemplate("extras/htaccess_edit") . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate("extras/htaccess_edit") . "\";"); } } } +} elseif ($page == 'backup') { + + // redirect if this customer sub-page is hidden via settings + if (Settings::IsInList('panel.customer_hide_options', 'extras.backup')) { + \Froxlor\UI\Response::redirectTo('customer_index.php'); + } + + if (Settings::Get('system.backupenabled') == 1) { + if ($action == 'abort' && isset($_POST['send']) && $_POST['send'] == 'send') { + $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "customer_extras::backup - aborted scheduled backupjob"); + try { + CustomerBackups::getLocal($userinfo, $_POST)->delete(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + \Froxlor\UI\Response::standard_success('backupaborted'); + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 'action' => '', + 's' => $s + )); + } + if ($action == '') { + $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed customer_extras::backup"); + + // check whether there is a backup-job for this customer + try { + $json_result = CustomerBackups::getLocal($userinfo)->listing(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; + $existing_backupJob = null; + if ($result['count'] > 0) { + $existing_backupJob = array_shift($result['list']); + } + + if (isset($_POST['send']) && $_POST['send'] == 'send') { + try { + CustomerBackups::getLocal($userinfo, $_POST)->add(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + \Froxlor\UI\Response::standard_success('backupscheduled'); + } else { + + if (! empty($existing_backupJob)) { + $action = "abort"; + $row = $existing_backupJob['data']; + + $row['path'] = \Froxlor\FileDir::makeCorrectDir(str_replace($userinfo['documentroot'], "/", $row['destdir'])); + $row['backup_web'] = ($row['backup_web'] == '1') ? $lng['panel']['yes'] : $lng['panel']['no']; + $row['backup_mail'] = ($row['backup_mail'] == '1') ? $lng['panel']['yes'] : $lng['panel']['no']; + $row['backup_dbs'] = ($row['backup_dbs'] == '1') ? $lng['panel']['yes'] : $lng['panel']['no']; + } + $pathSelect = \Froxlor\FileDir::makePathfield($userinfo['documentroot'], $userinfo['guid'], $userinfo['guid']); + $backup_data = include_once dirname(__FILE__) . '/lib/formfields/customer/extras/formfield.backup.php'; + $backup_form = \Froxlor\UI\HtmlForm::genHTMLForm($backup_data); + $title = $backup_data['backup']['title']; + $image = $backup_data['backup']['image']; + + if (! empty($existing_backupJob)) { + // overwrite backup_form after we took everything from it we needed + eval("\$backup_form = \"" . \Froxlor\UI\Template::getTemplate("extras/backup_listexisting") . "\";"); + } + eval("echo \"" . \Froxlor\UI\Template::getTemplate("extras/backup") . "\";"); + } + } + } else { + \Froxlor\UI\Response::standard_error('backupfunctionnotenabled'); + } } diff --git a/customer_ftp.php b/customer_ftp.php index c46ef9ce..4cbfa2b9 100644 --- a/customer_ftp.php +++ b/customer_ftp.php @@ -16,10 +16,18 @@ * @package Panel * */ - define('AREA', 'customer'); require './lib/init.php'; +use Froxlor\Database\Database; +use Froxlor\Settings; +use Froxlor\Api\Commands\Ftps as Ftps; + +// redirect if this customer page is hidden via settings +if (Settings::IsInList('panel.customer_hide_options', 'ftp')) { + \Froxlor\UI\Response::redirectTo('customer_index.php'); +} + $id = 0; if (isset($_POST['id'])) { $id = intval($_POST['id']); @@ -28,421 +36,205 @@ if (isset($_POST['id'])) { } if ($page == 'overview') { - $log->logAction(USR_ACTION, LOG_NOTICE, "viewed customer_ftp"); - eval("echo \"" . getTemplate('ftp/ftp') . "\";"); + $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed customer_ftp"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate('ftp/ftp') . "\";"); } elseif ($page == 'accounts') { if ($action == '') { - $log->logAction(USR_ACTION, LOG_NOTICE, "viewed customer_ftp::accounts"); + $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed customer_ftp::accounts"); $fields = array( 'username' => $lng['login']['username'], 'homedir' => $lng['panel']['path'], 'description' => $lng['panel']['ftpdesc'] ); - $paging = new paging($userinfo, TABLE_FTP_USERS, $fields); - - $result_stmt = Database::prepare("SELECT `id`, `username`, `description`, `homedir` FROM `" . TABLE_FTP_USERS . "` - WHERE `customerid`= :customerid " . $paging->getSqlWhere(true) . " " . $paging->getSqlOrderBy() . " " . $paging->getSqlLimit() - ); - Database::pexecute($result_stmt, array("customerid" => $userinfo['customerid'])); - $ftps_count = Database::num_rows(); - $paging->setEntries($ftps_count); + try { + // get total count + $json_result = Ftps::getLocal($userinfo)->listingCount(); + $result = json_decode($json_result, true)['data']; + // initialize pagination and filtering + $paging = new \Froxlor\UI\Pagination($userinfo, $fields, $result); + // get list + $json_result = Ftps::getLocal($userinfo, $paging->getApiCommandParams())->listing(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; + $ftps_count = $paging->getEntries(); $sortcode = $paging->getHtmlSortCode($lng); $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); $searchcode = $paging->getHtmlSearchCode($lng); $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); - $i = 0; $count = 0; $accounts = ''; - while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { - if ($paging->checkDisplay($i)) { - if (strpos($row['homedir'], $userinfo['documentroot']) === 0) { - $row['documentroot'] = str_replace($userinfo['documentroot'], "/", $row['homedir']); - } else { - $row['documentroot'] = $row['homedir']; - } - - $row['documentroot'] = makeCorrectDir($row['documentroot']); - - $row = htmlentities_array($row); - eval("\$accounts.=\"" . getTemplate('ftp/accounts_account') . "\";"); - $count++; + foreach ($result['list'] as $row) { + if (strpos($row['homedir'], $userinfo['documentroot']) === 0) { + $row['documentroot'] = str_replace($userinfo['documentroot'], "/", $row['homedir']); + } else { + $row['documentroot'] = $row['homedir']; } - - $i++; + $row['documentroot'] = \Froxlor\FileDir::makeCorrectDir($row['documentroot']); + $row = \Froxlor\PhpHelper::htmlentitiesArray($row); + eval("\$accounts.=\"" . \Froxlor\UI\Template::getTemplate('ftp/accounts_account') . "\";"); + $count ++; } - eval("echo \"" . getTemplate('ftp/accounts') . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate('ftp/accounts') . "\";"); } elseif ($action == 'delete' && $id != 0) { - $result_stmt = Database::prepare("SELECT `id`, `username`, `homedir`, `up_count`, `up_bytes`, `down_count`, `down_bytes` FROM `" . TABLE_FTP_USERS . "` - WHERE `customerid` = :customerid - AND `id` = :id" - ); - Database::pexecute($result_stmt, array("customerid" => $userinfo['customerid'], "id" => $id)); - $result = $result_stmt->fetch(PDO::FETCH_ASSOC); + try { + $json_result = Ftps::getLocal($userinfo, array( + 'id' => $id + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; if (isset($result['username']) && $result['username'] != $userinfo['loginname']) { if (isset($_POST['send']) && $_POST['send'] == 'send') { - $stmt = Database::prepare("UPDATE `" . TABLE_FTP_USERS . "` - SET `up_count` = `up_count` + :up_count, - `up_bytes` = `up_bytes` + :up_bytes, - `down_count` = `down_count` + :down_count, - `down_bytes` = `down_bytes` + :down_bytes - WHERE `username` = :username" - ); - $params = array( - "up_count" => $result['up_count'], - "up_bytes" => $result['up_bytes'], - "down_count" => $result['down_count'], - "down_bytes" => $result['down_bytes'], - "username" => $userinfo['loginname'] - ); - Database::pexecute($stmt, $params); - - $result_stmt = Database::prepare("SELECT `username`, `homedir` FROM `" . TABLE_FTP_USERS . "` - WHERE `customerid` = :customerid - AND `id` = :id" - ); - Database::pexecute($result_stmt, array("customerid" => $userinfo['customerid'], "id" => $id)); - $result = $result_stmt->fetch(PDO::FETCH_ASSOC); - - $stmt = Database::prepare("DELETE FROM `" . TABLE_FTP_QUOTATALLIES . "` WHERE `name` = :name"); - Database::pexecute($stmt, array("name" => $result['username'])); - - $stmt = Database::prepare("DELETE FROM `" . TABLE_FTP_USERS . "` - WHERE `customerid` = :customerid - AND `id` = :id" - ); - Database::pexecute($stmt, array("customerid" => $userinfo['customerid'], "id" => $id)); - - $stmt = Database::prepare(" - UPDATE `" . TABLE_FTP_GROUPS . "` SET - `members` = REPLACE(`members`, :username,'') - WHERE `customerid` = :customerid - "); - Database::pexecute($stmt, array("username" => ",".$result['username'], "customerid" => $userinfo['customerid'])); - - $log->logAction(USR_ACTION, LOG_INFO, "deleted ftp-account '" . $result['username'] . "'"); - - $resetaccnumber = ($userinfo['ftps_used'] == '1') ? " , `ftp_lastaccountnumber`='0'" : ''; - - // refs #293 - if (isset($_POST['delete_userfiles']) && (int)$_POST['delete_userfiles'] == 1) { - inserttask('8', $userinfo['loginname'], $result['homedir']); + try { + Ftps::getLocal($userinfo, $_POST)->delete(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } - - $stmt = Database::prepare("UPDATE `" . TABLE_PANEL_CUSTOMERS . "` - SET `ftps_used` = `ftps_used` - 1 $resetaccnumber - WHERE `customerid` = :customerid" - ); - Database::pexecute($stmt, array("customerid" => $userinfo['customerid'])); - - redirectTo($filename, array('page' => $page, 's' => $s)); + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); } else { - ask_yesno_withcheckbox('ftp_reallydelete', 'admin_customer_alsoremoveftphomedir', $filename, array('id' => $id, 'page' => $page, 'action' => $action), $result['username']); + \Froxlor\UI\HTML::askYesNoWithCheckbox('ftp_reallydelete', 'admin_customer_alsoremoveftphomedir', $filename, array( + 'id' => $id, + 'page' => $page, + 'action' => $action + ), $result['username']); } } else { - standard_error('ftp_cantdeletemainaccount'); + \Froxlor\UI\Response::standard_error('ftp_cantdeletemainaccount'); } } elseif ($action == 'add') { if ($userinfo['ftps_used'] < $userinfo['ftps'] || $userinfo['ftps'] == '-1') { - if (isset($_POST['send']) - && $_POST['send'] == 'send') { - $description = validate($_POST['ftp_description'], 'description'); - // @FIXME use a good path-validating regex here (refs #1231) - $path = validate($_POST['path'], 'path'); - $password = validate($_POST['ftp_password'], 'password'); - $password = validatePassword($password); - - $sendinfomail = isset($_POST['sendinfomail']) ? 1 : 0; - if ($sendinfomail != 1) { - $sendinfomail = 0; - } - - if (Settings::Get('customer.ftpatdomain') == '1') { - $ftpusername = validate($_POST['ftp_username'], 'username', '/^[a-zA-Z0-9][a-zA-Z0-9\-_]+\$?$/'); - if ($ftpusername == '') { - standard_error(array('stringisempty', 'username')); - } - $ftpdomain = $idna_convert->encode(validate($_POST['ftp_domain'], 'domain')); - $ftpdomain_check_stmt = Database::prepare("SELECT `id`, `domain`, `customerid` FROM `" . TABLE_PANEL_DOMAINS . "` - WHERE `domain` = :domain - AND `customerid` = :customerid" - ); - Database::pexecute($ftpdomain_check_stmt, array("domain" => $ftpdomain, "customerid" => $userinfo['customerid'])); - $ftpdomain_check = $ftpdomain_check_stmt->fetch(PDO::FETCH_ASSOC); - - if ($ftpdomain_check['domain'] != $ftpdomain) { - standard_error('maindomainnonexist', $domain); - } - $username = $ftpusername . "@" . $ftpdomain; - } else { - $username = $userinfo['loginname'] . Settings::Get('customer.ftpprefix') . (intval($userinfo['ftp_lastaccountnumber']) + 1); - } - - $username_check_stmt = Database::prepare("SELECT * FROM `" . TABLE_FTP_USERS . "` - WHERE `username` = :username" - ); - Database::pexecute($username_check_stmt, array("username" => $username)); - $username_check = $username_check_stmt->fetch(PDO::FETCH_ASSOC); - - if (!empty($username_check) && $username_check['username'] = $username) { - standard_error('usernamealreadyexists', $username); - } elseif ($password == '') { - standard_error(array('stringisempty', 'mypassword')); - } elseif ($path == '') { - standard_error('patherror'); - } elseif ($username == $password) { - standard_error('passwordshouldnotbeusername'); - } else { - $path = makeCorrectDir($userinfo['documentroot'] . '/' . $path); - - $cryptPassword = makeCryptPassword($password); - - $stmt = Database::prepare("INSERT INTO `" . TABLE_FTP_USERS . "` - (`customerid`, `username`, `description`, `password`, `homedir`, `login_enabled`, `uid`, `gid`) - VALUES (:customerid, :username, :description, :password, :homedir, 'y', :guid, :guid)" - ); - $params = array( - "customerid" => $userinfo['customerid'], - "username" => $username, - "description" => $description, - "password" => $cryptPassword, - "homedir" => $path, - "guid" => $userinfo['guid'] - ); - Database::pexecute($stmt, $params); - - $result_stmt = Database::prepare("SELECT `bytes_in_used` FROM `" . TABLE_FTP_QUOTATALLIES . "` - WHERE `name` = :name" - ); - Database::pexecute($result_stmt, array("name" => $userinfo['loginname'])); - - while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { - $stmt = Database::prepare("INSERT INTO `" . TABLE_FTP_QUOTATALLIES . "` - (`name`, `quota_type`, `bytes_in_used`, `bytes_out_used`, `bytes_xfer_used`, `files_in_used`, `files_out_used`, `files_xfer_used`) - VALUES (:name, 'user', :bytes_in_used, '0', '0', '0', '0', '0')" - ); - Database::pexecute($stmt, array("name" => $username, "bytes_in_used" => $row['bytes_in_used'])); - } - - $stmt = Database::prepare("UPDATE `" . TABLE_FTP_GROUPS . "` - SET `members` = CONCAT_WS(',',`members`, :username) - WHERE `customerid`= :customerid - AND `gid`= :guid" - ); - $params = array( - "username" => $username, - "customerid" => $userinfo['customerid'], - "guid" => $userinfo['guid'] - ); - Database::pexecute($stmt, $params); - - $stmt = Database::prepare("UPDATE `" . TABLE_PANEL_CUSTOMERS . "` - SET `ftps_used` = `ftps_used` + 1, - `ftp_lastaccountnumber` = `ftp_lastaccountnumber` + 1 - WHERE `customerid` = :customerid" - ); - Database::pexecute($stmt, array("customerid" => $userinfo['customerid'])); - - $log->logAction(USR_ACTION, LOG_INFO, "added ftp-account '" . $username . " (" . $path . ")'"); - inserttask(5); - - if ($sendinfomail == 1) { - $replace_arr = array( - 'SALUTATION' => getCorrectUserSalutation($userinfo), - 'CUST_NAME' => getCorrectUserSalutation($userinfo), // < keep this for compatibility - 'USR_NAME' => $username, - 'USR_PASS' => $password, - 'USR_PATH' => makeCorrectDir(str_replace($userinfo['documentroot'], "/", $path)) - ); - - $def_language = $userinfo['def_language']; - $result_stmt = Database::prepare("SELECT `value` FROM `" . TABLE_PANEL_TEMPLATES . "` - WHERE `adminid` = :adminid - AND `language` = :lang - AND `templategroup`='mails' - AND `varname`='new_ftpaccount_by_customer_subject'" - ); - Database::pexecute($result_stmt, array("adminid" => $userinfo['adminid'], "lang" => $def_language)); - $result = $result_stmt->fetch(PDO::FETCH_ASSOC); - $mail_subject = html_entity_decode(replace_variables((($result['value'] != '') ? $result['value'] : $lng['mails']['new_ftpaccount_by_customer']['subject']), $replace_arr)); - - $def_language = $userinfo['def_language']; - $result_stmt = Database::prepare("SELECT `value` FROM `" . TABLE_PANEL_TEMPLATES . "` - WHERE `adminid` = :adminid - AND `language` = :lang - AND `templategroup`='mails' - AND `varname`='new_ftpaccount_by_customer_mailbody'" - ); - Database::pexecute($result_stmt, array("adminid" => $userinfo['adminid'], "lang" => $def_language)); - $result = $result_stmt->fetch(PDO::FETCH_ASSOC); - $mail_body = html_entity_decode(replace_variables((($result['value'] != '') ? $result['value'] : $lng['mails']['new_ftpaccount_by_customer']['mailbody']), $replace_arr)); - - $_mailerror = false; - try { - $mail->Subject = $mail_subject; - $mail->AltBody = $mail_body; - $mail->MsgHTML(str_replace("\n", "
", $mail_body)); - $mail->AddAddress($userinfo['email'], getCorrectUserSalutation($userinfo)); - $mail->Send(); - } catch(phpmailerException $e) { - $mailerr_msg = $e->errorMessage(); - $_mailerror = true; - } catch (Exception $e) { - $mailerr_msg = $e->getMessage(); - $_mailerror = true; - } - - if ($_mailerror) { - $log->logAction(USR_ACTION, LOG_ERR, "Error sending mail: " . $mailerr_msg); - standard_error('errorsendingmail', $userinfo['email']); - } - - $mail->ClearAddresses(); - } - - redirectTo($filename, array('page' => $page, 's' => $s)); + if (isset($_POST['send']) && $_POST['send'] == 'send') { + try { + Ftps::getLocal($userinfo, $_POST)->add(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); } else { - $pathSelect = makePathfield($userinfo['documentroot'], $userinfo['guid'], $userinfo['guid'], '/'); + $pathSelect = \Froxlor\FileDir::makePathfield($userinfo['documentroot'], $userinfo['guid'], $userinfo['guid'], '/'); if (Settings::Get('customer.ftpatdomain') == '1') { $domainlist = array(); $domains = ''; $result_domains_stmt = Database::prepare("SELECT `domain` FROM `" . TABLE_PANEL_DOMAINS . "` - WHERE `customerid`= :customerid" - ); - Database::pexecute($result_domains_stmt, array("customerid" => $userinfo['customerid'])); + WHERE `customerid`= :customerid"); + Database::pexecute($result_domains_stmt, array( + "customerid" => $userinfo['customerid'] + )); while ($row_domain = $result_domains_stmt->fetch(PDO::FETCH_ASSOC)) { - $domainlist[] = $row_domain['domain']; + $domainlist[] = $row_domain['domain']; } sort($domainlist); if (isset($domainlist[0]) && $domainlist[0] != '') { foreach ($domainlist as $dom) { - $domains .= makeoption($idna_convert->decode($dom), $dom); + $domains .= \Froxlor\UI\HTML::makeoption($idna_convert->decode($dom), $dom); } } } - //$sendinfomail = makeyesno('sendinfomail', '1', '0', '0'); + if (Settings::Get('system.allow_customer_shell') == '1') { + $shells = \Froxlor\UI\HTML::makeoption("/bin/false", "/bin/false", "/bin/false"); + $shells_avail = Settings::Get('system.available_shells'); + if (! empty($shells_avail)) { + $shells_avail = explode(",", $shells_avail); + $shells_avail = array_map("trim", $shells_avail); + foreach ($shells_avail as $_shell) { + $shells .= \Froxlor\UI\HTML::makeoption($_shell, $_shell, "/bin/false"); + } + } + } - $ftp_add_data = include_once dirname(__FILE__).'/lib/formfields/customer/ftp/formfield.ftp_add.php'; - $ftp_add_form = htmlform::genHTMLForm($ftp_add_data); + // $sendinfomail = \Froxlor\UI\HTML::makeyesno('sendinfomail', '1', '0', '0'); + + $ftp_add_data = include_once dirname(__FILE__) . '/lib/formfields/customer/ftp/formfield.ftp_add.php'; + $ftp_add_form = \Froxlor\UI\HtmlForm::genHTMLForm($ftp_add_data); $title = $ftp_add_data['ftp_add']['title']; $image = $ftp_add_data['ftp_add']['image']; - eval("echo \"" . getTemplate('ftp/accounts_add') . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate('ftp/accounts_add') . "\";"); } } } elseif ($action == 'edit' && $id != 0) { - $result_stmt = Database::prepare("SELECT `id`, `username`, `description`, `homedir`, `uid`, `gid` FROM `" . TABLE_FTP_USERS . "` - WHERE `customerid` = :customerid - AND `id` = :id" - ); - Database::pexecute($result_stmt, array("customerid" => $userinfo['customerid'], "id" => $id)); - $result = $result_stmt->fetch(PDO::FETCH_ASSOC); + try { + $json_result = Ftps::getLocal($userinfo, array( + 'id' => $id + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; if (isset($result['username']) && $result['username'] != '') { if (isset($_POST['send']) && $_POST['send'] == 'send') { - // @FIXME use a good path-validating regex here (refs #1231) - $path = validate($_POST['path'], 'path'); - - $_setnewpass = false; - if (isset($_POST['ftp_password']) && $_POST['ftp_password'] != '') { - $password = validate($_POST['ftp_password'], 'password'); - $password = validatePassword($password); - $_setnewpass = true; + try { + Ftps::getLocal($userinfo, $_POST)->update(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } - - if ($_setnewpass) { - if ($password == '') { - standard_error(array('stringisempty', 'mypassword')); - } elseif ($result['username'] == $password) { - standard_error('passwordshouldnotbeusername'); - } - $log->logAction(USR_ACTION, LOG_INFO, "updated ftp-account password for '" . $result['username'] . "'"); - $cryptPassword = makeCryptPassword($password); - - $stmt = Database::prepare("UPDATE `" . TABLE_FTP_USERS . "` - SET `password` = :password - WHERE `customerid` = :customerid - AND `id` = :id" - ); - Database::pexecute($stmt, array("customerid" => $userinfo['customerid'], "id" => $id, "password" => $cryptPassword)); - } - - if ($path != '') { - $path = makeCorrectDir($userinfo['documentroot'] . '/' . $path); - - if ($path != $result['homedir']) { - if (!file_exists($path)) { - // it's the task for "new ftp" but that will - // create all directories and correct their permissions - inserttask(5); - } - - $log->logAction(USR_ACTION, LOG_INFO, "updated ftp-account homdir for '" . $result['username'] . "'"); - - $stmt = Database::prepare("UPDATE `" . TABLE_FTP_USERS . "` - SET `homedir` = :homedir - WHERE `customerid` = :customerid - AND `id` = :id" - ); - $params = array( - "homedir" => $path, - "customerid" => $userinfo['customerid'], - "id" => $id - ); - Database::pexecute($stmt, $params); - } - } - - $log->logAction(USR_ACTION, LOG_INFO, "edited ftp-account '" . $result['username'] . "'"); - $description = validate($_POST['ftp_description'], 'description'); - $stmt = Database::prepare("UPDATE `" . TABLE_FTP_USERS . "` - SET `description` = :desc - WHERE `customerid` = :customerid - AND `id` = :id" - ); - Database::pexecute($stmt, array("desc" => $description, "customerid" => $userinfo['customerid'], "id" => $id)); - - redirectTo($filename, array('page' => $page, 's' => $s)); + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); } else { if (strpos($result['homedir'], $userinfo['documentroot']) === 0) { $homedir = str_replace($userinfo['documentroot'], "/", $result['homedir']); } else { $homedir = $result['homedir']; } - $homedir = makeCorrectDir($homedir); + $homedir = \Froxlor\FileDir::makeCorrectDir($homedir); - $pathSelect = makePathfield($userinfo['documentroot'], $userinfo['guid'], $userinfo['guid'], $homedir); + $pathSelect = \Froxlor\FileDir::makePathfield($userinfo['documentroot'], $userinfo['guid'], $userinfo['guid'], $homedir); if (Settings::Get('customer.ftpatdomain') == '1') { $domains = ''; $result_domains_stmt = Database::prepare("SELECT `domain` FROM `" . TABLE_PANEL_DOMAINS . "` - WHERE `customerid` = :customerid" - ); - Database::pexecute($result_domains_stmt, array("customerid" => $userinfo['customerid'])); + WHERE `customerid` = :customerid"); + Database::pexecute($result_domains_stmt, array( + "customerid" => $userinfo['customerid'] + )); while ($row_domain = $result_domains_stmt->fetch(PDO::FETCH_ASSOC)) { - $domains .= makeoption($idna_convert->decode($row_domain['domain']), $row_domain['domain']); + $domains .= \Froxlor\UI\HTML::makeoption($idna_convert->decode($row_domain['domain']), $row_domain['domain']); } } - $ftp_edit_data = include_once dirname(__FILE__).'/lib/formfields/customer/ftp/formfield.ftp_edit.php'; - $ftp_edit_form = htmlform::genHTMLForm($ftp_edit_data); + if (Settings::Get('system.allow_customer_shell') == '1') { + $shells = \Froxlor\UI\HTML::makeoption("/bin/false", "/bin/false", $result['shell']); + $shells_avail = Settings::Get('system.available_shells'); + if (! empty($shells_avail)) { + $shells_avail = explode(",", $shells_avail); + $shells_avail = array_map("trim", $shells_avail); + foreach ($shells_avail as $_shell) { + $shells .= \Froxlor\UI\HTML::makeoption($_shell, $_shell, $result['shell']); + } + } + } + + $ftp_edit_data = include_once dirname(__FILE__) . '/lib/formfields/customer/ftp/formfield.ftp_edit.php'; + $ftp_edit_form = \Froxlor\UI\HtmlForm::genHTMLForm($ftp_edit_data); $title = $ftp_edit_data['ftp_edit']['title']; $image = $ftp_edit_data['ftp_edit']['image']; - eval("echo \"" . getTemplate('ftp/accounts_edit') . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate('ftp/accounts_edit') . "\";"); } } } diff --git a/customer_index.php b/customer_index.php index 9d8772d7..a164a16e 100644 --- a/customer_index.php +++ b/customer_index.php @@ -16,41 +16,47 @@ * @package Panel * */ - define('AREA', 'customer'); require './lib/init.php'; -if ($action == 'logout') { - $log->logAction(USR_ACTION, LOG_NOTICE, 'logged out'); +use Froxlor\Database\Database; +use Froxlor\Settings; +use Froxlor\Api\Commands\Customers as Customers; - $params = array("customerid" => $userinfo['customerid']); +if ($action == 'logout') { + $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, 'logged out'); + + $params = array( + "customerid" => $userinfo['customerid'] + ); if (Settings::Get('session.allow_multiple_login') == '1') { $stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_SESSIONS . "` WHERE `userid` = :customerid AND `adminsession` = '0' - AND `hash` = :hash" - ); + AND `hash` = :hash"); $params["hash"] = $s; } else { $stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_SESSIONS . "` WHERE `userid` = :customerid - AND `adminsession` = '0'" - ); + AND `adminsession` = '0'"); } Database::pexecute($stmt, $params); - redirectTo('index.php'); + \Froxlor\UI\Response::redirectTo('index.php'); } if ($page == 'overview') { - $log->logAction(USR_ACTION, LOG_NOTICE, "viewed customer_index"); + $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed customer_index"); $domain_stmt = Database::prepare("SELECT `domain` FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `customerid` = :customerid AND `parentdomainid` = '0' AND `id` <> :standardsubdomain "); - Database::pexecute($domain_stmt, array("customerid" => $userinfo['customerid'], "standardsubdomain" => $userinfo['standardsubdomain'])); + Database::pexecute($domain_stmt, array( + "customerid" => $userinfo['customerid'], + "standardsubdomain" => $userinfo['standardsubdomain'] + )); $domains = ''; $domainArray = array(); @@ -70,7 +76,10 @@ if ($page == 'overview') { WHERE `customerid` = :customerid AND `id` = :standardsubdomain "); - $std_domain = Database::pexecute_first($std_domain_stmt, array("customerid" => $userinfo['customerid'], "standardsubdomain" => $userinfo['standardsubdomain'])); + $std_domain = Database::pexecute_first($std_domain_stmt, array( + "customerid" => $userinfo['customerid'], + "standardsubdomain" => $userinfo['standardsubdomain'] + )); $stdsubdomain = $std_domain['domain']; } @@ -78,118 +87,150 @@ if ($page == 'overview') { $yesterday = time() - (60 * 60 * 24); $month = date('M Y', $yesterday); + // get disk-space usages for web, mysql and mail + $usages_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_DISKSPACE . "` WHERE `customerid` = :cid ORDER BY `stamp` DESC LIMIT 1"); + $usages = Database::pexecute_first($usages_stmt, array( + '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')); + } else { + $userinfo['diskspace_used'] = 0; + $userinfo['mailspace_used'] = 0; + $userinfo['dbspace_used'] = 0; + $userinfo['total_used'] = 0; + } $userinfo['diskspace'] = round($userinfo['diskspace'] / 1024, Settings::Get('panel.decimal_places')); - $userinfo['diskspace_used'] = round($userinfo['diskspace_used'] / 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 = str_replace_array('-1', $lng['customer']['unlimited'], $userinfo, 'diskspace traffic mysqls emails email_accounts email_forwarders email_quota ftps tickets subdomains'); + $userinfo = \Froxlor\PhpHelper::strReplaceArray('-1', $lng['customer']['unlimited'], $userinfo, 'diskspace traffic mysqls emails email_accounts email_forwarders email_quota ftps subdomains'); $userinfo['custom_notes'] = ($userinfo['custom_notes'] != '') ? nl2br($userinfo['custom_notes']) : ''; $services_enabled = ""; $se = array(); - if ($userinfo['imap'] == '1') $se[] = "IMAP"; - if ($userinfo['pop3'] == '1') $se[] = "POP3"; - if ($userinfo['phpenabled'] == '1') $se[] = "PHP"; - if ($userinfo['perlenabled'] == '1') $se[] = "Perl/CGI"; + if ($userinfo['imap'] == '1') + $se[] = "IMAP"; + if ($userinfo['pop3'] == '1') + $se[] = "POP3"; + if ($userinfo['phpenabled'] == '1') + $se[] = "PHP"; + if ($userinfo['perlenabled'] == '1') + $se[] = "Perl/CGI"; + if ($userinfo['api_allowed'] == '1') + $se[] = 'API'; $services_enabled = implode(", ", $se); - eval("echo \"" . getTemplate('index/index') . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate('index/index') . "\";"); } elseif ($page == 'change_password') { if (isset($_POST['send']) && $_POST['send'] == 'send') { - $old_password = validate($_POST['old_password'], 'old password'); - if (!validatePasswordLogin($userinfo,$old_password,TABLE_PANEL_CUSTOMERS,'customerid')) { - standard_error('oldpasswordnotcorrect'); + $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 = validatePassword($_POST['new_password'], 'new password'); - $new_password_confirm = validatePassword($_POST['new_password_confirm'], 'new password confirm'); + $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'); if ($old_password == '') { - standard_error(array('stringisempty', 'oldpassword')); + \Froxlor\UI\Response::standard_error(array( + 'stringisempty', + 'oldpassword' + )); } elseif ($new_password == '') { - standard_error(array('stringisempty', 'newpassword')); + \Froxlor\UI\Response::standard_error(array( + 'stringisempty', + 'newpassword' + )); } elseif ($new_password_confirm == '') { - standard_error(array('stringisempty', 'newpasswordconfirm')); + \Froxlor\UI\Response::standard_error(array( + 'stringisempty', + 'newpasswordconfirm' + )); } elseif ($new_password != $new_password_confirm) { - standard_error('newpasswordconfirmerror'); + \Froxlor\UI\Response::standard_error('newpasswordconfirmerror'); } else { // Update user password - $stmt = Database::prepare("UPDATE `" . TABLE_PANEL_CUSTOMERS . "` - SET `password` = :newpassword - WHERE `customerid` = :customerid" - ); - $params = array( - "newpassword" => makeCryptPassword($new_password), - "customerid" => $userinfo['customerid'] - ); - Database::pexecute($stmt, $params); - $log->logAction(USR_ACTION, LOG_NOTICE, 'changed password'); + try { + Customers::getLocal($userinfo, array( + 'id' => $userinfo['customerid'], + 'new_customer_password' => $new_password + ))->update(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, 'changed password'); // Update ftp password if (isset($_POST['change_main_ftp']) && $_POST['change_main_ftp'] == 'true') { - $cryptPassword = makeCryptPassword($new_password); + $cryptPassword = \Froxlor\System\Crypt::makeCryptPassword($new_password); $stmt = Database::prepare("UPDATE `" . TABLE_FTP_USERS . "` SET `password` = :password WHERE `customerid` = :customerid - AND `username` = :username" - ); + AND `username` = :username"); $params = array( "password" => $cryptPassword, "customerid" => $userinfo['customerid'], "username" => $userinfo['loginname'] ); Database::pexecute($stmt, $params); - $log->logAction(USR_ACTION, LOG_NOTICE, 'changed main ftp password'); + $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, 'changed main ftp password'); } - // Update webalizer password - if (isset($_POST['change_webalizer']) && $_POST['change_webalizer'] == 'true') { - if (CRYPT_STD_DES == 1) { - $saltfordescrypt = substr(md5(uniqid(microtime(), 1)), 4, 2); - $new_webalizer_password = crypt($new_password, $saltfordescrypt); - } else { - $new_webalizer_password = crypt($new_password); - } + // Update statistics password + if (isset($_POST['change_stats']) && $_POST['change_stats'] == 'true') { + $new_stats_password = \Froxlor\System\Crypt::makeCryptPassword($new_password, true); $stmt = Database::prepare("UPDATE `" . TABLE_PANEL_HTPASSWDS . "` SET `password` = :password WHERE `customerid` = :customerid - AND `username` = :username" - ); + AND `username` = :username"); $params = array( - "password" => $new_webalizer_password, + "password" => $new_stats_password, "customerid" => $userinfo['customerid'], "username" => $userinfo['loginname'] ); Database::pexecute($stmt, $params); } - redirectTo($filename, array('s' => $s)); + \Froxlor\UI\Response::redirectTo($filename, array( + 's' => $s + )); } } else { - eval("echo \"" . getTemplate('index/change_password') . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate('index/change_password') . "\";"); } } elseif ($page == 'change_language') { if (isset($_POST['send']) && $_POST['send'] == 'send') { - $def_language = validate($_POST['def_language'], 'default language'); + $def_language = \Froxlor\Validate\Validate::validate($_POST['def_language'], 'default language'); if (isset($languages[$def_language])) { - $stmt = Database::prepare("UPDATE `" . TABLE_PANEL_CUSTOMERS . "` - SET `def_language` = :lang - WHERE `customerid` = :customerid" - ); - Database::pexecute($stmt, array("lang" => $def_language, "customerid" => $userinfo['customerid'])); + try { + Customers::getLocal($userinfo, array( + 'id' => $userinfo['customerid'], + 'def_language' => $def_language + ))->update(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + // also update current session $stmt = Database::prepare("UPDATE `" . TABLE_PANEL_SESSIONS . "` SET `language` = :lang - WHERE `hash` = :hash" - ); - Database::pexecute($stmt, array("lang" => $def_language, "hash" => $s)); - - $log->logAction(USR_ACTION, LOG_NOTICE, "changed default language to '" . $def_language . "'"); + WHERE `hash` = :hash"); + Database::pexecute($stmt, array( + "lang" => $def_language, + "hash" => $s + )); } - - redirectTo($filename, array('s' => $s)); + $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "changed default language to '" . $def_language . "'"); + \Froxlor\UI\Response::redirectTo($filename, array( + 's' => $s + )); } else { $default_lang = Settings::Get('panel.standardlanguage'); if ($userinfo['def_language'] != '') { @@ -197,30 +238,37 @@ if ($page == 'overview') { } $language_options = ''; - while (list($language_file, $language_name) = each($languages)) { - $language_options .= makeoption($language_name, $language_file, $default_lang, true); + foreach ($languages as $language_file => $language_name) { + $language_options .= \Froxlor\UI\HTML::makeoption($language_name, $language_file, $default_lang, true); } - eval("echo \"" . getTemplate('index/change_language') . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate('index/change_language') . "\";"); } } elseif ($page == 'change_theme') { if (isset($_POST['send']) && $_POST['send'] == 'send') { - $theme = validate($_POST['theme'], 'theme'); - - $stmt = Database::prepare("UPDATE `" . TABLE_PANEL_CUSTOMERS . "` - SET `theme` = :theme - WHERE `customerid` = :customerid" - ); - Database::pexecute($stmt, array("theme" => $theme, "customerid" => $userinfo['customerid'])); + $theme = \Froxlor\Validate\Validate::validate($_POST['theme'], 'theme'); + try { + Customers::getLocal($userinfo, array( + 'id' => $userinfo['customerid'], + 'theme' => $theme + ))->update(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + // also update current session $stmt = Database::prepare("UPDATE `" . TABLE_PANEL_SESSIONS . "` SET `theme` = :theme - WHERE `hash` = :hash" - ); - Database::pexecute($stmt, array("theme" => $theme, "hash" => $s)); + WHERE `hash` = :hash"); + Database::pexecute($stmt, array( + "theme" => $theme, + "hash" => $s + )); - $log->logAction(USR_ACTION, LOG_NOTICE, "changed default theme to '" . $theme . "'"); - redirectTo($filename, array('s' => $s)); + $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "changed default theme to '" . $theme . "'"); + \Froxlor\UI\Response::redirectTo($filename, array( + 's' => $s + )); } else { $default_theme = Settings::Get('panel.default_theme'); if ($userinfo['theme'] != '') { @@ -228,14 +276,13 @@ if ($page == 'overview') { } $theme_options = ''; - $themes_avail = getThemes(); + $themes_avail = \Froxlor\UI\Template::getThemes(); foreach ($themes_avail as $t => $d) { - $theme_options.= makeoption($d, $t, $default_theme, true); + $theme_options .= \Froxlor\UI\HTML::makeoption($d, $t, $default_theme, true); } - eval("echo \"" . getTemplate('index/change_theme') . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate('index/change_theme') . "\";"); } - } elseif ($page == 'send_error_report' && Settings::Get('system.allow_error_report_customer') == '1') { // only show this if we really have an exception to report @@ -243,8 +290,8 @@ if ($page == 'overview') { $errid = $_GET['errorid']; // read error file - $err_dir = makeCorrectDir(FROXLOR_INSTALL_DIR."/logs/"); - $err_file = makeCorrectFile($err_dir."/".$errid."_sql-error.log"); + $err_dir = \Froxlor\FileDir::makeCorrectDir(\Froxlor\Froxlor::getInstallDir() . "/logs/"); + $err_file = \Froxlor\FileDir::makeCorrectFile($err_dir . "/" . $errid . "_sql-error.log"); if (file_exists($err_file)) { @@ -254,27 +301,26 @@ if ($page == 'overview') { $_error = array( 'code' => str_replace("\n", "", substr($error[1], 5)), 'message' => str_replace("\n", "", substr($error[2], 4)), - 'file' => str_replace("\n", "", substr($error[3], 5 + strlen(FROXLOR_INSTALL_DIR))), + 'file' => str_replace("\n", "", substr($error[3], 5 + strlen(\Froxlor\Froxlor::getInstallDir()))), 'line' => str_replace("\n", "", substr($error[4], 5)), - 'trace' => str_replace(FROXLOR_INSTALL_DIR, "", substr($error[5], 6)) + 'trace' => str_replace(\Froxlor\Froxlor::getInstallDir(), "", substr($error[5], 6)) ); // build mail-content $mail_body = "Dear froxlor-team,\n\n"; $mail_body .= "the following error has been reported by a user:\n\n"; $mail_body .= "-------------------------------------------------------------\n"; - $mail_body .= $_error['code'].' '.$_error['message']."\n\n"; - $mail_body .= "File: ".$_error['file'].':'.$_error['line']."\n\n"; - $mail_body .= "Trace:\n".trim($_error['trace'])."\n\n"; + $mail_body .= $_error['code'] . ' ' . $_error['message'] . "\n\n"; + $mail_body .= "File: " . $_error['file'] . ':' . $_error['line'] . "\n\n"; + $mail_body .= "Trace:\n" . trim($_error['trace']) . "\n\n"; $mail_body .= "-------------------------------------------------------------\n\n"; - $mail_body .= "Froxlor-version: ".$version."\n\n"; + $mail_body .= "Froxlor-version: " . $version . "\n"; + $mail_body .= "DB-version: " . $dbversion . "\n\n"; $mail_body .= "End of report"; $mail_html = str_replace("\n", "
", $mail_body); // send actual report to dev-team - if (isset($_POST['send']) - && $_POST['send'] == 'send' - ) { + if (isset($_POST['send']) && $_POST['send'] == 'send') { // send mail and say thanks $_mailerror = false; try { @@ -283,7 +329,7 @@ if ($page == 'overview') { $mail->MsgHTML($mail_html); $mail->AddAddress('error-reports@froxlor.org', 'Froxlor Developer Team'); $mail->Send(); - } catch(phpmailerException $e) { + } catch (\PHPMailer\PHPMailer\Exception $e) { $mailerr_msg = $e->errorMessage(); $_mailerror = true; } catch (Exception $e) { @@ -293,21 +339,30 @@ if ($page == 'overview') { if ($_mailerror) { // error when reporting an error...LOLFUQ - standard_error('send_report_error', $mailerr_msg); + \Froxlor\UI\Response::standard_error('send_report_error', $mailerr_msg); } // finally remove error from fs @unlink($err_file); - redirectTo($filename, array('s' => $s)); + \Froxlor\UI\Response::redirectTo($filename, array( + 's' => $s + )); } // show a nice summary of the error-report // before actually sending anything - eval("echo \"" . getTemplate("index/send_error_report") . "\";"); - + eval("echo \"" . \Froxlor\UI\Template::getTemplate("index/send_error_report") . "\";"); } else { - redirectTo($filename, array('s' => $s)); + \Froxlor\UI\Response::redirectTo($filename, array( + 's' => $s + )); } } else { - redirectTo($filename, array('s' => $s)); + \Froxlor\UI\Response::redirectTo($filename, array( + 's' => $s + )); } +} elseif ($page == 'apikeys' && Settings::Get('api.enabled') == 1) { + require_once __DIR__ . '/api_keys.php'; +} elseif ($page == '2fa' && Settings::Get('2fa.enabled') == 1) { + require_once __DIR__ . '/2fa.php'; } diff --git a/customer_logger.php b/customer_logger.php index ba8debe7..2c4bb534 100644 --- a/customer_logger.php +++ b/customer_logger.php @@ -16,12 +16,19 @@ * @package Panel * */ - define('AREA', 'customer'); require './lib/init.php'; -if ($page == 'log' -) { +use Froxlor\Api\Commands\SysLog; +use Froxlor\Database\Database; +use Froxlor\Settings; + +// redirect if this customer page is hidden via settings +if (Settings::IsInList('panel.customer_hide_options', 'extras.logger')) { + \Froxlor\UI\Response::redirectTo('customer_index.php'); +} + +if ($page == 'log') { if ($action == '') { $fields = array( 'date' => $lng['logger']['date'], @@ -29,89 +36,85 @@ if ($page == 'log' 'user' => $lng['logger']['user'], 'text' => $lng['logger']['action'] ); - $paging = new paging($userinfo, TABLE_PANEL_LOG, $fields, null, null, 0, 'desc'); - $result_stmt = Database::prepare(' - SELECT * FROM `' . TABLE_PANEL_LOG . '` WHERE `user` = :loginname ' . $paging->getSqlWhere(true) . ' ' . $paging->getSqlOrderBy() . ' ' . $paging->getSqlLimit() - ); - Database::pexecute($result_stmt, array("loginname" => $userinfo['loginname'])); - $logs_count = Database::num_rows(); - $paging->setEntries($logs_count); + try { + // get total count + $json_result = SysLog::getLocal($userinfo)->listingCount(); + $result = json_decode($json_result, true)['data']; + // initialize pagination and filtering + $paging = new \Froxlor\UI\Pagination($userinfo, $fields, $result); + // get list + $json_result = SysLog::getLocal($userinfo, $paging->getApiCommandParams())->listing(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; $sortcode = $paging->getHtmlSortCode($lng); $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); $searchcode = $paging->getHtmlSearchCode($lng); $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); $clog = array(); - while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { + foreach ($result['list'] as $row) { - if (!isset($clog[$row['action']]) - || !is_array($clog[$row['action']]) - ) { + if (! isset($clog[$row['action']]) || ! is_array($clog[$row['action']])) { $clog[$row['action']] = array(); } $clog[$row['action']][$row['logid']] = $row; } - if ($paging->sortfield == 'date' - && $paging->sortorder == 'desc' - ) { + if ($paging->sortfield == 'date' && $paging->sortorder == 'desc') { krsort($clog); } else { ksort($clog); } - $i = 0; $count = 0; $log_count = 0; $log = ''; foreach ($clog as $action => $logrows) { $_action = 0; foreach ($logrows as $row) { - if ($paging->checkDisplay($i)) { - $row = htmlentities_array($row); - $row['date'] = date("d.m.y H:i:s", $row['date']); + // if ($paging->checkDisplay($i)) { + $row = \Froxlor\PhpHelper::htmlentitiesArray($row); + $row['date'] = date("d.m.y H:i:s", $row['date']); - if ($_action != $action) { - switch ($action) { - case USR_ACTION: - $_action = $lng['admin']['customer']; - break; - case RES_ACTION: - $_action = $lng['logger']['reseller']; - break; - case ADM_ACTION: - $_action = $lng['logger']['admin']; - break; - case CRON_ACTION: - $_action = $lng['logger']['cron']; - break; - case LOGIN_ACTION: - $_action = $lng['logger']['login']; - break; - case LOG_ERROR: - $_action = $lng['logger']['intern']; - break; - default: - $_action = $lng['logger']['unknown']; - break; - } - - $row['action'] = $_action; - eval("\$log.=\"" . getTemplate('logger/logger_action') . "\";"); + if ($_action != $action) { + switch ($action) { + case \Froxlor\FroxlorLogger::USR_ACTION: + $_action = $lng['admin']['customer']; + break; + case \Froxlor\FroxlorLogger::RES_ACTION: + $_action = $lng['logger']['reseller']; + break; + case \Froxlor\FroxlorLogger::ADM_ACTION: + $_action = $lng['logger']['admin']; + break; + case \Froxlor\FroxlorLogger::CRON_ACTION: + $_action = $lng['logger']['cron']; + break; + case \Froxlor\FroxlorLogger::LOGIN_ACTION: + $_action = $lng['logger']['login']; + break; + case \Froxlor\FroxlorLogger::LOG_ERROR: + $_action = $lng['logger']['intern']; + break; + default: + $_action = $lng['logger']['unknown']; + break; } - $log_count++; - $row['type'] = getLogLevelDesc($row['type']); - eval("\$log.=\"" . getTemplate('logger/logger_log') . "\";"); - $count++; - $_action = $action; + $row['action'] = $_action; + eval("\$log.=\"" . \Froxlor\UI\Template::getTemplate('logger/logger_action') . "\";"); } - $i++; + + $log_count ++; + $row['type'] = \Froxlor\FroxlorLogger::getInstanceOf()->getLogLevelDesc($row['type']); + eval("\$log.=\"" . \Froxlor\UI\Template::getTemplate('logger/logger_log') . "\";"); + $count ++; + $_action = $action; } - $i++; } - eval("echo \"" . getTemplate('logger/logger') . "\";"); - + eval("echo \"" . \Froxlor\UI\Template::getTemplate('logger/logger') . "\";"); } } diff --git a/customer_mysql.php b/customer_mysql.php index 39c642da..40e84575 100644 --- a/customer_mysql.php +++ b/customer_mysql.php @@ -16,10 +16,18 @@ * @package Panel * */ - define('AREA', 'customer'); require './lib/init.php'; +use Froxlor\Database\Database; +use Froxlor\Settings; +use Froxlor\Api\Commands\Mysqls as Mysqls; + +// redirect if this customer page is hidden via settings +if (Settings::IsInList('panel.customer_hide_options', 'mysql')) { + \Froxlor\UI\Response::redirectTo('customer_index.php'); +} + // get sql-root access data Database::needRoot(true); Database::needSqlData(); @@ -33,67 +41,74 @@ if (isset($_POST['id'])) { } if ($page == 'overview') { - $log->logAction(USR_ACTION, LOG_NOTICE, "viewed customer_mysql"); + $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed customer_mysql"); Database::needSqlData(); $sql = Database::getSqlData(); $lng['mysql']['description'] = str_replace('', $sql['host'], $lng['mysql']['description']); - eval("echo \"" . getTemplate('mysql/mysql') . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate('mysql/mysql') . "\";"); } elseif ($page == 'mysqls') { if ($action == '') { - $log->logAction(USR_ACTION, LOG_NOTICE, "viewed customer_mysql::mysqls"); + $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed customer_mysql::mysqls"); $fields = array( 'databasename' => $lng['mysql']['databasename'], 'description' => $lng['mysql']['databasedescription'] ); - $paging = new paging($userinfo, TABLE_PANEL_DATABASES, $fields); - $result_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_DATABASES . "` - WHERE `customerid`= :customerid " . $paging->getSqlWhere(true) . " " . $paging->getSqlOrderBy() . " " . $paging->getSqlLimit() - ); - Database::pexecute($result_stmt, array("customerid" => $userinfo['customerid'])); - $mysqls_count = Database::num_rows(); - $paging->setEntries($mysqls_count); + try { + // get total count + $json_result = Mysqls::getLocal($userinfo)->listingCount(); + $result = json_decode($json_result, true)['data']; + // initialize pagination and filtering + $paging = new \Froxlor\UI\Pagination($userinfo, $fields, $result); + // get list + $json_result = Mysqls::getLocal($userinfo, $paging->getApiCommandParams())->listing(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; + $mysqls_count = $paging->getEntries(); $sortcode = $paging->getHtmlSortCode($lng); $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); $searchcode = $paging->getHtmlSearchCode($lng); $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); - $i = 0; $count = 0; $mysqls = ''; - $dbservers_stmt = Database::query("SELECT COUNT(DISTINCT `dbserver`) as numservers FROM `".TABLE_PANEL_DATABASES."`"); + $dbservers_stmt = Database::query("SELECT COUNT(DISTINCT `dbserver`) as numservers FROM `" . TABLE_PANEL_DATABASES . "`"); $dbserver = $dbservers_stmt->fetch(PDO::FETCH_ASSOC); $count_mysqlservers = $dbserver['numservers']; // Begin root-session Database::needRoot(true); - while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { - if ($paging->checkDisplay($i)) { - $row = htmlentities_array($row); - $mbdata_stmt = Database::prepare("SELECT SUM(data_length + index_length) as MB FROM information_schema.TABLES + foreach ($result['list'] as $row) { + $row = \Froxlor\PhpHelper::htmlentitiesArray($row); + $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("table_schema" => $row['databasename'])); - $mbdata = $mbdata_stmt->fetch(PDO::FETCH_ASSOC); - $row['size'] = size_readable($mbdata['MB'], 'GiB', 'bi', '%01.' . (int)Settings::Get('panel.decimal_places') . 'f %s'); - eval("\$mysqls.=\"" . getTemplate('mysql/mysqls_database') . "\";"); - $count++; + GROUP BY table_schema"); + $mbdata = Database::pexecute_first($mbdata_stmt, array( + "table_schema" => $row['databasename'] + )); + if (!$mbdata) { + $mbdata = array('MB' => 0); } - $i++; + $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 ++; } Database::needRoot(false); // End root-session - eval("echo \"" . getTemplate('mysql/mysqls') . "\";"); - + eval("echo \"" . \Froxlor\UI\Template::getTemplate('mysql/mysqls') . "\";"); } elseif ($action == 'delete' && $id != 0) { - $result_stmt = Database::prepare('SELECT `id`, `databasename`, `description`, `dbserver` FROM `' . TABLE_PANEL_DATABASES . '` - WHERE `customerid`="' . (int)$userinfo['customerid'] . '" - AND `id`="' . (int)$id . '"' - ); - Database::pexecute($result_stmt, array("customerid" => $userinfo['customerid'])); - $result = $result_stmt->fetch(PDO::FETCH_ASSOC); + + try { + $json_result = Mysqls::getLocal($userinfo, array( + 'id' => $id + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; if (isset($result['databasename']) && $result['databasename'] != '') { @@ -102,251 +117,91 @@ if ($page == 'overview') { $sql_root = Database::getSqlData(); Database::needRoot(false); - if (!isset($sql_root[$result['dbserver']]) || !is_array($sql_root[$result['dbserver']])) { + if (! isset($sql_root[$result['dbserver']]) || ! is_array($sql_root[$result['dbserver']])) { $result['dbserver'] = 0; } if (isset($_POST['send']) && $_POST['send'] == 'send') { - // Begin root-session - Database::needRoot(true, $result['dbserver']); - $dbm = new DbManager($log); - $dbm->getManager()->deleteDatabase($result['databasename']); - $log->logAction(USR_ACTION, LOG_INFO, "deleted database '" . $result['databasename'] . "'"); - Database::needRoot(false); - // End root-session - - $stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_DATABASES . "` - WHERE `customerid` = :customerid - AND `id` = :id" - ); - Database::pexecute($stmt, array("customerid" => $userinfo['customerid'], "id" => $id)); - - $resetaccnumber = ($userinfo['mysqls_used'] == '1') ? " , `mysql_lastaccountnumber` = '0' " : ''; - - $stmt = Database::prepare("UPDATE `" . TABLE_PANEL_CUSTOMERS . "` - SET `mysqls_used` = `mysqls_used` - 1 " . $resetaccnumber . " - WHERE `customerid` = :customerid" - ); - Database::pexecute($stmt, array("customerid" => $userinfo['customerid'])); - - redirectTo($filename, array('page' => $page, 's' => $s)); + try { + Mysqls::getLocal($userinfo, $_POST)->delete(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); } else { $dbnamedesc = $result['databasename']; if (isset($result['description']) && $result['description'] != '') { - $dbnamedesc .= ' ('.$result['description'].')'; + $dbnamedesc .= ' (' . $result['description'] . ')'; } - ask_yesno('mysql_reallydelete', $filename, array('id' => $id, 'page' => $page, 'action' => $action), $dbnamedesc); + \Froxlor\UI\HTML::askYesNo('mysql_reallydelete', $filename, array( + 'id' => $id, + 'page' => $page, + 'action' => $action + ), $dbnamedesc); } } } elseif ($action == 'add') { if ($userinfo['mysqls_used'] < $userinfo['mysqls'] || $userinfo['mysqls'] == '-1') { if (isset($_POST['send']) && $_POST['send'] == 'send') { - $password = validate($_POST['mysql_password'], 'password'); - $password = validatePassword($password); - - $sendinfomail = isset($_POST['sendinfomail']) ? 1 : 0; - if ($sendinfomail != 1) { - $sendinfomail = 0; - } - - if ($password == '') { - standard_error(array('stringisempty', 'mypassword')); - } else { - $dbserver = 0; - $dbservers_stmt = Database::query("SELECT COUNT(DISTINCT `dbserver`) as numservers FROM `".TABLE_PANEL_DATABASES."`"); - $_dbserver = $dbservers_stmt->fetch(PDO::FETCH_ASSOC); - $count_mysqlservers = $_dbserver['numservers']; - if ($count_mysqlservers > 1) { - $dbserver = validate($_POST['mysql_server'], html_entity_decode($lng['mysql']['mysql_server']), '', '', 0); - Database::needRoot(true, $dbserver); - Database::needSqlData(); - $sql_root = Database::getSqlData(); - Database::needRoot(false); - if (!isset($sql_root) || !is_array($sql_root)) { - $dbserver = 0; - } - } - - // validate description before actual adding the database, #1052 - $databasedescription = validate(trim($_POST['description']), 'description'); - - // create database, user, set permissions, etc.pp. - $dbm = new DbManager($log); - $username = $dbm->createDatabase( - $userinfo['loginname'], - $password, - $userinfo['mysql_lastaccountnumber'] - ); - - // we've checked against the password in dbm->createDatabase - if ($username == false) { - standard_error('passwordshouldnotbeusername'); - } - - // Statement modified for Database description -- PH 2004-11-29 - $stmt = Database::prepare('INSERT INTO `' . TABLE_PANEL_DATABASES . '` - (`customerid`, `databasename`, `description`, `dbserver`) - VALUES (:customerid, :databasename, :description, :dbserver)' - ); - $params = array( - "customerid" => $userinfo['customerid'], - "databasename" => $username, - "description" => $databasedescription, - "dbserver" => $dbserver - ); - Database::pexecute($stmt, $params); - - $stmt = Database::prepare('UPDATE `' . TABLE_PANEL_CUSTOMERS . '` - SET `mysqls_used` = `mysqls_used` + 1, `mysql_lastaccountnumber` = `mysql_lastaccountnumber` + 1 - WHERE `customerid` = :customerid' - ); - Database::pexecute($stmt, array("customerid" => $userinfo['customerid'])); - - if ($sendinfomail == 1) { - $pma = $lng['admin']['notgiven']; - if (Settings::Get('panel.phpmyadmin_url') != '') { - $pma = Settings::Get('panel.phpmyadmin_url'); - } - - Database::needRoot(true, $dbserver); - Database::needSqlData(); - $sql_root = Database::getSqlData(); - Database::needRoot(false); - - $replace_arr = array( - 'SALUTATION' => getCorrectUserSalutation($userinfo), - 'CUST_NAME' => getCorrectUserSalutation($userinfo), // < keep this for compatibility - 'DB_NAME' => $username, - 'DB_PASS' => $password, - 'DB_DESC' => $databasedescription, - 'DB_SRV' => $sql_root['host'], - 'PMA_URI' => $pma - ); - - $def_language = $userinfo['def_language']; - $result_stmt = Database::prepare("SELECT `value` FROM `" . TABLE_PANEL_TEMPLATES . "` - WHERE `adminid` = :adminid - AND `language` = :lang - AND `templategroup`='mails' - AND `varname`='new_database_by_customer_subject'" - ); - Database::pexecute($result_stmt, array("adminid" => $userinfo['adminid'], "lang" => $def_language)); - $result = $result_stmt->fetch(PDO::FETCH_ASSOC); - $mail_subject = html_entity_decode(replace_variables((($result['value'] != '') ? $result['value'] : $lng['mails']['new_database_by_customer']['subject']), $replace_arr)); - - $result_stmt = Database::prepare("SELECT `value` FROM `" . TABLE_PANEL_TEMPLATES . "` - WHERE `adminid`= :adminid - AND `language`= :lang - AND `templategroup` = 'mails' - AND `varname` = 'new_database_by_customer_mailbody'" - ); - Database::pexecute($result_stmt, array("adminid" => $userinfo['adminid'], "lang" => $def_language)); - $result = $result_stmt->fetch(PDO::FETCH_ASSOC); - $mail_body = html_entity_decode(replace_variables((($result['value'] != '') ? $result['value'] : $lng['mails']['new_database_by_customer']['mailbody']), $replace_arr)); - - $_mailerror = false; - try { - $mail->Subject = $mail_subject; - $mail->AltBody = $mail_body; - $mail->MsgHTML(str_replace("\n", "
", $mail_body)); - $mail->AddAddress($userinfo['email'], getCorrectUserSalutation($userinfo)); - $mail->Send(); - } catch(phpmailerException $e) { - $mailerr_msg = $e->errorMessage(); - $_mailerror = true; - } catch (Exception $e) { - $mailerr_msg = $e->getMessage(); - $_mailerror = true; - } - - if ($_mailerror) { - $log->logAction(USR_ACTION, LOG_ERR, "Error sending mail: " . $mailerr_msg); - standard_error('errorsendingmail', $userinfo['email']); - } - - $mail->ClearAddresses(); - } - - redirectTo($filename, array('page' => $page, 's' => $s)); + try { + Mysqls::getLocal($userinfo, $_POST)->add(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); } else { - $dbservers_stmt = Database::query("SELECT DISTINCT `dbserver` FROM `".TABLE_PANEL_DATABASES."`"); + $dbservers_stmt = Database::query("SELECT DISTINCT `dbserver` FROM `" . TABLE_PANEL_DATABASES . "`"); $mysql_servers = ''; $count_mysqlservers = 0; while ($dbserver = $dbservers_stmt->fetch(PDO::FETCH_ASSOC)) { Database::needRoot(true, $dbserver['dbserver']); Database::needSqlData(); $sql_root = Database::getSqlData(); - $mysql_servers .= makeoption($sql_root['caption'], $dbserver['dbserver']); - $count_mysqlservers++; + $mysql_servers .= \Froxlor\UI\HTML::makeoption($sql_root['caption'], $dbserver['dbserver']); + $count_mysqlservers ++; } Database::needRoot(false); - $mysql_add_data = include_once dirname(__FILE__).'/lib/formfields/customer/mysql/formfield.mysql_add.php'; - $mysql_add_form = htmlform::genHTMLForm($mysql_add_data); + $mysql_add_data = include_once dirname(__FILE__) . '/lib/formfields/customer/mysql/formfield.mysql_add.php'; + $mysql_add_form = \Froxlor\UI\HtmlForm::genHTMLForm($mysql_add_data); $title = $mysql_add_data['mysql_add']['title']; $image = $mysql_add_data['mysql_add']['image']; - eval("echo \"" . getTemplate('mysql/mysqls_add') . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate('mysql/mysqls_add') . "\";"); } } } elseif ($action == 'edit' && $id != 0) { - $result_stmt = Database::prepare("SELECT `id`, `databasename`, `description`, `dbserver` FROM `" . TABLE_PANEL_DATABASES . "` - WHERE `customerid` = :customerid - AND `id` = :id" - ); - Database::pexecute($result_stmt, array("customerid" => $userinfo['customerid'], "id" => $id)); - $result = $result_stmt->fetch(PDO::FETCH_ASSOC); + try { + $json_result = Mysqls::getLocal($userinfo, array( + 'id' => $id + ))->get(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + $result = json_decode($json_result, true)['data']; if (isset($result['databasename']) && $result['databasename'] != '') { - if (!isset($sql_root[$result['dbserver']]) || !is_array($sql_root[$result['dbserver']])) { - $result['dbserver'] = 0; - } - if (isset($_POST['send']) && $_POST['send'] == 'send') { - // Only change Password if it is set, do nothing if it is empty! -- PH 2004-11-29 - $password = validate($_POST['mysql_password'], 'password'); - if ($password != '') { - // validate password - $password = validatePassword($password); - - if ($password == $result['databasename']) { - standard_error('passwordshouldnotbeusername'); - } - - // Begin root-session - Database::needRoot(true); - foreach (array_map('trim', explode(',', Settings::Get('system.mysql_access_host'))) as $mysql_access_host) { - $stmt = Database::prepare("SET PASSWORD FOR :dbname@:host = PASSWORD(:password)"); - $params = array( - "dbname" => $result['databasename'], - "host" => $mysql_access_host, - "password" => $password - ); - Database::pexecute($stmt, $params); - } - - $stmt = Database::prepare("FLUSH PRIVILEGES"); - Database::pexecute($stmt); - Database::needRoot(false); - // End root-session + try { + $json_result = Mysqls::getLocal($userinfo, $_POST)->update(); + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); } - - // Update the Database description -- PH 2004-11-29 - $log->logAction(USR_ACTION, LOG_INFO, "edited database '" . $result['databasename'] . "'"); - $databasedescription = validate($_POST['description'], 'description'); - $stmt = Database::prepare("UPDATE `" . TABLE_PANEL_DATABASES . "` - SET `description` = :desc - WHERE `customerid` = :customerid - AND `id` = :id" - ); - Database::pexecute($stmt, array("desc" => $databasedescription, "customerid" => $userinfo['customerid'], "id" => $id)); - redirectTo($filename, array('page' => $page, 's' => $s)); + \Froxlor\UI\Response::redirectTo($filename, array( + 'page' => $page, + 's' => $s + )); } else { - $dbservers_stmt = Database::query("SELECT COUNT(DISTINCT `dbserver`) as numservers FROM `".TABLE_PANEL_DATABASES."`"); + $dbservers_stmt = Database::query("SELECT COUNT(DISTINCT `dbserver`) as numservers FROM `" . TABLE_PANEL_DATABASES . "`"); $dbserver = $dbservers_stmt->fetch(PDO::FETCH_ASSOC); $count_mysqlservers = $dbserver['numservers']; @@ -355,13 +210,13 @@ if ($page == 'overview') { $sql_root = Database::getSqlData(); Database::needRoot(false); - $mysql_edit_data = include_once dirname(__FILE__).'/lib/formfields/customer/mysql/formfield.mysql_edit.php'; - $mysql_edit_form = htmlform::genHTMLForm($mysql_edit_data); + $mysql_edit_data = include_once dirname(__FILE__) . '/lib/formfields/customer/mysql/formfield.mysql_edit.php'; + $mysql_edit_form = \Froxlor\UI\HtmlForm::genHTMLForm($mysql_edit_data); $title = $mysql_edit_data['mysql_edit']['title']; $image = $mysql_edit_data['mysql_edit']['image']; - eval("echo \"" . getTemplate('mysql/mysqls_edit') . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate('mysql/mysqls_edit') . "\";"); } } } diff --git a/customer_tickets.php b/customer_tickets.php deleted file mode 100644 index a2840ece..00000000 --- a/customer_tickets.php +++ /dev/null @@ -1,387 +0,0 @@ - (2003-2009) - * @author Froxlor team (2010-) - * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt - * @package Panel - * - */ - -define('AREA', 'customer'); -require './lib/init.php'; - -if (isset($_POST['id'])) { - - $id = intval($_POST['id']); - - //Check if the current user is allowed to see the current ticket. - $stmt = Database::prepare("SELECT `id` FROM `panel_tickets` WHERE `id` = :id AND `customerid` = :customerid"); - $result = Database::pexecute_first($stmt, array("id" => $id, "customerid" => $userinfo['customerid'])); - - if ($result == null) { - // no rights to see the requested ticket - standard_error(array('ticketnotaccessible')); - } -} elseif (isset($_GET['id'])) { - $id = intval($_GET['id']); -} - -if ($page == 'overview') { - $log->logAction(USR_ACTION, LOG_NOTICE, "viewed customer_tickets"); - eval("echo \"" . getTemplate("tickets/ticket") . "\";"); -} elseif ($page == 'tickets') { - if ($action == '') { - $log->logAction(USR_ACTION, LOG_NOTICE, "viewed customer_tickets::tickets"); - $fields = array( - 'status' => $lng['ticket']['status'], - 'lastchange' => $lng['ticket']['lastchange'], - 'subject' => $lng['ticket']['subject'], - 'lastreplier' => $lng['ticket']['lastreplier'] - ); - $paging = new paging($userinfo, TABLE_PANEL_TICKETS, $fields); - $stmt = Database::prepare('SELECT `main`.`id`, (SELECT COUNT(`sub`.`id`) FROM `' . TABLE_PANEL_TICKETS . '` `sub` - WHERE `sub`.`answerto` = `main`.`id`) AS `ticket_answers`, `main`.`lastchange`, `main`.`subject`, `main`.`status`, `main`.`lastreplier`, `main`.`priority` - FROM `' . TABLE_PANEL_TICKETS . '` as `main` - WHERE `main`.`answerto` = "0" - AND `archived` = "0" - AND `customerid`= :customerid ' . $paging->getSqlWhere(true) . " " . $paging->getSqlOrderBy() . " " . $paging->getSqlLimit() - ); - Database::pexecute($stmt, array("customerid" => $userinfo['customerid'])); - - $paging->setEntries(Database::num_rows()); - $sortcode = $paging->getHtmlSortCode($lng); - $arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s); - $searchcode = $paging->getHtmlSearchCode($lng); - $pagingcode = $paging->getHtmlPagingCode($filename . '?page=' . $page . '&s=' . $s); - $i = 0; - $count = 0; - $tickets = ''; - $tickets_count = 0; - - while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { - if ($paging->checkDisplay($i)) { - $tickets_count++; - $row = htmlentities_array($row); - $row['lastchange'] = date("d.m.y H:i", $row['lastchange']); - - if ($row['status'] >= 0 && $row['status'] <= 2) { - $reopen = 0; - } else { - $reopen = 1; - } - - $row['status'] = ticket::getStatusText($lng, $row['status']); - $row['priority'] = ticket::getPriorityText($lng, $row['priority']); - - if ($row['lastreplier'] == '1') { - $row['lastreplier'] = $lng['ticket']['staff']; - $cananswer = 1; - } else { - $row['lastreplier'] = $lng['ticket']['customer']; - $cananswer = 0; - } - - $row['subject'] = html_entity_decode($row['subject']); - if (strlen($row['subject']) > 30) { - $ts = wordwrap($row['subject'], 30, "|"); - $ts = explode("|", $ts); - $row['subject'] = $ts[0]. '...'; - } - - eval("\$tickets.=\"" . getTemplate("tickets/tickets_tickets") . "\";"); - $count++; - } - - $i++; - } - - $supportavailable = 0; - $time = date("Hi", time()); - $day = date("w", time()); - $start = substr(Settings::Get('ticket.worktime_begin'), 0, 2) . substr(Settings::Get('ticket.worktime_begin'), 3, 2); - $end = substr(Settings::Get('ticket.worktime_end'), 0, 2) . substr(Settings::Get('ticket.worktime_end'), 3, 2); - - if ($time >= $start && $time <= $end) { - $supportavailable = 1; - } - - if (Settings::Get('ticket.worktime_sat') == "0" && $day == "6") { - $supportavailable = 0; - } - - if (Settings::Get('ticket.worktime_sun') == "0" && $day == "0") { - $supportavailable = 0; - } - - if (Settings::Get('ticket.worktime_all') == "1") { - $supportavailable = 1; - } - - $ticketsopen = 0; - $stmt = Database::prepare('SELECT COUNT(`id`) as `count` FROM `' . TABLE_PANEL_TICKETS . '` - WHERE `customerid` = :customerid - AND `answerto` = "0" - AND (`status` = "0" OR `status` = "1" OR `status` = "2")' - ); - $opentickets = Database::pexecute_first($stmt, array("customerid" => $userinfo['customerid'])); - - if (Settings::Get('ticket.concurrently_open') != - 1 && Settings::Get('ticket.concurrently_open') != '') { - $notmorethanxopentickets = strtr($lng['ticket']['notmorethanxopentickets'], array('%s' => Settings::Get('ticket.concurrently_open'))); - } else { - $notmorethanxopentickets = ''; - } - - $ticketsopen = (int)$opentickets['count']; - eval("echo \"" . getTemplate("tickets/tickets") . "\";"); - - } elseif ($action == 'new') { - if ($userinfo['tickets_used'] < $userinfo['tickets'] || $userinfo['tickets'] == '-1') { - if (isset($_POST['send']) && $_POST['send'] == 'send') { - $newticket = ticket::getInstanceOf($userinfo, -1); - $newticket->Set('subject', validate($_POST['subject'], 'subject'), true, false); - $newticket->Set('priority', validate($_POST['priority'], 'priority'), true, false); - $newticket->Set('category', validate($_POST['category'], 'category'), true, false); - $newticket->Set('customer', (int)$userinfo['customerid'], true, false); - $newticket->Set('admin', (int)$userinfo['adminid'], true, false); - $newticket->Set('message', validate(str_replace("\r\n", "\n", $_POST['message']), 'message', '/^[^\0]*$/'), true, false); - - if ($newticket->Get('subject') == null) { - standard_error(array('stringisempty', 'mysubject')); - } elseif ($newticket->Get('message') == null) { - standard_error(array('stringisempty', 'mymessage')); - } else { - $now = time(); - $newticket->Set('dt', $now, true, true); - $newticket->Set('lastchange', $now, true, true); - $newticket->Set('ip', $_SERVER['REMOTE_ADDR'], true, true); - $newticket->Set('status', '0', true, true); - $newticket->Set('lastreplier', '0', true, true); - $newticket->Set('by', '0', true, true); - $newticket->Insert(); - $log->logAction(USR_ACTION, LOG_NOTICE, "opened support-ticket '" . $newticket->Get('subject') . "'"); - - $stmt = Database::prepare('UPDATE `' . TABLE_PANEL_CUSTOMERS . '` - SET `tickets_used`=`tickets_used` + 1 - WHERE `customerid`= :customerid' - ); - Database::pexecute($stmt, array("customerid" => $userinfo['customerid'])); - - // Customer mail - $newticket->sendMail((int)$userinfo['customerid'], 'new_ticket_for_customer_subject', $lng['mails']['new_ticket_for_customer']['subject'], 'new_ticket_for_customer_mailbody', $lng['mails']['new_ticket_for_customer']['mailbody']); - - // Admin mail - $newticket->sendMail(-1, 'new_ticket_by_customer_subject', $lng['mails']['new_ticket_by_customer']['subject'], 'new_ticket_by_customer_mailbody', $lng['mails']['new_ticket_by_customer']['mailbody']); - redirectTo($filename, array('page' => $page, 's' => $s)); - } - } else { - $categories = ''; - $result_stmt = Database::prepare('SELECT `id`, `name` FROM `' . TABLE_PANEL_TICKET_CATS . '` - WHERE `adminid` = :adminid - ORDER BY `logicalorder`, `name` ASC' - ); - $result = Database::pexecute_first($result_stmt, array("adminid" => $userinfo['adminid'])); - - if (isset($result['name']) && $result['name'] != '') { - $result2_stmt = Database::prepare('SELECT `id`, `name` FROM `' . TABLE_PANEL_TICKET_CATS . '` - WHERE `adminid` = :adminid - ORDER BY `logicalorder`, `name` ASC' - ); - Database::pexecute($result2_stmt, array("adminid" => $userinfo['adminid'])); - - while ($row = $result2_stmt->fetch(PDO::FETCH_ASSOC)) { - $categories.= makeoption($row['name'], $row['id']); - } - } else { - $categories = makeoption($lng['ticket']['no_cat'], '0'); - } - - $priorities = makeoption($lng['ticket']['high'], '1'); - $priorities.= makeoption($lng['ticket']['normal'], '2'); - $priorities.= makeoption($lng['ticket']['low'], '3'); - $ticketsopen = 0; - $opentickets_stmt = Database::prepare('SELECT COUNT(`id`) as `count` FROM `' . TABLE_PANEL_TICKETS . '` - WHERE `customerid` = :customerid - AND `answerto` = "0" - AND (`status` = "0" OR `status` = "1" OR `status` = "2")' - ); - $opentickets = Database::pexecute_first($opentickets_stmt, array("customerid" => $userinfo['customerid'])); - - if (Settings::Get('ticket.concurrently_open') != -1 && Settings::Get('ticket.concurrently_open') != '') { - $notmorethanxopentickets = strtr($lng['ticket']['notmorethanxopentickets'], array('%s' => Settings::Get('ticket.concurrently_open'))); - } else { - $notmorethanxopentickets = ''; - } - - $ticketsopen = (int)$opentickets['count']; - - $ticket_add_data = include_once dirname(__FILE__).'/lib/formfields/customer/tickets/formfield.ticket_add.php'; - $ticket_add_form = htmlform::genHTMLForm($ticket_add_data); - - $title = $ticket_add_data['ticket_add']['title']; - $image = $ticket_add_data['ticket_add']['image']; - - eval("echo \"" . getTemplate("tickets/tickets_new") . "\";"); - } - } else { - standard_error('nomoreticketsavailable'); - } - } elseif ($action == 'answer' && $id != 0) { - if (isset($_POST['send']) && $_POST['send'] == 'send') { - $replyticket = ticket::getInstanceOf($userinfo, -1); - $replyticket->Set('subject', validate($_POST['subject'], 'subject'), true, false); - $replyticket->Set('priority', validate($_POST['priority'], 'priority'), true, false); - $replyticket->Set('message', validate(str_replace("\r\n", "\n", $_POST['message']), 'message', '/^[^\0]*$/'), true, false); - - if ($replyticket->Get('message') == null) { - standard_error(array('stringisempty', 'mymessage')); - } else { - $now = time(); - $replyticket->Set('customer', (int)$userinfo['customerid'], true, true); - $replyticket->Set('lastchange', $now, true, true); - $replyticket->Set('ip', $_SERVER['REMOTE_ADDR'], true, true); - $replyticket->Set('status', '1', true, true); - $replyticket->Set('answerto', (int)$id, true, false); - $replyticket->Set('by', '0', true, true); - $replyticket->Insert(); - - // Update priority if changed - $mainticket = ticket::getInstanceOf($userinfo, (int)$id); - - if ($replyticket->Get('priority') != $mainticket->Get('priority')) { - $mainticket->Set('priority', $replyticket->Get('priority'), true); - } - - $mainticket->Set('lastchange', $now); - $mainticket->Set('lastreplier', '0'); - $mainticket->Set('status', '1'); - $mainticket->Update(); - $log->logAction(USR_ACTION, LOG_NOTICE, "answered support-ticket '" . $mainticket->Get('subject') . "'"); - $mainticket->sendMail(-1, 'new_reply_ticket_by_customer_subject', $lng['mails']['new_reply_ticket_by_customer']['subject'], 'new_reply_ticket_by_customer_mailbody', $lng['mails']['new_reply_ticket_by_customer']['mailbody']); - redirectTo($filename, array('page' => $page, 's' => $s)); - } - } else { - $ticket_replies = ''; - $mainticket = ticket::getInstanceOf($userinfo, (int)$id); - $dt = date("d.m.Y H:i\h", $mainticket->Get('dt')); - $status = ticket::getStatusText($lng, $mainticket->Get('status')); - - if ($mainticket->Get('status') >= 0 && $mainticket->Get('status') <= 2) { - $isclosed = 0; - } else { - $isclosed = 1; - } - - if ($mainticket->Get('by') == '1') { - $by = $lng['ticket']['staff']; - } else { - $cid = $mainticket->Get('customer'); - $usr_stmt = Database::prepare('SELECT `customerid`, `firstname`, `name`, `company`, `loginname` - FROM `' . TABLE_PANEL_CUSTOMERS . '` - WHERE `customerid` = :customerid ' - ); - $usr = Database::pexecute_first($usr_stmt, array("customerid" => $cid)); - $by = getCorrectFullUserDetails($usr); - } - - $subject = $mainticket->Get('subject'); - $message = $mainticket->Get('message'); - eval("\$ticket_replies.=\"" . getTemplate("tickets/tickets_tickets_main") . "\";"); - $result_stmt = Database::prepare('SELECT `name` FROM `' . TABLE_PANEL_TICKET_CATS . '` - WHERE `id`= :id ' - ); - $row = Database::pexecute_first($result_stmt, array("id" => $mainticket->Get('category'))); - - $andere_stmt = Database::prepare('SELECT * FROM `' . TABLE_PANEL_TICKETS . '` - WHERE `answerto`= :answerto - ORDER BY `lastchange` ASC' - ); - Database::pexecute($andere_stmt, array("answerto" => $id)); - $numrows_andere = Database::num_rows(); - - while ($row2 = $andere_stmt->fetch(PDO::FETCH_ASSOC)) { - $subticket = ticket::getInstanceOf($userinfo, (int)$row2['id']); - $lastchange = date("d.m.Y H:i\h", $subticket->Get('lastchange')); - - if ($subticket->Get('by') == '1') { - $by = $lng['ticket']['staff']; - } else { - $cid = $subticket->Get('customer'); - $usr_stmt = Database::prepare(' - SELECT `customerid`, `firstname`, `name`, `company`, `loginname` - FROM `' . TABLE_PANEL_CUSTOMERS . '` - WHERE `customerid` = :customerid ' - ); - $usr = Database::pexecute_first($usr_stmt, array("customerid" => $cid)); - $by = getCorrectFullUserDetails($usr); - } - - $subject = $subticket->Get('subject'); - $message = $subticket->Get('message'); - - $row2 = htmlentities_array($row2); - eval("\$ticket_replies.=\"" . getTemplate("tickets/tickets_tickets_list") . "\";"); - } - - $priorities = makeoption($lng['ticket']['high'], '1', $mainticket->Get('priority'), true, true); - $priorities.= makeoption($lng['ticket']['normal'], '2', $mainticket->Get('priority'), true, true); - $priorities.= makeoption($lng['ticket']['low'], '3', $mainticket->Get('priority'), true, true); - $subject = htmlentities($mainticket->Get('subject')); - $ticket_replies_count = $numrows_andere + 1; - - // don't forget the main-ticket! - $ticket_reply_data = include_once dirname(__FILE__).'/lib/formfields/customer/tickets/formfield.ticket_reply.php'; - $ticket_reply_form = htmlform::genHTMLForm($ticket_reply_data); - - $title = $ticket_reply_data['ticket_reply']['title']; - $image = $ticket_reply_data['ticket_reply']['image']; - - eval("echo \"" . getTemplate("tickets/tickets_reply") . "\";"); - } - } elseif ($action == 'close' && $id != 0) { - if (isset($_POST['send']) && $_POST['send'] == 'send') { - $now = time(); - $mainticket = ticket::getInstanceOf($userinfo, (int)$id); - $mainticket->Set('lastchange', $now, true, true); - $mainticket->Set('lastreplier', '0', true, true); - $mainticket->Set('status', '3', true, true); - $mainticket->Update(); - $log->logAction(USR_ACTION, LOG_NOTICE, "closed support-ticket '" . $mainticket->Get('subject') . "'"); - redirectTo($filename, array('page' => $page, 's' => $s)); - } else { - $mainticket = ticket::getInstanceOf($userinfo, (int)$id); - ask_yesno('ticket_reallyclose', $filename, array('id' => $id, 'page' => $page, 'action' => $action), $mainticket->Get('subject')); - } - } elseif ($action == 'reopen' && $id != 0) { - $ticketsopen = 0; - $opentickets_stmt = Database::prepare('SELECT COUNT(`id`) as `count` FROM `' . TABLE_PANEL_TICKETS . '` - WHERE `customerid` = :customerid - AND `answerto` = "0" - AND (`status` = "0" OR `status` = "1" OR `status` = "2")' - ); - $opentickets = Database::pexecute_first($opentickets_stmt, array("customerid" => $userinfo['customerid'])); - $ticketsopen = (int)$opentickets['count']; - - if ($ticketsopen > Settings::Get('ticket.concurrently_open') && Settings::Get('ticket.concurrently_open') != - 1 && Settings::Get('ticket.concurrently_open') != '') { - standard_error('notmorethanxopentickets', Settings::Get('ticket.concurrently_open')); - } - - $now = time(); - $mainticket = ticket::getInstanceOf($userinfo, (int)$id); - $mainticket->Set('lastchange', $now, true, true); - $mainticket->Set('lastreplier', '0', true, true); - $mainticket->Set('status', '0', true, true); - $mainticket->Update(); - $log->logAction(USR_ACTION, LOG_NOTICE, "reopened support-ticket '" . $mainticket->Get('subject') . "'"); - redirectTo($filename, array('page' => $page, 's' => $s)); - } -} diff --git a/customer_traffic.php b/customer_traffic.php index bbf42281..fdb73394 100644 --- a/customer_traffic.php +++ b/customer_traffic.php @@ -16,10 +16,18 @@ * @package Panel * */ - define('AREA', 'customer'); $intrafficpage = 1; require './lib/init.php'; + +use Froxlor\Database\Database; +use Froxlor\Settings; + +// redirect if this customer page is hidden via settings +if (Settings::IsInList('panel.customer_hide_options', 'traffic')) { + \Froxlor\UI\Response::redirectTo('customer_index.php'); +} + $traffic = ''; $month = null; $year = null; @@ -30,8 +38,7 @@ if (isset($_POST['month']) && isset($_POST['year'])) { } elseif (isset($_GET['month']) && isset($_GET['year'])) { $month = intval($_GET['month']); $year = intval($_GET['year']); -} -//BAM! $_GET??? +} // BAM! $_GET??? elseif (isset($_GET['page']) && $_GET['page'] == 'current') { if (date('d') != '01') { $month = date('m'); @@ -47,7 +54,7 @@ elseif (isset($_GET['page']) && $_GET['page'] == 'current') { } } -if (!is_null($month) && !is_null($year)) { +if (! is_null($month) && ! is_null($year)) { $traf['byte'] = 0; $result_stmt = Database::prepare("SELECT SUM(`http`) as 'http', SUM(`ftp_up`) AS 'ftp_up', SUM(`ftp_down`) as 'ftp_down', SUM(`mail`) as 'mail', `day`, `month`, `year` FROM `" . TABLE_PANEL_TRAFFIC . "` @@ -55,8 +62,7 @@ if (!is_null($month) && !is_null($year)) { AND `month` = :month AND `year` = :year GROUP BY `day` - ORDER BY `day` DESC" - ); + ORDER BY `day` DESC"); $params = array( "customerid" => $userinfo['customerid'], "month" => $month, @@ -80,40 +86,39 @@ 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')); } - eval("\$traffic.=\"" . getTemplate('traffic/traffic_month') . "\";"); + 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']; } - $traffic_complete['http'] = size_readable($traffic_complete['http'] * 1024, 'GiB', 'bi', '%01.'.(int)Settings::Get('panel.decimal_places').'f %s'); - $traffic_complete['ftp'] = size_readable($traffic_complete['ftp'] * 1024, 'GiB', 'bi', '%01.'.(int)Settings::Get('panel.decimal_places').'f %s'); - $traffic_complete['mail'] = size_readable($traffic_complete['mail'] * 1024, 'GiB', 'bi', '%01.'.(int)Settings::Get('panel.decimal_places').'f %s'); + $traffic_complete['http'] = \Froxlor\PhpHelper::sizeReadable($traffic_complete['http'] * 1024, 'GiB', 'bi', '%01.' . (int) Settings::Get('panel.decimal_places') . 'f %s'); + $traffic_complete['ftp'] = \Froxlor\PhpHelper::sizeReadable($traffic_complete['ftp'] * 1024, 'GiB', 'bi', '%01.' . (int) Settings::Get('panel.decimal_places') . 'f %s'); + $traffic_complete['mail'] = \Froxlor\PhpHelper::sizeReadable($traffic_complete['mail'] * 1024, 'GiB', 'bi', '%01.' . (int) Settings::Get('panel.decimal_places') . 'f %s'); - eval("echo \"" . getTemplate('traffic/traffic_details') . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate('traffic/traffic_details') . "\";"); } else { - $result_stmt = Database::prepare("SELECT `month`, `year`, SUM(`http`) AS http, SUM(`ftp_up`) AS ftp_up, SUM(`ftp_down`) AS ftp_down, SUM(`mail`) AS mail + $result_stmt = Database::prepare(" + SELECT `month`, `year`, SUM(`http`) AS http, SUM(`ftp_up`) AS ftp_up, SUM(`ftp_down`) AS ftp_down, SUM(`mail`) AS mail FROM `" . TABLE_PANEL_TRAFFIC . "` WHERE `customerid` = :customerid - GROUP BY CONCAT(`year`,`month`) - ORDER BY CONCAT(`year`,`month`) DESC - LIMIT 12" - ); - Database::pexecute($result_stmt, array("customerid" => $userinfo['customerid'])); + GROUP BY `year`, `month` + ORDER BY `year` DESC, `month` DESC + LIMIT 12 + "); + Database::pexecute($result_stmt, array( + "customerid" => $userinfo['customerid'] + )); $traffic_complete['http'] = 0; $traffic_complete['ftp'] = 0; $traffic_complete['mail'] = 0; @@ -133,28 +138,33 @@ 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')); } - eval("\$traffic.=\"" . getTemplate('traffic/traffic_traffic') . "\";"); + 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') . "\";"); } - $traffic_complete['http'] = size_readable($traffic_complete['http'] * 1024, 'GiB', 'bi', '%01.'.(int)Settings::Get('panel.decimal_places').'f %s'); - $traffic_complete['ftp'] = size_readable($traffic_complete['ftp'] * 1024, 'GiB', 'bi', '%01.'.(int)Settings::Get('panel.decimal_places').'f %s'); - $traffic_complete['mail'] = size_readable($traffic_complete['mail'] * 1024, 'GiB', 'bi', '%01.'.(int)Settings::Get('panel.decimal_places').'f %s'); + $traffic_complete['http'] = \Froxlor\PhpHelper::sizeReadable($traffic_complete['http'] * 1024, 'GiB', 'bi', '%01.' . (int) Settings::Get('panel.decimal_places') . 'f %s'); + $traffic_complete['ftp'] = \Froxlor\PhpHelper::sizeReadable($traffic_complete['ftp'] * 1024, 'GiB', 'bi', '%01.' . (int) Settings::Get('panel.decimal_places') . 'f %s'); + $traffic_complete['mail'] = \Froxlor\PhpHelper::sizeReadable($traffic_complete['mail'] * 1024, 'GiB', 'bi', '%01.' . (int) Settings::Get('panel.decimal_places') . 'f %s'); - eval("echo \"" . getTemplate('traffic/traffic') . "\";"); + 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 new file mode 100644 index 00000000..a5d25eac --- /dev/null +++ b/dns_editor.php @@ -0,0 +1,132 @@ + (2016-) + * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt + * @package Panel + * + */ + +use Froxlor\Api\Commands\DomainZones as DomainZones; + +// This file is being included in admin_domains and customer_domains +// and therefore does not need to require lib/init.php + +$domain_id = isset($_GET['domain_id']) ? (int) $_GET['domain_id'] : null; + +$record = isset($_POST['record']['record']) ? trim($_POST['record']['record']) : null; +$type = isset($_POST['record']['type']) ? $_POST['record']['type'] : 'A'; +$prio = isset($_POST['record']['prio']) ? (int) $_POST['record']['prio'] : null; +$content = isset($_POST['record']['content']) ? trim($_POST['record']['content']) : null; +$ttl = isset($_POST['record']['ttl']) ? (int) $_POST['record']['ttl'] : 18000; + +// get domain-name +$domain = \Froxlor\Dns\Dns::getAllowedDomainEntry($domain_id, AREA, $userinfo); + +$errors = ""; +$success_message = ""; + +// action for adding a new entry +if ($action == 'add_record' && ! empty($_POST)) { + try { + DomainZones::getLocal($userinfo, array( + 'id' => $domain_id, + 'record' => $record, + 'type' => $type, + 'prio' => $prio, + 'content' => $content, + 'ttl' => $ttl + ))->add(); + $success_message = $lng['success']['dns_record_added']; + $record = $prio = $content = ""; + } catch (Exception $e) { + $errors = str_replace("\n", "
", $e->getMessage()); + } +} elseif ($action == 'delete') { + // remove entry + $entry_id = isset($_GET['id']) ? (int) $_GET['id'] : 0; + if ($entry_id > 0) { + try { + DomainZones::getLocal($userinfo, array( + '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()); + } + } +} + +// 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 = ""; +$type_select = ""; +$entriescount = 0; + +if (! empty($dom_entries)) { + $entriescount = count($dom_entries); + foreach ($dom_entries as $entry) { + $entry['content'] = wordwrap($entry['content'], 100, '
', true); + eval("\$existing_entries.=\"" . \Froxlor\UI\Template::getTemplate("dns_editor/entry_bit", true) . "\";"); + } +} + +// available types +$type_select_values = array( + 'A', + 'AAAA', + 'CAA', + 'CNAME', + 'DNAME', + 'LOC', + 'MX', + 'NS', + 'RP', + 'SRV', + 'SSHFP', + 'TXT' +); +asort($type_select_values); +foreach ($type_select_values as $_type) { + $type_select .= \Froxlor\UI\HTML::makeoption($_type, $_type, $type); +} + +eval("\$record_list=\"" . \Froxlor\UI\Template::getTemplate("dns_editor/list", true) . "\";"); + +try { + $json_result = DomainZones::getLocal($userinfo, array( + 'id' => $domain_id + ))->get(); +} catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); +} +$result = json_decode($json_result, true)['data']; +$zonefile = implode("\n", $result); + +eval("echo \"" . \Froxlor\UI\Template::getTemplate("dns_editor/index", true) . "\";"); diff --git a/doc/example/FroxlorAPI.php b/doc/example/FroxlorAPI.php new file mode 100644 index 00000000..9b2ef050 --- /dev/null +++ b/doc/example/FroxlorAPI.php @@ -0,0 +1,213 @@ + (2018-) + * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt + * @package API-example + * @since 0.10.0 + * + */ +class FroxlorAPI +{ + + /** + * URL to api.php of your froxlor installation + * + * @var string + */ + private $host = ""; + + /** + * your api-key + * + * @var string + */ + private $api_key = ""; + + /** + * your api-secret + * + * @var string + */ + private $api_secret = ""; + + /** + * last cURL error message + * + * @var string + */ + private $last_error = ""; + + /** + * last response header received + * + * @var array + */ + private $last_header = array(); + + /** + * last response data received + * + * @var array + */ + private $last_body = array(); + + /** + * create FroxlorAPI object + * + * @param string $host + * URL to api.php of your froxlor installation + * @param string $api_key + * your api-key + * @param string $api_secret + * your api-secret + * + * @return FroxlorAPI + */ + public function __construct(string $host, string $api_key, string $api_secret) + { + $this->host = $host; + $this->api_key = $api_key; + $this->api_secret = $api_secret; + } + + /** + * send request to froxlor api + * + * @param string $command + * @param array $params + * + * @return FroxlorAPI + */ + public function request(string $command, array $params = array()): FroxlorAPI + { + // build request array + $request = [ + 'header' => [ + 'apikey' => $this->api_key, + 'secret' => $this->api_secret + ], + 'body' => [ + 'command' => $command + ] + ]; + + // add parameter to request-body if any + if (! empty($params)) { + $request['body']['params'] = $params; + } + + // reset last data + $this->last_header = array(); + $this->last_body = array(); + + // send actual request + $response = $this->requestCurl(json_encode($request)); + + // decode response + $resp = json_decode($response[1], true); + // set body to data-part of response + $this->last_body = $resp['data']; + // set header of response + $this->last_header = [ + 'status' => $resp['status'], + 'status_message' => $resp['status_message'] + ]; + + // check for error in api response + if (isset($this->last_header['status']) && $this->last_header['status'] >= 400) { + // set last-error message + $this->last_error .= "[" . $this->last_header['status'] . "] " . $this->last_header['status_message']; + } + + return $this; +} + + /** + * returns last response header + * + * @return array status|status_message + */ + public function getLastHeader(): array + { + return $this->last_header; + } + + /** + * returns last response data + * + * @return array + */ + public function getLastResponse(): array + { + if (!empty($this->getLastError())) { + // nothing is returned when the last call + // was not successful + return []; + } + return $this->last_body; + } + + /** + * return last known error message + * + * @return string + */ + public function getLastError(): string + { + return $this->last_error; + } + + /** + * send cURL request to api + * + * @param string $data + * json array + * + * @return array header|body + */ + private function requestCurl(string $data): array + { + // reset last error message + $this->last_error = ""; + + $ch = curl_init($this->host); + curl_setopt($ch, CURLOPT_POST, 1); + curl_setopt($ch, CURLOPT_POSTFIELDS, $data); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); + curl_setopt($ch, CURLOPT_HTTPHEADER, array( + 'Content-type: application/json' + )); + curl_setopt($ch, CURLOPT_POSTFIELDS, $data); + curl_setopt($ch, CURLOPT_VERBOSE, true); + curl_setopt($ch, CURLOPT_HEADER, 1); + $verbose = fopen('php://temp', 'w+'); + curl_setopt($ch, CURLOPT_STDERR, $verbose); + + if (! $data = curl_exec($ch)) { + $this->last_error = 'Curl execution error: ' . curl_error($ch) . "\n"; + rewind($verbose); + $verboseLog = stream_get_contents($verbose); + $this->last_error .= "Verbose information: " . htmlspecialchars($verboseLog) . "\n"; + } + + $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); + $header = substr($data, 0, $header_size); + $body = substr($data, $header_size); + + curl_close($ch); + return array( + $header, + $body + ); + } +} diff --git a/doc/example/create_customer.php b/doc/example/create_customer.php new file mode 100644 index 00000000..dcd11d3b --- /dev/null +++ b/doc/example/create_customer.php @@ -0,0 +1,48 @@ + 'test', + 'email' => 'test@froxlor.org', + 'firstname' => 'Test', + 'name' => 'Testman', + 'customernumber' => 1337, + 'new_customer_password' => 's0mEcRypt1cpassword' . uniqid() +]; +// send request +$fapi->request('Customers.add', $data); + +// check for error +if (! empty($fapi->getLastError())) { + echo "Error: " . $fapi->getLastError(); + exit(); +} + +// get response of request +$request = $fapi->getLastResponse(); + +// view response data +var_dump($request); + +/* +array(60) { + ["customerid"]=> + string(1) "1" + ["loginname"]=> + string(4) "test" + ["password"]=> + string(63) "$5$asdasdasd.asdasd" + ["adminid"]=> + string(1) "1" + ["name"]=> + string(7) "Testman" + ["firstname"]=> + string(4) "Test" + [...] +*/ \ No newline at end of file diff --git a/doc/example/list_functions.php b/doc/example/list_functions.php new file mode 100644 index 00000000..a691df7c --- /dev/null +++ b/doc/example/list_functions.php @@ -0,0 +1,22 @@ +request('Froxlor.listFunctions'); + +// check for error +if (! empty($fapi->getLastError())) { + echo "Error: " . $fapi->getLastError(); + exit(); +} + +// get response of request +$request = $fapi->getLastResponse(); + +// view response data +var_dump($request); diff --git a/index.php b/index.php index da6bba42..8f5b4c8b 100644 --- a/index.php +++ b/index.php @@ -16,23 +16,102 @@ * @package Panel * */ - define('AREA', 'login'); require './lib/init.php'; +use Froxlor\Database\Database; +use Froxlor\Settings; +use Froxlor\FroxlorLogger; + if ($action == '') { $action = 'login'; } -if ($action == 'login') { +if (session_status() == PHP_SESSION_NONE) { + session_start(); +} + +if ($action == '2fa_entercode') { + // page for entering the 2FA code after successful login + if (! isset($_SESSION) || ! isset($_SESSION['secret_2fa'])) { + // no session - redirect to index + \Froxlor\UI\Response::redirectTo('index.php'); + exit(); + } + // show template to enter code + eval("echo \"" . \Froxlor\UI\Template::getTemplate('2fa/entercode', true) . "\";"); +} elseif ($action == '2fa_verify') { + // verify code from 2fa code-enter form + if (! isset($_SESSION) || ! isset($_SESSION['secret_2fa'])) { + // no session - redirect to index + \Froxlor\UI\Response::redirectTo('index.php'); + exit(); + } + $code = isset($_POST['2fa_code']) ? $_POST['2fa_code'] : null; + // verify entered code + $tfa = new \Froxlor\FroxlorTwoFactorAuth('Froxlor'); + $result = ($_SESSION['secret_2fa'] == 'email' ? true : $tfa->verifyCode($_SESSION['secret_2fa'], $code, 3)); + // either the code is valid when using authenticator-app, or we will select userdata by id and entered code + // which is temporarily stored for the customer when using email-2fa + if ($result) { + // get user-data + $table = $_SESSION['uidtable_2fa']; + $field = $_SESSION['uidfield_2fa']; + $uid = $_SESSION['uid_2fa']; + $isadmin = $_SESSION['unfo_2fa']; + $sel_param = array( + 'uid' => $uid + ); + if ($_SESSION['secret_2fa'] == 'email') { + // verify code by selecting user by id and the temp. stored code, + // so only if it's the correct code, we get the user-data + $sel_stmt = Database::prepare("SELECT * FROM $table WHERE `" . $field . "` = :uid AND `data_2fa` = :code"); + $sel_param['code'] = $code; + } else { + // Authenticator-verification has already happened at this point, so just get the user-data + $sel_stmt = Database::prepare("SELECT * FROM $table WHERE `" . $field . "` = :uid"); + } + $userinfo = Database::pexecute_first($sel_stmt, $sel_param); + // whoops, no (valid) user? Start again + if (empty($userinfo)) { + \Froxlor\UI\Response::redirectTo('index.php', array( + 'showmessage' => '2' + )); + } + // set fields in $userinfo required for finishLogin() + $userinfo['adminsession'] = $isadmin; + $userinfo['userid'] = $uid; + + // if not successful somehow - start again + if (! finishLogin($userinfo)) { + \Froxlor\UI\Response::redirectTo('index.php', array( + 'showmessage' => '2' + )); + } + + // when using email-2fa, remove the one-time-code + if ($userinfo['type_2fa'] == '1') { + $del_stmt = Database::prepare("UPDATE $table SET `data_2fa` = '' WHERE `" . $field . "` = :uid"); + $userinfo = Database::pexecute_first($del_stmt, array( + 'uid' => $uid + )); + } + exit(); + } + \Froxlor\UI\Response::redirectTo('index.php', array( + 'showmessage' => '2' + )); + exit(); +} elseif ($action == 'login') { if (isset($_POST['send']) && $_POST['send'] == 'send') { - $loginname = validate($_POST['loginname'], 'loginname'); - $password = validate($_POST['password'], 'password'); + $loginname = \Froxlor\Validate\Validate::validate($_POST['loginname'], 'loginname'); + $password = \Froxlor\Validate\Validate::validate($_POST['password'], 'password'); $stmt = Database::prepare("SELECT `loginname` AS `customer` FROM `" . TABLE_PANEL_CUSTOMERS . "` - WHERE `loginname`= :loginname" - ); - Database::pexecute($stmt, array("loginname" => $loginname)); + WHERE `loginname`= :loginname"); + Database::pexecute($stmt, array( + "loginname" => $loginname + )); $row = $stmt->fetch(PDO::FETCH_ASSOC); if ($row['customer'] == $loginname) { @@ -42,21 +121,26 @@ if ($action == 'login') { $is_admin = false; } else { $is_admin = true; - if ((int)Settings::Get('login.domain_login') == 1) { - $domainname = $idna_convert->encode(preg_replace(array('/\:(\d)+$/', '/^https?\:\/\//'), '', $loginname)); + if ((int) Settings::Get('login.domain_login') == 1) { + $domainname = $idna_convert->encode(preg_replace(array( + '/\:(\d)+$/', + '/^https?\:\/\//' + ), '', $loginname)); $stmt = Database::prepare("SELECT `customerid` FROM `" . TABLE_PANEL_DOMAINS . "` - WHERE `domain` = :domain" - ); - Database::pexecute($stmt, array("domain" => $domainname)); + WHERE `domain` = :domain"); + Database::pexecute($stmt, array( + "domain" => $domainname + )); $row2 = $stmt->fetch(PDO::FETCH_ASSOC); if (isset($row2['customerid']) && $row2['customerid'] > 0) { - $loginname = getCustomerDetail($row2['customerid'], 'loginname'); + $loginname = \Froxlor\Customer\Customer::getCustomerDetail($row2['customerid'], 'loginname'); if ($loginname !== false) { $stmt = Database::prepare("SELECT `loginname` AS `customer` FROM `" . TABLE_PANEL_CUSTOMERS . "` - WHERE `loginname`= :loginname" - ); - Database::pexecute($stmt, array("loginname" => $loginname)); + WHERE `loginname`= :loginname"); + Database::pexecute($stmt, array( + "loginname" => $loginname + )); $row3 = $stmt->fetch(PDO::FETCH_ASSOC); if ($row3['customer'] == $loginname) { $table = "`" . TABLE_PANEL_CUSTOMERS . "`"; @@ -69,29 +153,31 @@ if ($action == 'login') { } } - if ((hasUpdates($version) || hasDbUpdates($dbversion)) && $is_admin == false) { - redirectTo('index.php'); - exit; + if ((\Froxlor\Froxlor::hasUpdates() || \Froxlor\Froxlor::hasDbUpdates()) && $is_admin == false) { + \Froxlor\UI\Response::redirectTo('index.php'); + exit(); } if ($is_admin) { - if (hasUpdates($version) || hasDbUpdates($dbversion)) { + if (\Froxlor\Froxlor::hasUpdates() || \Froxlor\Froxlor::hasDbUpdates()) { $stmt = Database::prepare("SELECT `loginname` AS `admin` FROM `" . TABLE_PANEL_ADMINS . "` WHERE `loginname`= :loginname - AND `change_serversettings` = '1'" - ); - Database::pexecute($stmt, array("loginname" => $loginname)); + AND `change_serversettings` = '1'"); + Database::pexecute($stmt, array( + "loginname" => $loginname + )); $row = $stmt->fetch(PDO::FETCH_ASSOC); - if (!isset($row['admin'])) { + if (! isset($row['admin'])) { // not an admin who can see updates - redirectTo('index.php'); - exit; + \Froxlor\UI\Response::redirectTo('index.php'); + exit(); } } else { $stmt = Database::prepare("SELECT `loginname` AS `admin` FROM `" . TABLE_PANEL_ADMINS . "` - WHERE `loginname`= :loginname" - ); - Database::pexecute($stmt, array("loginname" => $loginname)); + WHERE `loginname`= :loginname"); + Database::pexecute($stmt, array( + "loginname" => $loginname + )); $row = $stmt->fetch(PDO::FETCH_ASSOC); } @@ -101,211 +187,202 @@ if ($action == 'login') { $adminsession = '1'; } else { // Log failed login - $rstlog = FroxlorLogger::getInstanceOf(array('loginname' => $_SERVER['REMOTE_ADDR'])); - $rstlog->logAction(LOGIN_ACTION, LOG_WARNING, "Unknown user '" . $loginname . "' tried to login."); + $rstlog = FroxlorLogger::getInstanceOf(array( + 'loginname' => $_SERVER['REMOTE_ADDR'] + )); + $rstlog->logAction(\Froxlor\FroxlorLogger::LOGIN_ACTION, LOG_WARNING, "Unknown user '" . $loginname . "' tried to login."); - redirectTo('index.php', array('showmessage' => '2')); - exit; + \Froxlor\UI\Response::redirectTo('index.php', array( + 'showmessage' => '2' + )); + exit(); } } $userinfo_stmt = Database::prepare("SELECT * FROM $table - WHERE `loginname`= :loginname" - ); - Database::pexecute($userinfo_stmt, array("loginname" => $loginname)); + WHERE `loginname`= :loginname"); + Database::pexecute($userinfo_stmt, array( + "loginname" => $loginname + )); $userinfo = $userinfo_stmt->fetch(PDO::FETCH_ASSOC); if ($userinfo['loginfail_count'] >= Settings::Get('login.maxloginattempts') && $userinfo['lastlogin_fail'] > (time() - Settings::Get('login.deactivatetime'))) { - redirectTo('index.php', array('showmessage' => '3')); - exit; - } elseif (validatePasswordLogin($userinfo, $password, $table, $uid)) { - // only show "you're banned" if the login was successful - // because we don't want to publish that the user does exist - if ($userinfo['deactivated']) { - unset($userinfo); - redirectTo('index.php', array('showmessage' => '5')); - exit; - } else { - // login correct - // reset loginfail_counter, set lastlogin_succ - $stmt = Database::prepare("UPDATE $table + \Froxlor\UI\Response::redirectTo('index.php', array( + 'showmessage' => '3' + )); + exit(); + } elseif (\Froxlor\System\Crypt::validatePasswordLogin($userinfo, $password, $table, $uid)) { + // only show "you're banned" if the login was successful + // because we don't want to publish that the user does exist + if ($userinfo['deactivated']) { + unset($userinfo); + \Froxlor\UI\Response::redirectTo('index.php', array( + 'showmessage' => '5' + )); + exit(); + } else { + // login correct + // reset loginfail_counter, set lastlogin_succ + $stmt = Database::prepare("UPDATE $table SET `lastlogin_succ`= :lastlogin_succ, `loginfail_count`='0' - WHERE `$uid`= :uid" - ); - Database::pexecute($stmt, array("lastlogin_succ" => time(), "uid" => $userinfo[$uid])); - $userinfo['userid'] = $userinfo[$uid]; - $userinfo['adminsession'] = $adminsession; - } + WHERE `$uid`= :uid"); + Database::pexecute($stmt, array( + "lastlogin_succ" => time(), + "uid" => $userinfo[$uid] + )); + $userinfo['userid'] = $userinfo[$uid]; + $userinfo['adminsession'] = $adminsession; + } } else { // login incorrect $stmt = Database::prepare("UPDATE $table SET `lastlogin_fail`= :lastlogin_fail, `loginfail_count`=`loginfail_count`+1 - WHERE `$uid`= :uid" - ); - Database::pexecute($stmt, array("lastlogin_fail" => time(), "uid" => $userinfo[$uid])); + WHERE `$uid`= :uid"); + Database::pexecute($stmt, array( + "lastlogin_fail" => time(), + "uid" => $userinfo[$uid] + )); // Log failed login - $rstlog = FroxlorLogger::getInstanceOf(array('loginname' => $_SERVER['REMOTE_ADDR'])); - $rstlog->logAction(LOGIN_ACTION, LOG_WARNING, "User '" . $loginname . "' tried to login with wrong password."); + $rstlog = FroxlorLogger::getInstanceOf(array( + 'loginname' => $_SERVER['REMOTE_ADDR'] + )); + $rstlog->logAction(\Froxlor\FroxlorLogger::LOGIN_ACTION, LOG_WARNING, "User '" . $loginname . "' tried to login with wrong password."); unset($userinfo); - redirectTo('index.php', array('showmessage' => '2')); - exit; + \Froxlor\UI\Response::redirectTo('index.php', array( + 'showmessage' => '2' + )); + exit(); } - if (isset($userinfo['userid']) && $userinfo['userid'] != '') { - $s = md5(uniqid(microtime(), 1)); - - if (isset($_POST['language'])) { - $language = validate($_POST['language'], 'language'); - if ($language == 'profile') { - $language = $userinfo['def_language']; - } elseif (!isset($languages[$language])) { - $language = Settings::Get('panel.standardlanguage'); - } - } else { - $language = Settings::Get('panel.standardlanguage'); - } - - if (isset($userinfo['theme']) && $userinfo['theme'] != '') { - $theme = $userinfo['theme']; - } else { - $theme = Settings::Get('panel.default_theme'); - } - - if (Settings::Get('session.allow_multiple_login') != '1') { - $stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_SESSIONS . "` - WHERE `userid` = :uid - AND `adminsession` = :adminsession" + // 2FA activated + if (Settings::Get('2fa.enabled') == '1' && $userinfo['type_2fa'] > 0) { + // redirect to code-enter-page + $_SESSION['secret_2fa'] = ($userinfo['type_2fa'] == 2 ? $userinfo['data_2fa'] : 'email'); + $_SESSION['uid_2fa'] = $userinfo[$uid]; + $_SESSION['uidfield_2fa'] = $uid; + $_SESSION['uidtable_2fa'] = $table; + $_SESSION['unfo_2fa'] = $is_admin; + // send mail if type_2fa = 1 (email) + if ($userinfo['type_2fa'] == 1) { + // generate code + $tfa = new \Froxlor\FroxlorTwoFactorAuth('Froxlor'); + $code = $tfa->getCode($tfa->createSecret()); + // set code for user + $stmt = Database::prepare("UPDATE $table SET `data_2fa` = :d2fa WHERE `$uid` = :uid"); + Database::pexecute($stmt, array( + "d2fa" => $code, + "uid" => $userinfo[$uid] + )); + // build up & send email + $_mailerror = false; + $mailerr_msg = ""; + $replace_arr = array( + 'CODE' => $code ); - Database::pexecute($stmt, array("uid" => $userinfo['userid'], "adminsession" => $userinfo['adminsession'])); - } + $mail_body = html_entity_decode(\Froxlor\PhpHelper::replaceVariables($lng['mails']['2fa']['mailbody'], $replace_arr)); - // check for field 'theme' in session-table, refs #607 - // Changed with #1287 to new method - $theme_field = false; - $stmt = Database::query("SHOW COLUMNS FROM panel_sessions LIKE 'theme'"); - while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { - if ($row['Field'] == "theme") { - $has_theme = true; + try { + $mail->Subject = $lng['mails']['2fa']['subject']; + $mail->AltBody = $mail_body; + $mail->MsgHTML(str_replace("\n", "
", $mail_body)); + $mail->AddAddress($userinfo['email'], \Froxlor\User::getCorrectUserSalutation($userinfo)); + $mail->Send(); + } catch (\PHPMailer\PHPMailer\Exception $e) { + $mailerr_msg = $e->errorMessage(); + $_mailerror = true; + } catch (Exception $e) { + $mailerr_msg = $e->getMessage(); + $_mailerror = true; } - } - $params = array( - "hash" => $s, - "userid" => $userinfo['userid'], - "ipaddress" => $remote_addr, - "useragent" => $http_user_agent, - "lastactivity" => time(), - "language" => $language, - "adminsession" => $userinfo['adminsession'] - ); - - if ($has_theme) { - $params["theme"] = $theme; - $stmt = Database::prepare("INSERT INTO `" . TABLE_PANEL_SESSIONS . "` - (`hash`, `userid`, `ipaddress`, `useragent`, `lastactivity`, `language`, `adminsession`, `theme`) - VALUES (:hash, :userid, :ipaddress, :useragent, :lastactivity, :language, :adminsession, :theme)" - ); - } else { - $stmt = Database::prepare("INSERT INTO `" . TABLE_PANEL_SESSIONS . "` - (`hash`, `userid`, `ipaddress`, `useragent`, `lastactivity`, `language`, `adminsession`) - VALUES (:hash, :userid, :ipaddress, :useragent, :lastactivity, :language, :adminsession)" - ); - } - Database::pexecute($stmt, $params); - - $qryparams = array(); - if (isset($_POST['qrystr']) && $_POST['qrystr'] != "") { - parse_str(urldecode($_POST['qrystr']), $qryparams); - } - $qryparams['s'] = $s; - - if ($userinfo['adminsession'] == '1') { - if (hasUpdates($version) || hasDbUpdates($dbversion)) { - redirectTo('admin_updates.php', array('s' => $s)); - } else { - if (isset($_POST['script']) && $_POST['script'] != "") { - if (preg_match("/customer\_/", $_POST['script']) === 1) { - redirectTo('admin_customers.php', array("page" => "customers")); - } else { - redirectTo($_POST['script'], $qryparams); - } - } else { - redirectTo('admin_index.php', $qryparams); - } - } - } else { - if (isset($_POST['script']) && $_POST['script'] != "") { - redirectTo($_POST['script'], $qryparams); - } else { - redirectTo('customer_index.php', $qryparams); + if ($_mailerror) { + $rstlog = FroxlorLogger::getInstanceOf(array( + 'loginname' => '2fa code-sending' + )); + $rstlog->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_ERR, "Error sending mail: " . $mailerr_msg); + \Froxlor\UI\Response::redirectTo('index.php', array( + 'showmessage' => '4', + 'customermail' => $userinfo['email'] + )); + exit(); } + + $mail->ClearAddresses(); } - } else { - redirectTo('index.php', array('showmessage' => '2')); + \Froxlor\UI\Response::redirectTo('index.php', array( + 'action' => '2fa_entercode' + )); + exit(); } - exit; + + if (! finishLogin($userinfo)) { + \Froxlor\UI\Response::redirectTo('index.php', array( + 'showmessage' => '2' + )); + } + exit(); } else { $language_options = ''; - $language_options .= makeoption($lng['login']['profile_lng'], 'profile', 'profile', true, true); + $language_options .= \Froxlor\UI\HTML::makeoption($lng['login']['profile_lng'], 'profile', 'profile', true, true); - while (list($language_file, $language_name) = each($languages)) { - $language_options .= makeoption($language_name, $language_file, 'profile', true); + foreach ($languages as $language_file => $language_name) { + $language_options .= \Froxlor\UI\HTML::makeoption($language_name, $language_file, 'profile', true); } - $smessage = isset($_GET['showmessage']) ? (int)$_GET['showmessage'] : 0; + $smessage = isset($_GET['showmessage']) ? (int) $_GET['showmessage'] : 0; $message = ''; $successmessage = ''; switch ($smessage) { - case 1: - $successmessage = $lng['pwdreminder']['success']; - break; - case 2: - $message = $lng['error']['login']; - break; - case 3: - $message = sprintf($lng['error']['login_blocked'], Settings::Get('login.deactivatetime')); - break; - case 4: - $cmail = isset($_GET['customermail']) ? $_GET['customermail'] : 'unknown'; - $message = str_replace('%s', $cmail, $lng['error']['errorsendingmail']); - break; - case 5: - $message = $lng['error']['user_banned']; - break; - case 6: - $successmessage = $lng['pwdreminder']['changed']; - break; - case 7: - $message = $lng['pwdreminder']['wrongcode']; - break; - case 8: - $message = $lng['pwdreminder']['notallowed']; - break; + case 1: + $successmessage = $lng['pwdreminder']['success']; + break; + case 2: + $message = $lng['error']['login']; + break; + case 3: + $message = sprintf($lng['error']['login_blocked'], Settings::Get('login.deactivatetime')); + break; + case 4: + $cmail = isset($_GET['customermail']) ? $_GET['customermail'] : 'unknown'; + $message = str_replace('%s', $cmail, $lng['error']['errorsendingmail']); + break; + case 5: + $message = $lng['error']['user_banned']; + break; + case 6: + $successmessage = $lng['pwdreminder']['changed']; + break; + case 7: + $message = $lng['pwdreminder']['wrongcode']; + break; + case 8: + $message = $lng['pwdreminder']['notallowed']; + break; } $update_in_progress = ''; - if (hasUpdates($version) || hasDbUpdates($dbversion)) { + if (\Froxlor\Froxlor::hasUpdates() || \Froxlor\Froxlor::hasDbUpdates()) { $update_in_progress = $lng['update']['updateinprogress_onlyadmincanlogin']; } - + // Pass the last used page if needed $lastscript = ""; if (isset($_REQUEST['script']) && $_REQUEST['script'] != "") { $lastscript = $_REQUEST['script']; - if (!file_exists(__DIR__."/".$lastscript)) { + if (! file_exists(__DIR__ . "/" . $lastscript)) { $lastscript = ""; } } $lastqrystr = ""; if (isset($_REQUEST['qrystr']) && $_REQUEST['qrystr'] != "") { - $lastqrystr = strip_tags($_REQUEST['qrystr']); + $lastqrystr = htmlspecialchars($_REQUEST['qrystr'], ENT_QUOTES); } - eval("echo \"" . getTemplate('login') . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate('login') . "\";"); } } @@ -314,20 +391,24 @@ if ($action == 'forgotpwd') { $message = ''; if (isset($_POST['send']) && $_POST['send'] == 'send') { - $loginname = validate($_POST['loginname'], 'loginname'); - $email = validateEmail($_POST['loginemail'], 'email'); - $result_stmt = Database::prepare("SELECT `adminid`, `customerid`, `firstname`, `name`, `company`, `email`, `loginname`, `def_language`, `deactivated` FROM `" . TABLE_PANEL_CUSTOMERS . "` + $loginname = \Froxlor\Validate\Validate::validate($_POST['loginname'], 'loginname'); + $email = \Froxlor\Validate\Validate::validateEmail($_POST['loginemail'], 'email'); + $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("loginname" => $loginname, "email" => $email)); + AND `email`= :email"); + Database::pexecute($result_stmt, array( + "loginname" => $loginname, + "email" => $email + )); if (Database::num_rows() == 0) { $result_stmt = Database::prepare("SELECT `adminid`, `name`, `email`, `loginname`, `def_language`, `deactivated` FROM `" . TABLE_PANEL_ADMINS . "` WHERE `loginname`= :loginname - AND `email`= :email" - ); - Database::pexecute($result_stmt, array("loginname" => $loginname, "email" => $email)); + AND `email`= :email"); + Database::pexecute($result_stmt, array( + "loginname" => $loginname, + "email" => $email + )); if (Database::num_rows() > 0) { $adminchecked = true; @@ -341,23 +422,24 @@ if ($action == 'forgotpwd') { /* Check whether user is banned */ if ($user['deactivated']) { - redirectTo('index.php', array('showmessage' => '8')); - exit; + \Froxlor\UI\Response::redirectTo('index.php', array( + 'showmessage' => '8' + )); + exit(); } if (($adminchecked && Settings::Get('panel.allow_preset_admin') == '1') || $adminchecked == false) { if ($user !== false) { // build a activation code $timestamp = time(); - $first = substr(md5($user['loginname'] . $timestamp . randomStr(16)), 0, 15); - $third = substr(md5($user['email'] . $timestamp . randomStr(16)), -15); + $first = substr(md5($user['loginname'] . $timestamp . \Froxlor\PhpHelper::randomStr(16)), 0, 15); + $third = substr(md5($user['email'] . $timestamp . \Froxlor\PhpHelper::randomStr(16)), - 15); $activationcode = $first . $timestamp . $third . substr(md5($third . $timestamp), 0, 10); // Drop all existing activation codes for this user $stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_ACTIVATION . "` WHERE `userid` = :userid - AND `admin` = :admin" - ); + AND `admin` = :admin"); $params = array( "userid" => $adminchecked ? $user['adminid'] : $user['customerid'], "admin" => $adminchecked ? 1 : 0 @@ -367,8 +449,7 @@ if ($action == 'forgotpwd') { // Add new activation code to database $stmt = Database::prepare("INSERT INTO `" . TABLE_PANEL_ACTIVATION . "` (userid, admin, creation, activationcode) - VALUES (:userid, :admin, :creation, :activationcode)" - ); + VALUES (:userid, :admin, :creation, :activationcode)"); $params = array( "userid" => $adminchecked ? $user['adminid'] : $user['customerid'], "admin" => $adminchecked ? 1 : 0, @@ -377,11 +458,13 @@ if ($action == 'forgotpwd') { ); Database::pexecute($stmt, $params); - $rstlog = FroxlorLogger::getInstanceOf(array('loginname' => 'password_reset')); - $rstlog->logAction(USR_ACTION, LOG_WARNING, "User '" . $user['loginname'] . "' requested a link for setting a new password."); + $rstlog = FroxlorLogger::getInstanceOf(array( + 'loginname' => 'password_reset' + )); + $rstlog->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_WARNING, "User '" . $user['loginname'] . "' requested a link for setting a new password."); // Set together our activation link - $protocol = empty( $_SERVER['HTTPS'] ) ? 'http' : 'https'; + $protocol = empty($_SERVER['HTTPS']) ? 'http' : 'https'; // this can be a fixed value to avoid potential exploiting by modifying headers $host = Settings::Get('system.hostname'); // $_SERVER['HTTP_HOST']; $port = $_SERVER['SERVER_PORT'] != 80 ? ':' . $_SERVER['SERVER_PORT'] : ''; @@ -392,12 +475,16 @@ if ($action == 'forgotpwd') { // there can be only one script to handle this so we can use a fixed value here $script = "/index.php"; // $_SERVER['SCRIPT_NAME']; if (Settings::Get('system.froxlordirectlyviahostname') == 0) { - $script = makeCorrectFile("/".basename(__DIR__)."/".$script); + $script = \Froxlor\FileDir::makeCorrectFile("/" . basename(__DIR__) . "/" . $script); } $activationlink = $protocol . '://' . $host . $port . $script . '?action=resetpwd&resetcode=' . $activationcode; $replace_arr = array( - 'SALUTATION' => getCorrectUserSalutation($user), + 'SALUTATION' => \Froxlor\User::getCorrectUserSalutation($user), + 'NAME' => $user['name'], + 'FIRSTNAME' => $user['firstname'] ?? "", + 'COMPANY' => $user['company'] ?? "", + 'CUSTOMER_NO' => $user['customernumber'] ?? 0, 'USERNAME' => $loginname, 'LINK' => $activationlink ); @@ -407,30 +494,35 @@ if ($action == 'forgotpwd') { WHERE `adminid`= :adminid AND `language`= :lang AND `templategroup`=\'mails\' - AND `varname`=\'password_reset_subject\'' - ); - Database::pexecute($result_stmt, array("adminid" => $user['adminid'], "lang" => $def_language)); + AND `varname`=\'password_reset_subject\''); + Database::pexecute($result_stmt, array( + "adminid" => $user['adminid'], + "lang" => $def_language + )); $result = $result_stmt->fetch(PDO::FETCH_ASSOC); - $mail_subject = html_entity_decode(replace_variables((($result['value'] != '') ? $result['value'] : $lng['mails']['password_reset']['subject']), $replace_arr)); + $mail_subject = html_entity_decode(\Froxlor\PhpHelper::replaceVariables((($result['value'] != '') ? $result['value'] : $lng['mails']['password_reset']['subject']), $replace_arr)); $result_stmt = Database::prepare('SELECT `value` FROM `' . TABLE_PANEL_TEMPLATES . '` WHERE `adminid`= :adminid AND `language`= :lang AND `templategroup`=\'mails\' - AND `varname`=\'password_reset_mailbody\'' - ); - Database::pexecute($result_stmt, array("adminid" => $user['adminid'], "lang" => $def_language)); + AND `varname`=\'password_reset_mailbody\''); + Database::pexecute($result_stmt, array( + "adminid" => $user['adminid'], + "lang" => $def_language + )); $result = $result_stmt->fetch(PDO::FETCH_ASSOC); - $mail_body = html_entity_decode(replace_variables((($result['value'] != '') ? $result['value'] : $lng['mails']['password_reset']['mailbody']), $replace_arr)); + $mail_body = html_entity_decode(\Froxlor\PhpHelper::replaceVariables((($result['value'] != '') ? $result['value'] : $lng['mails']['password_reset']['mailbody']), $replace_arr)); $_mailerror = false; + $mailerr_msg = ""; try { $mail->Subject = $mail_subject; $mail->AltBody = $mail_body; $mail->MsgHTML(str_replace("\n", "
", $mail_body)); - $mail->AddAddress($user['email'], getCorrectUserSalutation($user)); + $mail->AddAddress($user['email'], \Froxlor\User::getCorrectUserSalutation($user)); $mail->Send(); - } catch(phpmailerException $e) { + } catch (\PHPMailer\PHPMailer\Exception $e) { $mailerr_msg = $e->errorMessage(); $_mailerror = true; } catch (Exception $e) { @@ -439,18 +531,27 @@ if ($action == 'forgotpwd') { } if ($_mailerror) { - $rstlog = FroxlorLogger::getInstanceOf(array('loginname' => 'password_reset')); - $rstlog->logAction(ADM_ACTION, LOG_ERR, "Error sending mail: " . $mailerr_msg); - redirectTo('index.php', array('showmessage' => '4', 'customermail' => $user['email'])); - exit; + $rstlog = FroxlorLogger::getInstanceOf(array( + 'loginname' => 'password_reset' + )); + $rstlog->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_ERR, "Error sending mail: " . $mailerr_msg); + \Froxlor\UI\Response::redirectTo('index.php', array( + 'showmessage' => '4', + 'customermail' => $user['email'] + )); + exit(); } $mail->ClearAddresses(); - redirectTo('index.php', array('showmessage' => '1')); - exit; + \Froxlor\UI\Response::redirectTo('index.php', array( + 'showmessage' => '1' + )); + exit(); } else { - $rstlog = FroxlorLogger::getInstanceOf(array('loginname' => 'password_reset')); - $rstlog->logAction(USR_ACTION, LOG_WARNING, "User '" . $loginname . "' requested to set a new password, but was not found in database!"); + $rstlog = FroxlorLogger::getInstanceOf(array( + 'loginname' => 'password_reset' + )); + $rstlog->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_WARNING, "User '" . $loginname . "' requested to set a new password, but was not found in database!"); $message = $lng['login']['combination_not_found']; } @@ -464,7 +565,7 @@ if ($action == 'forgotpwd') { if ($adminchecked) { if (Settings::Get('panel.allow_preset_admin') != '1') { $message = $lng['pwdreminder']['notallowed']; - unset ($adminchecked); + unset($adminchecked); } } else { if (Settings::Get('panel.allow_preset') != '1') { @@ -472,7 +573,7 @@ if ($action == 'forgotpwd') { } } - eval("echo \"" . getTemplate('fpwd') . "\";"); + eval("echo \"" . \Froxlor\UI\Template::getTemplate('fpwd') . "\";"); } if ($action == 'resetpwd') { @@ -480,9 +581,10 @@ if ($action == 'resetpwd') { // Remove old activation codes $stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_ACTIVATION . "` - WHERE creation < :oldest" - ); - Database::pexecute($stmt, array("oldest" => time() - 86400)); + WHERE creation < :oldest"); + Database::pexecute($stmt, array( + "oldest" => time() - 86400 + )); if (isset($_GET['resetcode']) && strlen($_GET['resetcode']) == 50) { // Check if activation code is valid @@ -494,63 +596,170 @@ if ($action == 'resetpwd') { if (substr(md5($third . $timestamp), 0, 10) == $check && $timestamp >= time() - 86400) { if (isset($_POST['send']) && $_POST['send'] == 'send') { $stmt = Database::prepare("SELECT `userid`, `admin` FROM `" . TABLE_PANEL_ACTIVATION . "` - WHERE `activationcode` = :activationcode" - ); - $result = Database::pexecute_first($stmt, array("activationcode" => $activationcode)); + WHERE `activationcode` = :activationcode"); + $result = Database::pexecute_first($stmt, array( + "activationcode" => $activationcode + )); if ($result !== false) { - if ($result['admin'] == 1) { - $new_password = validate($_POST['new_password'], 'new password'); - $new_password_confirm = validate($_POST['new_password_confirm'], 'new password confirm'); - } else { - $new_password = validatePassword($_POST['new_password'], 'new password'); - $new_password_confirm = 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 . "` SET `password` = :newpassword - WHERE `adminid` = :userid" - ); + WHERE `adminid` = :userid"); } else { $stmt = Database::prepare("UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET `password` = :newpassword - WHERE `customerid` = :userid" - ); + WHERE `customerid` = :userid"); } - Database::pexecute($stmt, array("newpassword" => makeCryptPassword($new_password), "userid" => $result['userid'])); + Database::pexecute($stmt, array( + "newpassword" => \Froxlor\System\Crypt::makeCryptPassword($new_password), + "userid" => $result['userid'] + )); - $rstlog = FroxlorLogger::getInstanceOf(array('loginname' => 'password_reset')); - $rstlog->logAction(USR_ACTION, LOG_NOTICE, "changed password using password reset."); + $rstlog = FroxlorLogger::getInstanceOf(array( + 'loginname' => 'password_reset' + )); + $rstlog->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "changed password using password reset."); // Remove activation code from DB $stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_ACTIVATION . "` WHERE `activationcode` = :activationcode - AND `userid` = :userid" - ); - Database::pexecute($stmt, array("activationcode" => $activationcode, "userid" => $result['userid'])); - redirectTo('index.php', array("showmessage" => '6')); + AND `userid` = :userid"); + Database::pexecute($stmt, array( + "activationcode" => $activationcode, + "userid" => $result['userid'] + )); + \Froxlor\UI\Response::redirectTo('index.php', array( + "showmessage" => '6' + )); } } else { - redirectTo('index.php', array("showmessage" => '7')); + \Froxlor\UI\Response::redirectTo('index.php', array( + "showmessage" => '7' + )); } } - eval("echo \"" . getTemplate('rpwd') . "\";"); - + eval("echo \"" . \Froxlor\UI\Template::getTemplate('rpwd') . "\";"); } else { - redirectTo('index.php', array("showmessage" => '7')); + \Froxlor\UI\Response::redirectTo('index.php', array( + "showmessage" => '7' + )); } - } else { - redirectTo('index.php'); + \Froxlor\UI\Response::redirectTo('index.php'); } } + +function finishLogin($userinfo) +{ + global $version, $dbversion, $remote_addr, $http_user_agent, $languages; + + if (isset($userinfo['userid']) && $userinfo['userid'] != '') { + $s = md5(uniqid(microtime(), 1)); + + if (isset($_POST['language'])) { + $language = \Froxlor\Validate\Validate::validate($_POST['language'], 'language'); + if ($language == 'profile') { + $language = $userinfo['def_language']; + } elseif (! isset($languages[$language])) { + $language = Settings::Get('panel.standardlanguage'); + } + } else { + $language = Settings::Get('panel.standardlanguage'); + } + + if (isset($userinfo['theme']) && $userinfo['theme'] != '') { + $theme = $userinfo['theme']; + } else { + $theme = Settings::Get('panel.default_theme'); + } + + if (Settings::Get('session.allow_multiple_login') != '1') { + $stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_SESSIONS . "` + WHERE `userid` = :uid + AND `adminsession` = :adminsession"); + Database::pexecute($stmt, array( + "uid" => $userinfo['userid'], + "adminsession" => $userinfo['adminsession'] + )); + } + + // check for field 'theme' in session-table, refs #607 + // Changed with #1287 to new method + $stmt = Database::query("SHOW COLUMNS FROM panel_sessions LIKE 'theme'"); + while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { + if ($row['Field'] == "theme") { + $has_theme = true; + } + } + + $params = array( + "hash" => $s, + "userid" => $userinfo['userid'], + "ipaddress" => $remote_addr, + "useragent" => $http_user_agent, + "lastactivity" => time(), + "language" => $language, + "adminsession" => $userinfo['adminsession'] + ); + + if ($has_theme) { + $params["theme"] = $theme; + $stmt = Database::prepare("INSERT INTO `" . TABLE_PANEL_SESSIONS . "` + (`hash`, `userid`, `ipaddress`, `useragent`, `lastactivity`, `language`, `adminsession`, `theme`) + VALUES (:hash, :userid, :ipaddress, :useragent, :lastactivity, :language, :adminsession, :theme)"); + } else { + $stmt = Database::prepare("INSERT INTO `" . TABLE_PANEL_SESSIONS . "` + (`hash`, `userid`, `ipaddress`, `useragent`, `lastactivity`, `language`, `adminsession`) + VALUES (:hash, :userid, :ipaddress, :useragent, :lastactivity, :language, :adminsession)"); + } + Database::pexecute($stmt, $params); + + $qryparams = array(); + if (isset($_POST['qrystr']) && $_POST['qrystr'] != "") { + parse_str(urldecode($_POST['qrystr']), $qryparams); + } + $qryparams['s'] = $s; + + if ($userinfo['adminsession'] == '1') { + if (\Froxlor\Froxlor::hasUpdates() || \Froxlor\Froxlor::hasDbUpdates()) { + \Froxlor\UI\Response::redirectTo('admin_updates.php', array( + 's' => $s + )); + } else { + if (isset($_POST['script']) && $_POST['script'] != "") { + if (preg_match("/customer\_/", $_POST['script']) === 1) { + \Froxlor\UI\Response::redirectTo('admin_customers.php', array( + "page" => "customers" + )); + } else { + \Froxlor\UI\Response::redirectTo($_POST['script'], $qryparams); + } + } else { + \Froxlor\UI\Response::redirectTo('admin_index.php', $qryparams); + } + } + } else { + if (isset($_POST['script']) && $_POST['script'] != "") { + \Froxlor\UI\Response::redirectTo($_POST['script'], $qryparams); + } else { + \Froxlor\UI\Response::redirectTo('customer_index.php', $qryparams); + } + } + } + return false; +} diff --git a/install/froxlor.sql b/install/froxlor.sql index fb16e4af..9426e3e6 100644 --- a/install/froxlor.sql +++ b/install/froxlor.sql @@ -8,22 +8,22 @@ CREATE TABLE `ftp_groups` ( PRIMARY KEY (`id`), UNIQUE KEY `groupname` (`groupname`), KEY `customerid` (`customerid`) -) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; +) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci; 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', `login_count` int(15) NOT NULL default '0', - `last_login` datetime NOT NULL default '0000-00-00 00:00:00', + `last_login` datetime default NULL, `up_count` int(15) NOT NULL default '0', `up_bytes` bigint(30) NOT NULL default '0', `down_count` int(15) NOT NULL default '0', @@ -33,7 +33,7 @@ CREATE TABLE `ftp_users` ( PRIMARY KEY (`id`), UNIQUE KEY `username` (`username`), KEY `customerid` (`customerid`) -) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; +) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci; @@ -57,7 +57,7 @@ CREATE TABLE `mail_users` ( `mboxsize` bigint(30) NOT NULL default '0', PRIMARY KEY (`id`), UNIQUE KEY `email` (`email`) -) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; +) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci; @@ -66,14 +66,14 @@ CREATE TABLE `mail_virtual` ( `id` int(11) NOT NULL auto_increment, `email` varchar(255) NOT NULL default '', `email_full` varchar(255) NOT NULL default '', - `destination` text NOT NULL, + `destination` text, `domainid` int(11) NOT NULL default '0', `customerid` int(11) NOT NULL default '0', `popaccountid` int(11) NOT NULL default '0', `iscatchall` tinyint(1) unsigned NOT NULL default '0', PRIMARY KEY (`id`), KEY `email` (`email`) -) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; +) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci; DROP TABLE IF EXISTS `panel_activation`; @@ -84,18 +84,18 @@ CREATE TABLE `panel_activation` ( `creation` int(11) unsigned NOT NULL default '0', `activationcode` varchar(50) default NULL, PRIMARY KEY (id) -) ENGINE=MyISAM 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(255) NOT NULL default '', - `ip` tinyint(4) NOT NULL default '-1', + `def_language` varchar(100) NOT NULL default '', + `ip` varchar(500) NOT NULL default '-1', `customers` int(15) NOT NULL default '0', `customers_used` int(15) NOT NULL default '0', `customers_see_all` tinyint(1) NOT NULL default '0', @@ -118,9 +118,6 @@ CREATE TABLE `panel_admins` ( `email_quota_used` bigint(13) NOT NULL default '0', `ftps` int(15) NOT NULL default '0', `ftps_used` int(15) NOT NULL default '0', - `tickets` int(15) NOT NULL default '-1', - `tickets_used` int(15) NOT NULL default '0', - `tickets_see_all` tinyint(1) NOT NULL default '0', `subdomains` int(15) NOT NULL default '0', `subdomains_used` int(15) NOT NULL default '0', `traffic` bigint(30) NOT NULL default '0', @@ -130,19 +127,22 @@ CREATE TABLE `panel_admins` ( `lastlogin_fail` int(11) unsigned NOT NULL default '0', `loginfail_count` int(11) unsigned NOT NULL default '0', `reportsent` tinyint(4) unsigned NOT NULL default '0', - `theme` varchar(255) NOT NULL default 'Sparkle', + `theme` varchar(50) NOT NULL default 'Sparkle', `custom_notes` text, `custom_notes_show` tinyint(1) NOT NULL default '0', + `type_2fa` tinyint(1) NOT NULL default '0', + `data_2fa` varchar(25) NOT NULL default '', + `api_allowed` tinyint(1) NOT NULL default '1', PRIMARY KEY (`adminid`), UNIQUE KEY `loginname` (`loginname`) -) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; +) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci; 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 '', @@ -150,13 +150,13 @@ CREATE TABLE `panel_customers` ( `gender` int(1) NOT NULL DEFAULT '0', `company` varchar(255) NOT NULL default '', `street` varchar(255) NOT NULL default '', - `zipcode` varchar(255) NOT NULL default '', + `zipcode` varchar(25) NOT NULL default '', `city` varchar(255) NOT NULL default '', - `phone` varchar(255) NOT NULL default '', - `fax` varchar(255) NOT NULL default '', + `phone` varchar(50) NOT NULL default '', + `fax` varchar(50) NOT NULL default '', `email` varchar(255) NOT NULL default '', `customernumber` varchar(255) NOT NULL default '', - `def_language` varchar(255) NOT NULL default '', + `def_language` varchar(100) NOT NULL default '', `diskspace` bigint(30) NOT NULL default '0', `diskspace_used` bigint(30) NOT NULL default '0', `mysqls` int(15) NOT NULL default '0', @@ -171,8 +171,6 @@ CREATE TABLE `panel_customers` ( `email_quota_used` bigint(13) NOT NULL default '0', `ftps` int(15) NOT NULL default '0', `ftps_used` int(15) NOT NULL default '0', - `tickets` int(15) NOT NULL default '0', - `tickets_used` int(15) NOT NULL default '0', `subdomains` int(15) NOT NULL default '0', `subdomains_used` int(15) NOT NULL default '0', `traffic` bigint(30) NOT NULL default '0', @@ -191,14 +189,21 @@ CREATE TABLE `panel_customers` ( `pop3` tinyint(1) NOT NULL default '1', `imap` tinyint(1) NOT NULL default '1', `perlenabled` tinyint(1) NOT NULL default '0', - `theme` varchar(255) NOT NULL default 'Sparkle', + `dnsenabled` tinyint(1) NOT NULL default '0', + `theme` varchar(50) NOT NULL default 'Sparkle', `custom_notes` text, `custom_notes_show` tinyint(1) NOT NULL default '0', - `lepublickey` mediumtext DEFAULT NULL, - `leprivatekey` mediumtext DEFAULT NULL, + `lepublickey` mediumtext default NULL, + `leprivatekey` mediumtext default NULL, + `leregistered` tinyint(1) NOT NULL default '0', + `allowed_phpconfigs` varchar(500) NOT NULL default '', + `type_2fa` tinyint(1) NOT NULL default '0', + `data_2fa` varchar(25) NOT NULL default '', + `api_allowed` tinyint(1) NOT NULL default '1', + `logviewenabled` tinyint(1) NOT NULL default '0', PRIMARY KEY (`customerid`), UNIQUE KEY `loginname` (`loginname`) -) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; +) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci; @@ -211,14 +216,15 @@ CREATE TABLE `panel_databases` ( `dbserver` int(11) unsigned NOT NULL default '0', PRIMARY KEY (`id`), KEY `customerid` (`customerid`) -) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; +) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci; 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, @@ -236,16 +242,19 @@ CREATE TABLE `panel_domains` ( `dkim_pubkey` text, `wwwserveralias` tinyint(1) NOT NULL default '1', `parentdomainid` int(11) NOT NULL default '0', + `phpenabled` tinyint(1) NOT NULL default '0', `openbasedir` tinyint(1) NOT NULL default '0', `openbasedir_path` tinyint(1) NOT NULL default '0', `speciallogfile` tinyint(1) NOT NULL default '0', `ssl_redirect` tinyint(4) NOT NULL default '0', `specialsettings` text, + `ssl_specialsettings` text, + `include_specialsettings` tinyint(1) NOT NULL default '0', `deactivated` tinyint(1) NOT NULL default '0', `bindserial` varchar(10) NOT NULL default '2000010100', `add_date` int( 11 ) NOT NULL default '0', - `registration_date` date NOT NULL, - `termination_date` date NOT NULL, + `registration_date` date DEFAULT NULL, + `termination_date` date DEFAULT NULL, `phpsettingid` INT( 11 ) UNSIGNED NOT NULL DEFAULT '1', `mod_fcgid_starter` int(4) default '-1', `mod_fcgid_maxrequests` int(4) default '-1', @@ -253,19 +262,31 @@ CREATE TABLE `panel_domains` ( `letsencrypt` tinyint(1) NOT NULL default '0', `hsts` varchar(10) NOT NULL default '0', `hsts_sub` tinyint(1) NOT NULL default '0', - `hsts_preload` tinyint(1) NOT NULL default '1', + `hsts_preload` tinyint(1) NOT NULL default '0', + `ocsp_stapling` tinyint(1) DEFAULT '0', + `http2` tinyint(1) DEFAULT '0', + `notryfiles` tinyint(1) DEFAULT '0', + `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_enabled` tinyint(1) DEFAULT '1', + `ssl_honorcipherorder` tinyint(1) DEFAULT '0', + `ssl_sessiontickets` tinyint(1) DEFAULT '1', PRIMARY KEY (`id`), KEY `customerid` (`customerid`), KEY `parentdomain` (`parentdomainid`), KEY `domain` (`domain`) -) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; +) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci; 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', @@ -273,14 +294,19 @@ CREATE TABLE `panel_ipsandports` ( `vhostcontainer_servername_statement` tinyint(1) NOT NULL default '0', `specialsettings` text, `ssl` tinyint(4) NOT NULL default '0', - `ssl_cert_file` varchar(255) NOT NULL, - `ssl_key_file` varchar(255) NOT NULL, - `ssl_ca_file` varchar(255) NOT NULL, + `ssl_cert_file` varchar(255) NOT NULL default '', + `ssl_key_file` varchar(255) NOT NULL default '', + `ssl_ca_file` varchar(255) NOT NULL default '', `default_vhostconf_domain` text, - `ssl_cert_chainfile` varchar(255) NOT NULL, + `ssl_cert_chainfile` varchar(255) NOT NULL default '', `docroot` varchar(255) NOT NULL default '', - PRIMARY KEY (`id`) -) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; + `ssl_specialsettings` text, + `include_specialsettings` tinyint(1) NOT NULL default '0', + `ssl_default_vhostconf_domain` text, + `include_default_vhostconf_domain` tinyint(1) NOT NULL default '0', + PRIMARY KEY (`id`), + UNIQUE KEY `ip_port` (`ip`,`port`) +) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci; @@ -296,7 +322,7 @@ CREATE TABLE `panel_htaccess` ( `error401path` varchar(255) NOT NULL default '', `options_cgi` tinyint(1) NOT NULL default '0', PRIMARY KEY (`id`) -) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; +) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci; @@ -310,7 +336,7 @@ CREATE TABLE `panel_htpasswds` ( `authname` varchar(255) NOT NULL default 'Restricted Area', PRIMARY KEY (`id`), KEY `customerid` (`customerid`) -) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; +) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci; @@ -339,7 +365,7 @@ CREATE TABLE `panel_settings` ( `varname` varchar(255) NOT NULL default '', `value` text NOT NULL, PRIMARY KEY (`settingid`) -) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; +) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci; INSERT INTO `panel_settings` (`settinggroup`, `varname`, `value`) VALUES ('catchall', 'catchall_enabled', '1'), @@ -351,17 +377,6 @@ INSERT INTO `panel_settings` (`settinggroup`, `varname`, `value`) VALUES ('customer', 'ftpatdomain', '0'), ('customer', 'show_news_feed', '0'), ('customer', 'news_feed_url', ''), - ('ticket', 'noreply_email', 'NO-REPLY@SERVERNAME'), - ('ticket', 'worktime_all', '1'), - ('ticket', 'worktime_begin', '00:00'), - ('ticket', 'worktime_end', '23:59'), - ('ticket', 'worktime_sat', '0'), - ('ticket', 'worktime_sun', '0'), - ('ticket', 'archiving_days', '5'), - ('ticket', 'enabled', '1'), - ('ticket', 'concurrently_open', '5'), - ('ticket', 'noreply_name', 'Hosting Support'), - ('ticket', 'reset_cycle', '2'), ('logger', 'enabled', '1'), ('logger', 'log_cron', '0'), ('logger', 'logfile', ''), @@ -375,20 +390,18 @@ INSERT INTO `panel_settings` (`settinggroup`, `varname`, `value`) VALUES ('admin', 'show_news_feed', '0'), ('admin', 'show_version_login', '0'), ('admin', 'show_version_footer', '0'), + ('caa', 'caa_entry', ''), ('spf', 'use_spf', '0'), - ('spf', 'spf_entry', '@ IN TXT "v=spf1 a mx -all"'), + ('spf', 'spf_entry', '"v=spf1 a mx -all"'), ('dkim', 'dkim_algorithm', 'all'), - ('dkim', 'dkim_add_adsp', '1'), ('dkim', 'dkim_keylength', '1024'), ('dkim', 'dkim_servicetype', '0'), - ('dkim', 'dkim_add_adsppolicy', '1'), ('dkim', 'dkim_notes', ''), ('defaultwebsrverrhandler', 'enabled', '0'), ('defaultwebsrverrhandler', 'err401', ''), ('defaultwebsrverrhandler', 'err403', ''), ('defaultwebsrverrhandler', 'err404', ''), ('defaultwebsrverrhandler', 'err500', ''), - ('ticket', 'default_priority', '2'), ('customredirect', 'enabled', '1'), ('customredirect', 'default', '1'), ('perl', 'suexecworkaround', '0'), @@ -397,25 +410,113 @@ INSERT INTO `panel_settings` (`settinggroup`, `varname`, `value`) VALUES ('login', 'maxloginattempts', '3'), ('login', 'deactivatetime', '900'), ('phpfpm', 'enabled', '0'), - ('phpfpm', 'configdir', '/etc/php-fpm.d/'), - ('phpfpm', 'reload', '/etc/init.d/php-fpm restart'), - ('phpfpm', 'pm', 'static'), - ('phpfpm', 'max_children', '1'), - ('phpfpm', 'start_servers', '20'), - ('phpfpm', 'min_spare_servers', '5'), - ('phpfpm', 'max_spare_servers', '35'), - ('phpfpm', 'max_requests', '0'), ('phpfpm', 'tmpdir', '/var/customers/tmp/'), ('phpfpm', 'peardir', '/usr/share/php/:/usr/share/php5/'), + ('phpfpm', 'envpath', '/usr/local/bin:/usr/bin:/bin'), ('phpfpm', 'enabled_ownvhost', '0'), ('phpfpm', 'vhost_httpuser', 'froxlorlocal'), ('phpfpm', 'vhost_httpgroup', 'froxlorlocal'), - ('phpfpm', 'idle_timeout', '30'), ('phpfpm', 'aliasconfigdir', '/var/www/php-fpm/'), ('phpfpm', 'defaultini', '1'), ('phpfpm', 'vhost_defaultini', '2'), ('phpfpm', 'fastcgi_ipcdir', '/var/lib/apache2/fastcgi/'), - ('phpfpm', 'use_mod_proxy', '0'), + ('phpfpm', 'use_mod_proxy', '1'), + ('phpfpm', 'ini_flags', 'asp_tags +display_errors +display_startup_errors +html_errors +log_errors +magic_quotes_gpc +magic_quotes_runtime +magic_quotes_sybase +mail.add_x_header +session.cookie_secure +session.use_cookies +short_open_tag +track_errors +xmlrpc_errors +suhosin.simulation +suhosin.session.encrypt +suhosin.session.cryptua +suhosin.session.cryptdocroot +suhosin.cookie.encrypt +suhosin.cookie.cryptua +suhosin.cookie.cryptdocroot +suhosin.executor.disable_eval +mbstring.func_overload'), + ('phpfpm', 'ini_values', 'auto_append_file +auto_prepend_file +date.timezone +default_charset +error_reporting +include_path +log_errors_max_len +mail.log +max_execution_time +session.cookie_domain +session.cookie_lifetime +session.cookie_path +session.name +session.serialize_handler +upload_max_filesize +xmlrpc_error_number +session.auto_start +always_populate_raw_post_data +suhosin.session.cryptkey +suhosin.session.cryptraddr +suhosin.session.checkraddr +suhosin.cookie.cryptkey +suhosin.cookie.plainlist +suhosin.cookie.cryptraddr +suhosin.cookie.checkraddr +suhosin.executor.func.blacklist +suhosin.executor.eval.whitelist'), + ('phpfpm', 'ini_admin_flags', 'allow_call_time_pass_reference +allow_url_fopen +allow_url_include +auto_detect_line_endings +cgi.fix_pathinfo +cgi.force_redirect +enable_dl +expose_php +file_uploads +ignore_repeated_errors +ignore_repeated_source +log_errors +register_argc_argv +report_memleaks +opcache.enable +opcache.consistency_checks +opcache.dups_fix +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 +disable_classes +disable_functions +error_log +gpc_order +max_input_time +max_input_vars +memory_limit +open_basedir +output_buffering +post_max_size +precision +sendmail_path +session.gc_divisor +session.gc_probability +variables_order +opcache.log_verbosity_level +opcache.restrict_api +opcache.revalidate_freq +opcache.max_accelerated_files +opcache.memory_consumption +opcache.interned_strings_buffer'), ('nginx', 'fastcgiparams', '/etc/nginx/fastcgi_params'), ('system', 'lastaccountnumber', '0'), ('system', 'lastguid', '9999'), @@ -435,9 +536,10 @@ INSERT INTO `panel_settings` (`settinggroup`, `varname`, `value`) VALUES ('system', 'mysql_access_host', 'localhost'), ('system', 'lastcronrun', ''), ('system', 'defaultip', '1'), + ('system', 'defaultsslip', ''), ('system', 'phpappendopenbasedir', '/tmp/'), ('system', 'deactivateddocroot', ''), - ('system', 'mailpwcleartext', '1'), + ('system', 'mailpwcleartext', '0'), ('system', 'last_tasks_run', '000000'), ('system', 'nameservers', ''), ('system', 'mxservers', ''), @@ -452,6 +554,7 @@ INSERT INTO `panel_settings` (`settinggroup`, `varname`, `value`) VALUES ('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'), @@ -471,10 +574,12 @@ INSERT INTO `panel_settings` (`settinggroup`, `varname`, `value`) VALUES ('system', 'stdsubdomain', ''), ('system', 'awstats_path', '/usr/bin/'), ('system', 'awstats_conf', '/etc/awstats/'), + ('system', 'awstats_logformat', '1'), ('system', 'defaultttl', '604800'), ('system', 'mod_fcgid_defaultini', '1'), ('system', 'ftpserver', 'proftpd'), ('system', 'dns_createmailentry', '0'), + ('system', 'dns_createcaaentry', '1'), ('system', 'froxlordirectlyviahostname', '0'), ('system', 'report_enable', '1'), ('system', 'report_webmax', '90'), @@ -495,9 +600,11 @@ INSERT INTO `panel_settings` (`settinggroup`, `varname`, `value`) VALUES ('system', 'ssl_cert_chainfile', ''), ('system', 'ssl_cipher_list', 'ECDH+AESGCM:ECDH+AES256:!aNULL:!MD5:!DSS:!DH:!AES128'), ('system', 'nginx_php_backend', '127.0.0.1:8888'), + ('system', 'http2_support', '0'), ('system', 'perl_server', 'unix:/var/run/nginx/cgiwrap-dispatch.sock'), ('system', 'phpreload_command', ''), - ('system', 'apache24', '0'), + ('system', 'apache24', '1'), + ('system', 'apache24_ocsp_cache_path', 'shmcb:/var/run/apache2/ocsp-stapling.cache(131072)'), ('system', 'documentroot_use_default_value', '0'), ('system', 'passwordcryptfunc', '3'), ('system', 'axfrservers', ''), @@ -520,11 +627,53 @@ INSERT INTO `panel_settings` (`settinggroup`, `varname`, `value`) VALUES ('system', 'lepublickey', 'unset'), ('system', 'letsencryptca', 'production'), ('system', 'letsencryptcountrycode', 'DE'), - ('system', 'letsencryptstate', 'Germany'), + ('system', 'letsencryptstate', 'Hessen'), ('system', 'letsencryptchallengepath', '/var/www/froxlor'), ('system', 'letsencryptkeysize', '4096'), ('system', 'letsencryptreuseold', 0), ('system', 'leenabled', '0'), + ('system', 'leapiversion', '2'), + ('system', 'backupenabled', '0'), + ('system', 'dnsenabled', '0'), + ('system', 'dns_server', 'Bind'), + ('system', 'apacheglobaldiropt', ''), + ('system', 'allow_customer_shell', '0'), + ('system', 'available_shells', ''), + ('system', 'le_froxlor_enabled', '0'), + ('system', 'le_froxlor_redirect', '0'), + ('system', 'letsencryptacmeconf', '/etc/apache2/conf-enabled/acme.conf'), + ('system', 'mail_use_smtp', '0'), + ('system', 'mail_smtp_host', 'localhost'), + ('system', 'mail_smtp_port', '25'), + ('system', 'mail_smtp_usetls', '1'), + ('system', 'mail_smtp_auth', '1'), + ('system', 'mail_smtp_user', ''), + ('system', 'mail_smtp_passwd', ''), + ('system', 'hsts_maxage', '0'), + ('system', 'hsts_incsub', '0'), + ('system', 'hsts_preload', '0'), + ('system', 'leregistered', '0'), + ('system', 'leaccount', ''), + ('system', 'nssextrausers', '0'), + ('system', 'le_domain_dnscheck', '1'), + ('system', 'ssl_protocols', 'TLSv1.2'), + ('system', 'tlsv13_cipher_list', ''), + ('system', 'honorcipherorder', '0'), + ('system', 'sessiontickets', '1'), + ('system', 'sessionticketsenabled', '1'), + ('system', 'logfiles_format', ''), + ('system', 'logfiles_type', '1'), + ('system', 'logfiles_piped', '0'), + ('system', 'logfiles_script', ''), + ('system', 'dhparams_file', ''), + ('system', 'errorlog_level', 'warn'), + ('system', 'leecc', '0'), + ('system', 'froxloraliases', ''), + ('system', 'apply_specialsettings_default', '1'), + ('system', 'apply_phpconfigs_default', '1'), + ('system', 'hide_incompatible_settings', '0'), + ('api', 'enabled', '0'), + ('2fa', 'enabled', '1'), ('panel', 'decimal_places', '4'), ('panel', 'adminmail', 'admin@SERVERNAME'), ('panel', 'phpmyadmin_url', ''), @@ -555,17 +704,19 @@ INSERT INTO `panel_settings` (`settinggroup`, `varname`, `value`) VALUES ('panel', 'password_numeric', '0'), ('panel', 'password_special_char_required', '0'), ('panel', 'password_special_char', '!?<>§$%+#=@'), - ('panel', 'version', '0.9.35-rc1'), - ('panel', 'db_version', '201603150'); + ('panel', 'customer_hide_options', ''), + ('panel', 'is_configured', '0'), + ('panel', 'version', '0.10.23.1'), + ('panel', 'db_version', '202012300'); DROP TABLE IF EXISTS `panel_tasks`; CREATE TABLE `panel_tasks` ( `id` int(11) unsigned NOT NULL auto_increment, `type` int(11) NOT NULL default '0', - `data` text NOT NULL, + `data` text, PRIMARY KEY (`id`) -) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; +) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci; INSERT INTO `panel_tasks` (`type`) VALUES ('99'); @@ -580,7 +731,7 @@ CREATE TABLE `panel_templates` ( `value` longtext NOT NULL, PRIMARY KEY (id), KEY adminid (adminid) -) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; +) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci; @@ -598,7 +749,7 @@ CREATE TABLE `panel_traffic` ( `mail` bigint(30) unsigned NOT NULL default '0', PRIMARY KEY (`id`), KEY `customerid` (`customerid`) -) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; +) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci; @@ -616,7 +767,7 @@ CREATE TABLE `panel_traffic_admins` ( `mail` bigint(30) unsigned NOT NULL default '0', PRIMARY KEY (`id`), KEY `adminid` (`adminid`) -) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; +) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci; @@ -633,24 +784,7 @@ CREATE TABLE `panel_diskspace` ( `mysql` bigint(30) unsigned NOT NULL default '0', PRIMARY KEY (`id`), KEY `customerid` (`customerid`) -) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; - - - -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=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; +) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci; @@ -661,7 +795,7 @@ CREATE TABLE `panel_languages` ( `iso` char(3) NOT NULL DEFAULT 'foo', `file` varchar(255) NOT NULL DEFAULT '', PRIMARY KEY (`id`) -) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; +) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci; @@ -675,41 +809,6 @@ INSERT INTO `panel_languages` (`id`, `language`, `iso`, `file`) VALUES (7, 'Svenska', 'sv', 'lng/swedish.lng.php'); - -DROP TABLE IF EXISTS `panel_tickets`; -CREATE TABLE `panel_tickets` ( - `id` int(11) unsigned NOT NULL auto_increment, - `customerid` int(11) NOT NULL, - `adminid` int(11) NOT NULL, - `category` smallint(5) unsigned NOT NULL default '1', - `priority` enum('1','2','3') NOT NULL default '3', - `subject` varchar(70) NOT NULL, - `message` text NOT NULL, - `dt` int(15) NOT NULL, - `lastchange` int(15) NOT NULL, - `ip` varchar(39) NOT NULL default '', - `status` enum('0','1','2','3') NOT NULL default '1', - `lastreplier` enum('0','1') NOT NULL default '0', - `answerto` int(11) unsigned NOT NULL, - `by` enum('0','1') NOT NULL default '0', - `archived` enum('0','1') NOT NULL default '0', - PRIMARY KEY (`id`), - KEY `customerid` (`customerid`) -) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; - - - -DROP TABLE IF EXISTS `panel_ticket_categories`; -CREATE TABLE `panel_ticket_categories` ( - `id` smallint(5) unsigned NOT NULL auto_increment, - `name` varchar(60) NOT NULL, - `adminid` int(11) NOT NULL, - `logicalorder` int(3) NOT NULL default '1', - PRIMARY KEY (`id`) -) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; - - - DROP TABLE IF EXISTS `panel_syslog`; CREATE TABLE IF NOT EXISTS `panel_syslog` ( `logid` bigint(20) NOT NULL auto_increment, @@ -719,7 +818,35 @@ CREATE TABLE IF NOT EXISTS `panel_syslog` ( `user` varchar(50) NOT NULL, `text` text NOT NULL, PRIMARY KEY (`logid`) -) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; +) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci; + + + +DROP TABLE IF EXISTS `panel_fpmdaemons`; +CREATE TABLE `panel_fpmdaemons` ( + `id` int(11) unsigned NOT NULL auto_increment, + `description` varchar(50) NOT NULL, + `reload_cmd` varchar(255) NOT NULL, + `config_dir` varchar(255) NOT NULL, + `pm` varchar(15) NOT NULL DEFAULT 'dynamic', + `max_children` int(4) NOT NULL DEFAULT '5', + `start_servers` int(4) NOT NULL DEFAULT '2', + `min_spare_servers` int(4) NOT NULL DEFAULT '1', + `max_spare_servers` int(4) NOT NULL DEFAULT '3', + `max_requests` int(4) NOT NULL DEFAULT '0', + `idle_timeout` int(4) NOT NULL DEFAULT '10', + `limit_extensions` varchar(255) NOT NULL default '.php', + `custom_config` text, + PRIMARY KEY (`id`), + UNIQUE KEY `reload` (`reload_cmd`), + UNIQUE KEY `config` (`config_dir`) +) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci; + + + +INSERT INTO `panel_fpmdaemons` (`id`, `description`, `reload_cmd`, `config_dir`) VALUES +(1, 'System default', 'service php7.3-fpm restart', '/etc/php/7.3/fpm/pool.d/'); + DROP TABLE IF EXISTS `panel_phpconfigs`; @@ -735,14 +862,26 @@ CREATE TABLE `panel_phpconfigs` ( `fpm_reqterm` varchar(15) NOT NULL default '60s', `fpm_reqslow` varchar(15) NOT NULL default '5s', `phpsettings` text NOT NULL, - PRIMARY KEY (`id`) -) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; + `fpmsettingid` int(11) NOT NULL DEFAULT '1', + `pass_authorizationheader` tinyint(1) NOT NULL default '0', + `override_fpmconfig` tinyint(1) NOT NULL DEFAULT '0', + `pm` varchar(15) NOT NULL DEFAULT 'dynamic', + `max_children` int(4) NOT NULL DEFAULT '5', + `start_servers` int(4) NOT NULL DEFAULT '2', + `min_spare_servers` int(4) NOT NULL DEFAULT '1', + `max_spare_servers` int(4) NOT NULL DEFAULT '3', + `max_requests` int(4) NOT NULL DEFAULT '0', + `idle_timeout` int(4) NOT NULL DEFAULT '10', + `limit_extensions` varchar(255) NOT NULL default '.php', + PRIMARY KEY (`id`), + KEY `fpmsettingid` (`fpmsettingid`) +) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci; INSERT INTO `panel_phpconfigs` (`id`, `description`, `binary`, `file_extensions`, `mod_fcgid_starter`, `mod_fcgid_maxrequests`, `phpsettings`) VALUES -(1, 'Default Config', '/usr/bin/php-cgi', 'php', '-1', '-1', 'allow_call_time_pass_reference = Off\r\nallow_url_fopen = Off\r\nasp_tags = Off\r\ndisable_classes =\r\ndisable_functions = curl_exec,curl_multi_exec,exec,parse_ini_file,passthru,popen,proc_close,proc_get_status,proc_nice,proc_open,proc_terminate,shell_exec,show_source,system\r\ndisplay_errors = Off\r\ndisplay_startup_errors = Off\r\nenable_dl = Off\r\nerror_reporting = E_ALL & ~E_NOTICE\r\nexpose_php = Off\r\nfile_uploads = On\r\ncgi.force_redirect = 1\r\ngpc_order = "GPC"\r\nhtml_errors = Off\r\nignore_repeated_errors = Off\r\nignore_repeated_source = Off\r\ninclude_path = ".:{PEAR_DIR}"\r\nlog_errors = On\r\nlog_errors_max_len = 1024\r\nmagic_quotes_gpc = Off\r\nmagic_quotes_runtime = Off\r\nmagic_quotes_sybase = Off\r\nmax_execution_time = 30\r\nmax_input_time = 60\r\nmemory_limit = 128M\r\n{OPEN_BASEDIR_C}open_basedir = "{OPEN_BASEDIR}"\r\noutput_buffering = 4096\r\npost_max_size = 16M\r\nprecision = 14\r\nregister_argc_argv = Off\r\nregister_globals = Off\r\nreport_memleaks = On\r\nsendmail_path = "/usr/sbin/sendmail -t -i -f {CUSTOMER_EMAIL}"\r\nsession.auto_start = 0\r\nsession.bug_compat_42 = 0\r\nsession.bug_compat_warn = 1\r\nsession.cache_expire = 180\r\nsession.cache_limiter = nocache\r\nsession.cookie_domain =\r\nsession.cookie_lifetime = 0\r\nsession.cookie_path = /\r\nsession.entropy_file = /dev/urandom\r\nsession.entropy_length = 16\r\nsession.gc_divisor = 1000\r\nsession.gc_maxlifetime = 1440\r\nsession.gc_probability = 1\r\nsession.name = PHPSESSID\r\nsession.referer_check =\r\nsession.save_handler = files\r\nsession.save_path = "{TMP_DIR}"\r\nsession.serialize_handler = php\r\nsession.use_cookies = 1\r\nsession.use_trans_sid = 0\r\nshort_open_tag = On\r\nsuhosin.mail.protect = 1\r\nsuhosin.simulation = Off\r\ntrack_errors = Off\r\nupload_max_filesize = 32M\r\nupload_tmp_dir = "{TMP_DIR}"\r\nvariables_order = "GPCS"\r\n;mail.add_x_header = On\r\n;mail.log = "/var/log/phpmail.log"\r\nopcache.restrict_api = "{DOCUMENT_ROOT}"\r\n'), -(2, 'Froxlor Vhost Config', '/usr/bin/php-cgi', 'php', '-1', '-1', 'allow_call_time_pass_reference = Off\r\nallow_url_fopen = On\r\nasp_tags = Off\r\ndisable_classes =\r\ndisable_functions = curl_multi_exec,exec,parse_ini_file,passthru,popen,proc_close,proc_get_status,proc_nice,proc_open,proc_terminate,shell_exec,show_source,system\r\ndisplay_errors = Off\r\ndisplay_startup_errors = Off\r\nenable_dl = Off\r\nerror_reporting = E_ALL & ~E_NOTICE\r\nexpose_php = Off\r\nfile_uploads = On\r\ncgi.force_redirect = 1\r\ngpc_order = "GPC"\r\nhtml_errors = Off\r\nignore_repeated_errors = Off\r\nignore_repeated_source = Off\r\ninclude_path = ".:{PEAR_DIR}"\r\nlog_errors = On\r\nlog_errors_max_len = 1024\r\nmagic_quotes_gpc = Off\r\nmagic_quotes_runtime = Off\r\nmagic_quotes_sybase = Off\r\nmax_execution_time = 60\r\nmax_input_time = 60\r\nmemory_limit = 128M\r\nnoutput_buffering = 4096\r\npost_max_size = 16M\r\nprecision = 14\r\nregister_argc_argv = Off\r\nregister_globals = Off\r\nreport_memleaks = On\r\nsendmail_path = "/usr/sbin/sendmail -t -i -f {CUSTOMER_EMAIL}"\r\nsession.auto_start = 0\r\nsession.bug_compat_42 = 0\r\nsession.bug_compat_warn = 1\r\nsession.cache_expire = 180\r\nsession.cache_limiter = nocache\r\nsession.cookie_domain =\r\nsession.cookie_lifetime = 0\r\nsession.cookie_path = /\r\nsession.entropy_file = /dev/urandom\r\nsession.entropy_length = 16\r\nsession.gc_divisor = 1000\r\nsession.gc_maxlifetime = 1440\r\nsession.gc_probability = 1\r\nsession.name = PHPSESSID\r\nsession.referer_check =\r\nsession.save_handler = files\r\nsession.save_path = "{TMP_DIR}"\r\nsession.serialize_handler = php\r\nsession.use_cookies = 1\r\nsession.use_trans_sid = 0\r\nshort_open_tag = On\r\nsuhosin.mail.protect = 1\r\nsuhosin.simulation = Off\r\ntrack_errors = Off\r\nupload_max_filesize = 32M\r\nupload_tmp_dir = "{TMP_DIR}"\r\nvariables_order = "GPCS"\r\n;mail.add_x_header = On\r\n;mail.log = "/var/log/phpmail.log"\r\nopcache.restrict_api = ""\r\n'); +(1, 'Default Config', '/usr/bin/php-cgi', 'php', '-1', '-1', 'allow_url_fopen = Off\r\nallow_url_include = Off\r\nauto_append_file =\r\nauto_globals_jit = On\r\nauto_prepend_file =\r\nbcmath.scale = 0\r\ncli_server.color = On\r\ndefault_charset = "UTF-8"\r\ndefault_mimetype = "text/html"\r\ndefault_socket_timeout = 60\r\nasp_tags = Off\r\ndisable_functions = pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,curl_exec,curl_multi_exec,exec,parse_ini_file,passthru,popen,proc_close,proc_get_status,proc_nice,proc_open,proc_terminate,shell_exec,show_source,system\r\ndisplay_errors = Off\r\ndisplay_startup_errors = Off\r\ndoc_root =\r\nenable_dl = Off\r\nerror_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT & ~E_NOTICE\r\nexpose_php = Off\r\nfile_uploads = On\r\nhtml_errors = On\r\nignore_repeated_errors = Off\r\nignore_repeated_source = Off\r\ninclude_path = ".:{PEAR_DIR}"\r\nimplicit_flush = Off\r\nldap.max_links = -1\r\nlog_errors = On\r\nlog_errors_max_len = 1024\r\nmail.add_x_header = Off\r\nmax_execution_time = 30\r\nmax_file_uploads = 20\r\nmax_input_time = 60\r\nmemory_limit = 128M\r\n{OPEN_BASEDIR_C}open_basedir = "{OPEN_BASEDIR}"\r\noutput_buffering = 4096\r\npost_max_size = 16M\r\nprecision = 14\r\nregister_argc_argv = Off\r\nreport_memleaks = On\r\nrequest_order = "GP"\r\nsendmail_path = "/usr/sbin/sendmail -t -i -f {CUSTOMER_EMAIL}"\r\nserialize_precision = -1\r\nsession.auto_start = 0\r\nsession.cache_expire = 180\r\nsession.cache_limiter = nocache\r\nsession.cookie_domain =\r\nsession.cookie_httponly =\r\nsession.cookie_lifetime = 0\r\nsession.cookie_path = /\r\nsession.cookie_samesite =\r\nsession.gc_divisor = 1000\r\nsession.gc_maxlifetime = 1440\r\nsession.gc_probability = 0\r\nsession.name = PHPSESSID\r\nsession.referer_check =\r\nsession.save_handler = files\r\nsession.save_path = "{TMP_DIR}"\r\nsession.serialize_handler = php\r\nsession.sid_bits_per_character = 5\r\nsession.sid_length = 26\r\nsession.trans_sid_tags = "a=href,area=href,frame=src,form="\r\nsession.use_cookies = 1\r\nsession.use_only_cookies = 1\r\nsession.use_strict_mode = 0\r\nsession.use_trans_sid = 0\r\nshort_open_tag = On\r\nupload_max_filesize = 32M\r\nupload_tmp_dir = "{TMP_DIR}"\r\nvariables_order = "GPCS"\r\nopcache.restrict_api = "{DOCUMENT_ROOT}"\r\n'), +(2, 'Froxlor Vhost Config', '/usr/bin/php-cgi', 'php', '-1', '-1', 'allow_url_fopen = On\r\nallow_url_include = Off\r\nauto_append_file =\r\nauto_globals_jit = On\r\nauto_prepend_file =\r\nbcmath.scale = 0\r\ncli_server.color = On\r\ndefault_charset = "UTF-8"\r\ndefault_mimetype = "text/html"\r\ndefault_socket_timeout = 60\r\nasp_tags = Off\r\ndisable_functions = pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,curl_multi_exec,parse_ini_file,passthru,popen,proc_close,proc_get_status,proc_nice,proc_open,proc_terminate,shell_exec,show_source,system\r\ndisplay_errors = Off\r\ndisplay_startup_errors = Off\r\ndoc_root =\r\nenable_dl = Off\r\nerror_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT & ~E_NOTICE\r\nexpose_php = Off\r\nfile_uploads = On\r\nhtml_errors = On\r\nignore_repeated_errors = Off\r\nignore_repeated_source = Off\r\ninclude_path = ".:{PEAR_DIR}"\r\nimplicit_flush = Off\r\nldap.max_links = -1\r\nlog_errors = On\r\nlog_errors_max_len = 1024\r\nmail.add_x_header = Off\r\nmax_execution_time = 60\r\nmax_file_uploads = 20\r\nmax_input_time = 60\r\nmemory_limit = 128M\r\noutput_buffering = 4096\r\npost_max_size = 16M\r\nprecision = 14\r\nregister_argc_argv = Off\r\nreport_memleaks = On\r\nrequest_order = "GP"\r\nsendmail_path = "/usr/sbin/sendmail -t -i -f {CUSTOMER_EMAIL}"\r\nserialize_precision = -1\r\nsession.auto_start = 0\r\nsession.cache_expire = 180\r\nsession.cache_limiter = nocache\r\nsession.cookie_domain =\r\nsession.cookie_httponly =\r\nsession.cookie_lifetime = 0\r\nsession.cookie_path = /\r\nsession.cookie_samesite =\r\nsession.gc_divisor = 1000\r\nsession.gc_maxlifetime = 1440\r\nsession.gc_probability = 0\r\nsession.name = PHPSESSID\r\nsession.referer_check =\r\nsession.save_handler = files\r\nsession.save_path = "{TMP_DIR}"\r\nsession.serialize_handler = php\r\nsession.sid_bits_per_character = 5\r\nsession.sid_length = 26\r\nsession.trans_sid_tags = "a=href,area=href,frame=src,form="\r\nsession.use_cookies = 1\r\nsession.use_only_cookies = 1\r\nsession.use_strict_mode = 0\r\nsession.use_trans_sid = 0\r\nshort_open_tag = On\r\nupload_max_filesize = 32M\r\nupload_tmp_dir = "{TMP_DIR}"\r\nvariables_order = "GPCS"\r\nopcache.restrict_api = ""\r\n'); DROP TABLE IF EXISTS `cronjobs_run`; @@ -750,22 +889,22 @@ CREATE TABLE IF NOT EXISTS `cronjobs_run` ( `id` bigint(20) NOT NULL auto_increment, `module` varchar(250) NOT NULL, `cronfile` varchar(250) NOT NULL, + `cronclass` varchar(500) NOT NULL, `lastrun` int(15) NOT NULL DEFAULT '0', `interval` varchar(100) NOT NULL DEFAULT '5 MINUTE', `isactive` tinyint(1) DEFAULT '1', `desc_lng_key` varchar(100) NOT NULL DEFAULT 'cron_unknown_desc', PRIMARY KEY (`id`) -) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; +) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci; -INSERT INTO `cronjobs_run` (`id`, `module`, `cronfile`, `interval`, `isactive`, `desc_lng_key`) VALUES - (1, 'froxlor/core', 'tasks', '5 MINUTE', '1', 'cron_tasks'), - (2, 'froxlor/core', 'traffic', '1 DAY', '1', 'cron_traffic'), - (3, 'froxlor/ticket', 'used_tickets_reset', '1 DAY', '1', 'cron_ticketsreset'), - (4, 'froxlor/ticket', 'ticketarchive', '1 MONTH', '1', 'cron_ticketarchive'), - (5, 'froxlor/reports', 'usage_report', '1 DAY', '1', 'cron_usage_report'), - (6, 'froxlor/core', 'mailboxsize', '6 HOUR', '1', 'cron_mailboxsize'), - (7, 'froxlor/letsencrypt', 'letsencrypt', '5 MINUTE', '0', 'cron_letsencrypt'); +INSERT INTO `cronjobs_run` (`id`, `module`, `cronfile`, `cronclass`, `interval`, `isactive`, `desc_lng_key`) VALUES + (1, 'froxlor/core', 'tasks', '\\Froxlor\\Cron\\System\\TasksCron', '5 MINUTE', '1', 'cron_tasks'), + (2, 'froxlor/core', 'traffic', '\\Froxlor\\Cron\\Traffic\\TrafficCron', '1 DAY', '1', 'cron_traffic'), + (3, 'froxlor/reports', 'usage_report', '\\Froxlor\\Cron\\Traffic\\ReportsCron', '1 DAY', '1', 'cron_usage_report'), + (4, 'froxlor/core', 'mailboxsize', '\\Froxlor\\Cron\\System\\MailboxsizeCron', '6 HOUR', '1', 'cron_mailboxsize'), + (5, 'froxlor/letsencrypt', 'letsencrypt', '\\Froxlor\\Cron\\Http\\LetsEncrypt\\AcmeSh', '5 MINUTE', '0', 'cron_letsencrypt'), + (6, 'froxlor/backup', 'backup', '\\Froxlor\\Cron\\System\\BackupCron', '1 DAY', '1', 'cron_backup'); @@ -781,7 +920,7 @@ CREATE TABLE IF NOT EXISTS `ftp_quotalimits` ( `files_in_avail` int(10) unsigned NOT NULL, `files_out_avail` int(10) unsigned NOT NULL, `files_xfer_avail` int(10) unsigned NOT NULL -) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; +) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci; @@ -800,7 +939,7 @@ CREATE TABLE IF NOT EXISTS `ftp_quotatallies` ( `files_in_used` int(10) unsigned NOT NULL, `files_out_used` int(10) unsigned NOT NULL, `files_xfer_used` int(10) unsigned NOT NULL -) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; +) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci; @@ -811,7 +950,7 @@ CREATE TABLE IF NOT EXISTS `redirect_codes` ( `desc` varchar(200) NOT NULL, `enabled` tinyint(1) DEFAULT '1', PRIMARY KEY (`id`) -) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; +) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci; @@ -829,21 +968,23 @@ CREATE TABLE IF NOT EXISTS `domain_redirect_codes` ( `rid` int(5) NOT NULL, `did` int(11) unsigned NOT NULL, UNIQUE KEY `rc` (`rid`, `did`) -) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; +) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci; DROP TABLE IF EXISTS `domain_ssl_settings`; CREATE TABLE IF NOT EXISTS `domain_ssl_settings` ( `id` int(5) NOT NULL auto_increment, `domainid` int(11) NOT NULL, - `ssl_cert_file` mediumtext NOT NULL, - `ssl_key_file` mediumtext NOT NULL, + `ssl_cert_file` mediumtext, + `ssl_key_file` mediumtext, `ssl_ca_file` mediumtext, `ssl_cert_chainfile` mediumtext, `ssl_csr_file` mediumtext, + `ssl_fullchain_file` mediumtext, `expirationdate` datetime DEFAULT NULL, - PRIMARY KEY (`id`) -) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; + PRIMARY KEY (`id`), + UNIQUE KEY (`domainid`) +) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci; DROP TABLE IF EXISTS `panel_domaintoip`; @@ -851,5 +992,46 @@ CREATE TABLE IF NOT EXISTS `panel_domaintoip` ( `id_domain` int(11) unsigned NOT NULL, `id_ipandports` int(11) unsigned NOT NULL, PRIMARY KEY (`id_domain`,`id_ipandports`) -) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; +) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci; + + +DROP TABLE IF EXISTS `domain_dns_entries`; +CREATE TABLE `domain_dns_entries` ( + `id` int(20) NOT NULL auto_increment, + `domain_id` int(15) NOT NULL, + `record` varchar(255) NOT NULL, + `type` varchar(10) NOT NULL DEFAULT 'A', + `content` text NOT NULL, + `ttl` int(11) NOT NULL DEFAULT '18000', + `prio` int(11) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci; + + +DROP TABLE IF EXISTS `panel_plans`; +CREATE TABLE `panel_plans` ( + `id` int(11) NOT NULL auto_increment, + `adminid` int(11) NOT NULL default '0', + `name` varchar(255) NOT NULL default '', + `description` text NOT NULL, + `value` longtext NOT NULL, + `ts` int(15) NOT NULL default '0', + PRIMARY KEY (id), + KEY adminid (adminid) +) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci; + + +DROP TABLE IF EXISTS `api_keys`; +CREATE TABLE `api_keys` ( + `id` int(11) NOT NULL auto_increment, + `adminid` int(11) NOT NULL default '0', + `customerid` int(11) NOT NULL default '0', + `apikey` varchar(500) NOT NULL default '', + `secret` varchar(500) NOT NULL default '', + `allowed_from` text NOT NULL, + `valid_until` int(15) NOT NULL default '0', + PRIMARY KEY (id), + KEY adminid (adminid), + KEY customerid (customerid) +) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci; diff --git a/install/install.php b/install/install.php index 58e03083..7a258149 100644 --- a/install/install.php +++ b/install/install.php @@ -15,8 +15,16 @@ * @package Install * */ - -require 'lib/class.FroxlorInstall.php'; +if (! file_exists(dirname(__DIR__) . '/vendor/autoload.php')) { + // get hint-template + $vendor_hint = file_get_contents(dirname(__DIR__) . '/templates/Sparkle/misc/vendormissinghint.tpl'); + // replace values + $vendor_hint = str_replace("", dirname(__DIR__), $vendor_hint); + $vendor_hint = str_replace("", date('Y', time()), $vendor_hint); + die($vendor_hint); +} +require dirname(__DIR__) . '/vendor/autoload.php'; +require __DIR__ . '/lib/class.FroxlorInstall.php'; $frxinstall = new FroxlorInstall(); $frxinstall->run(); diff --git a/install/lib/class.FroxlorInstall.php b/install/lib/class.FroxlorInstall.php index 73fd3eb8..0bb6e0a3 100644 --- a/install/lib/class.FroxlorInstall.php +++ b/install/lib/class.FroxlorInstall.php @@ -23,17 +23,19 @@ * * Does the dirty work * - * @copyright (c) the authors - * @author Michael Kaufmann - * @author Froxlor team (2010-) - * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt - * @package Install - * + * @copyright (c) the authors + * @author Michael Kaufmann + * @author Froxlor team (2010-) + * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt + * @package Install + * */ -class FroxlorInstall { +class FroxlorInstall +{ /** - * define froxlor basepath e.g. /var/www/froxlor + * define froxlor basepath e.g. + * /var/www/froxlor * * @var string */ @@ -64,21 +66,30 @@ class FroxlorInstall { * supported languages for install */ private $_languages = array( - 'german' => 'Deutsch', - 'english' => 'English', - 'french' => 'Français' + 'german' => 'Deutsch', + 'english' => 'English', + 'french' => 'Français' ); /** * currently used language - * @var unknown - */ + * + * @var string + */ private $_activelng = 'english'; + /** + * check whether to abort due to errors + * + * @var bool + */ + private $_abort = false; + /** * Class constructor */ - public function __construct() { + public function __construct() + { $this->_basepath = dirname(dirname(dirname(__FILE__))); $this->_data = array(); } @@ -86,15 +97,14 @@ class FroxlorInstall { /** * FC */ - public function run() { + public function run() + { // send headers $this->_sendHeaders(); // check if we have a valid installation already $this->_checkUserdataFile(); - // include the functions - require $this->_basepath.'/lib/functions.php'; // include the MySQL-Table-Definitions - require $this->_basepath.'/lib/tables.inc.php'; + require_once $this->_basepath . '/lib/tables.inc.php'; // include language $this->_includeLanguageFile(); // show the action @@ -104,15 +114,13 @@ class FroxlorInstall { /** * build up and show the install-process-pages */ - private function _showPage() { + private function _showPage() + { // set theme for templates $theme = $this->_theme; eval("echo \"" . $this->_getTemplate("header") . "\";"); // check install-state - if ((isset($_POST['installstep']) - && $_POST['installstep'] == '1') - || (isset($_GET['check']) && $_GET['check'] == '1') - ) { + 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. @@ -123,8 +131,8 @@ class FroxlorInstall { } else { // this should not happen $result = array( - 'pagecontent' => "How did you manage to get here? Well, you shouldn't be here. Go back!", - 'pagenavigation' => '' + 'pagecontent' => "How did you manage to get here? Well, you shouldn't be here. Go back!", + 'pagenavigation' => '' ); } } else { @@ -146,10 +154,12 @@ class FroxlorInstall { * * @return boolean */ - private function _checkPostData() { + private function _checkPostData() + { $this->_guessServerName(); $this->_guessServerIP(); $this->_guessWebserver(); + $this->_guessDistribution(); $this->_getPostField('mysql_host', '127.0.0.1'); $this->_getPostField('mysql_database', 'froxlor'); @@ -166,32 +176,22 @@ class FroxlorInstall { $posixgroup = posix_getgrgid(posix_getgid()); $this->_getPostField('httpgroup', $posixgroup['name']); - if ($this->_data['mysql_host'] == 'localhost' - || $this->_data['mysql_host'] == '127.0.0.1' - ) { + if ($this->_data['mysql_host'] == 'localhost' || $this->_data['mysql_host'] == '127.0.0.1') { $this->_data['mysql_access_host'] = $this->_data['mysql_host']; } else { $this->_data['mysql_access_host'] = $this->_data['serverip']; } // check system-hostname to be a FQDN - if ($this->_validate_ip($this->_data['servername'], true) !== false) { + if ($this->_validate_ip($this->_data['servername']) !== false) { $this->_data['servername'] = ''; } - if (isset($_POST['installstep']) - && $_POST['installstep'] == '1' - && $this->_data['admin_pass1'] == $this->_data['admin_pass2'] - && $this->_data['admin_pass1'] != '' - && $this->_data['admin_pass2'] != '' - && $this->_data['mysql_unpriv_pass'] != '' - && $this->_data['mysql_root_pass'] != '' - && $this->_data['servername'] != '' - && $this->_data['serverip'] != '' - && $this->_data['httpuser'] != '' - && $this->_data['httpgroup'] != '' - && $this->_data['mysql_unpriv_user'] != $this->_data['mysql_root_user'] - ) { + if (empty($this->_data['serverip']) || $this->_validate_ip($this->_data['serverip']) == false) { + return false; + } + + if (isset($_POST['installstep']) && $_POST['installstep'] == '1' && $this->_data['admin_pass1'] == $this->_data['admin_pass2'] && $this->_data['admin_pass1'] != '' && $this->_data['admin_pass2'] != '' && $this->_data['mysql_unpriv_pass'] != '' && $this->_data['mysql_root_pass'] != '' && $this->_data['servername'] != '' && $this->_data['serverip'] != '' && $this->_data['httpuser'] != '' && $this->_data['httpgroup'] != '' && $this->_data['mysql_unpriv_user'] != $this->_data['mysql_root_user']) { return true; } return false; @@ -202,31 +202,31 @@ class FroxlorInstall { * * @return array */ - private function _doInstall() { - + private function _doInstall() + { $content = ""; // check for mysql-root-connection $content .= $this->_status_message('begin', $this->_lng['install']['testing_mysql']); - $options = array('PDO::MYSQL_ATTR_INIT_COMMAND' => 'set names utf8'); - $dsn = "mysql:host=".$this->_data['mysql_host'].";"; + $options = array( + 'PDO::MYSQL_ATTR_INIT_COMMAND' => 'SET names utf8' + ); + $dsn = "mysql:host=" . $this->_data['mysql_host'] . ";"; $fatal_fail = false; try { - $db_root = new PDO( - $dsn, $this->_data['mysql_root_user'], $this->_data['mysql_root_pass'], $options - ); + $db_root = new PDO($dsn, $this->_data['mysql_root_user'], $this->_data['mysql_root_pass'], $options); } catch (PDOException $e) { // possibly without passwd? try { - $db_root = new PDO( - $dsn, $this->_data['mysql_root_user'], '', $options - ); + $db_root = new PDO($dsn, $this->_data['mysql_root_user'], '', $options); // set the given password $passwd_stmt = $db_root->prepare(" SET PASSWORD = PASSWORD(:passwd) "); - $passwd_stmt->execute(array('passwd' => $this->_data['mysql_root_pass'])); + $passwd_stmt->execute(array( + 'passwd' => $this->_data['mysql_root_pass'] + )); } catch (PDOException $e) { // nope $content .= $this->_status_message('red', $e->getMessage()); @@ -234,7 +234,13 @@ class FroxlorInstall { } } - if (!$fatal_fail) { + if (! $fatal_fail) { + $version_server = $db_root->getAttribute(PDO::ATTR_SERVER_VERSION); + $sql_mode = 'NO_ENGINE_SUBSTITUTION'; + if (version_compare($version_server, '8.0.11', '<')) { + $sql_mode .= ',NO_AUTO_CREATE_USER'; + } + $db_root->exec('SET sql_mode = "' . $sql_mode . '"'); // ok, if we are here, the database connection is up and running $content .= $this->_status_message('green', "OK"); @@ -244,35 +250,43 @@ class FroxlorInstall { $content .= $this->_createDatabaseAndUser($db_root); // importing data to new database $content .= $this->_importDatabaseData(); - // create DB object for new database - $options = array('PDO::MYSQL_ATTR_INIT_COMMAND' => 'set names utf8'); - $dsn = "mysql:host=".$this->_data['mysql_host'].";dbname=".$this->_data['mysql_database'].";"; - $another_fail = false; - try { - $db = new PDO( - $dsn, $this->_data['mysql_unpriv_user'], $this->_data['mysql_unpriv_pass'], $options + if (! $this->_abort) { + // create DB object for new database + $options = array( + 'PDO::MYSQL_ATTR_INIT_COMMAND' => 'SET names utf8' ); - } catch (PDOException $e) { - // dafuq? this should have happened in _importDatabaseData() - $content .= $this->_status_message('red', $e->getMessage()); - $another_fail = true; - }; + $dsn = "mysql:host=" . $this->_data['mysql_host'] . ";dbname=" . $this->_data['mysql_database'] . ";"; + $another_fail = false; + try { + $db = new PDO($dsn, $this->_data['mysql_unpriv_user'], $this->_data['mysql_unpriv_pass'], $options); + $version_server = $db->getAttribute(PDO::ATTR_SERVER_VERSION); + $sql_mode = 'NO_ENGINE_SUBSTITUTION'; + if (version_compare($version_server, '8.0.11', '<')) { + $sql_mode .= ',NO_AUTO_CREATE_USER'; + } + $db->exec('SET sql_mode = "' . $sql_mode . '"'); + } catch (PDOException $e) { + // dafuq? this should have happened in _importDatabaseData() + $content .= $this->_status_message('red', $e->getMessage()); + $another_fail = true; + } - if (!$another_fail) { - // change settings accordingly - $content .= $this->_doSettings($db); - // create entries - $content .= $this->_doDataEntries($db); - $db = null; - // create config-file - $content .= $this->_createUserdataConf(); + if (! $another_fail) { + // change settings accordingly + $content .= $this->_doSettings($db); + // create entries + $content .= $this->_doDataEntries($db); + $db = null; + // create config-file + $content .= $this->_createUserdataConf(); + } } } $content .= "
"; // check if we have unrecoverable errors - if ($fatal_fail || $another_fail) { + if ($fatal_fail || $another_fail || $this->_abort) { // D'oh $navigation = ''; $msgcolor = 'red'; @@ -290,46 +304,58 @@ class FroxlorInstall { eval("\$navigation .= \"" . $this->_getTemplate("pagebottom") . "\";"); - return array('pagecontent' => $content, 'pagenavigation' => $navigation); + return array( + 'pagecontent' => $content, + 'pagenavigation' => $navigation + ); } /** * Create userdata.inc.php file */ - private function _createUserdataConf() { - + private function _createUserdataConf() + { $content = ""; $content .= $this->_status_message('begin', $this->_lng['install']['creating_configfile']); $userdata = "_data['mysql_host'], "'\\") . "';\n"; - $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_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.= "?>"; + $userdata .= "// automatically generated userdata.inc.php for Froxlor\n"; + $userdata .= "\$sql['host']='" . addcslashes($this->_data['mysql_host'], "'\\") . "';\n"; + $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_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 .= "// 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 - if ($fp = @fopen(dirname(dirname(dirname(__FILE__))).'/lib/userdata.inc.php', 'w')) { - $result = @fputs($fp, $userdata, strlen($userdata)); + $umask = @umask(077); + $userdata_file = dirname(dirname(dirname(__FILE__))) . '/lib/userdata.inc.php'; + 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('../lib/userdata.inc.php', 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; } @@ -341,42 +367,46 @@ class FroxlorInstall { * * @return string status messages */ - private function _doDataEntries(&$db) { - + private function _doDataEntries(&$db) + { $content = ""; $content .= $this->_status_message('begin', $this->_lng['install']['creating_entries']); // and lets insert the default ip and port $stmt = $db->prepare(" - INSERT INTO `".TABLE_PANEL_IPSANDPORTS."` SET + INSERT INTO `" . TABLE_PANEL_IPSANDPORTS . "` SET `ip`= :serverip, `port` = '80', `namevirtualhost_statement` = '1', `vhostcontainer` = '1', `vhostcontainer_servername_statement` = '1' "); - $stmt->execute(array('serverip' => $this->_data['serverip'])); + $stmt->execute(array( + 'serverip' => $this->_data['serverip'] + )); $defaultip = $db->lastInsertId(); // insert the defaultip $upd_stmt = $db->prepare(" - UPDATE `".TABLE_PANEL_SETTINGS."` SET + UPDATE `" . TABLE_PANEL_SETTINGS . "` SET `value` = :defaultip WHERE `settinggroup` = 'system' AND `varname` = 'defaultip' "); - $upd_stmt->execute(array('defaultip' => $defaultip)); + $upd_stmt->execute(array( + 'defaultip' => $defaultip + )); $content .= $this->_status_message('green', 'OK'); - //last but not least create the main admin + // last but not least create the main admin $content .= $this->_status_message('begin', $this->_lng['install']['adding_admin_user']); $ins_data = array( - 'loginname' => $this->_data['admin_user'], + 'loginname' => $this->_data['admin_user'], /* use SHA256 default crypt */ - 'password' => crypt($this->_data['admin_pass1'], '$5$'. md5(uniqid(microtime(), 1)) . md5(uniqid(microtime(), 1))), - 'email' => 'admin@' . $this->_data['servername'], - 'deflang' => $this->_languages[$this->_activelng] + 'password' => crypt($this->_data['admin_pass1'], '$5$' . md5(uniqid(microtime(), 1)) . md5(uniqid(microtime(), 1))), + 'email' => 'admin@' . $this->_data['servername'], + 'deflang' => $this->_languages[$this->_activelng] ); $ins_stmt = $db->prepare(" INSERT INTO `" . TABLE_PANEL_ADMINS . "` SET @@ -385,6 +415,7 @@ class FroxlorInstall { `name` = 'Froxlor-Administrator', `email` = :email, `def_language` = :deflang, + `api_allowed` = 1, `customers` = -1, `customers_see_all` = 1, `caneditphpsettings` = 1, @@ -398,8 +429,6 @@ class FroxlorInstall { `email_forwarders` = -1, `email_quota` = -1, `ftps` = -1, - `tickets` = -1, - `tickets_see_all` = 1, `subdomains` = -1, `traffic` = -1048576 "); @@ -419,11 +448,12 @@ class FroxlorInstall { * @param string $varname * @param string $value */ - private function _updateSetting(&$stmt = null, $value = null, $group = null, $varname = null) { + private function _updateSetting(&$stmt = null, $value = null, $group = null, $varname = null) + { $stmt->execute(array( - 'group' => $group, - 'varname' => $varname, - 'value' => $value + 'group' => $group, + 'varname' => $varname, + 'value' => $value )); } @@ -434,8 +464,8 @@ class FroxlorInstall { * * @return string status messages */ - private function _doSettings(&$db) { - + private function _doSettings(&$db) + { $content = ""; $content .= $this->_status_message('begin', $this->_lng['install']['changing_data']); @@ -456,8 +486,8 @@ class FroxlorInstall { // necessary changes for webservers != apache2 if ($this->_data['webserver'] == "apache24") { - $this->_updateSetting($upd_stmt, 'apache2', 'system', 'webserver'); - $this->_updateSetting($upd_stmt, '1', 'system', 'apache24'); + $this->_updateSetting($upd_stmt, 'apache2', 'system', 'webserver'); + $this->_updateSetting($upd_stmt, '1', 'system', 'apache24'); } elseif ($this->_data['webserver'] == "lighttpd") { $this->_updateSetting($upd_stmt, '/etc/lighttpd/conf-enabled/', 'system', 'apacheconf_vhost'); $this->_updateSetting($upd_stmt, '/etc/lighttpd/froxlor-diroptions/', 'system', 'apacheconf_diroptions'); @@ -472,23 +502,39 @@ class FroxlorInstall { $this->_updateSetting($upd_stmt, '/etc/init.d/nginx reload', 'system', 'apachereload_command'); $this->_updateSetting($upd_stmt, '/etc/nginx/nginx.pem', 'system', 'ssl_cert_file'); $this->_updateSetting($upd_stmt, '/var/run/', 'phpfpm', 'fastcgi_ipcdir'); + $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.php';"); - $ts = mktime(1, 0, 0, date('m', time()), date('d', time()), date('Y', time())); - $db->query("UPDATE `".TABLE_PANEL_CRONRUNS."` SET `lastrun` = '".$ts."' WHERE `cronfile` ='cron_used_tickets_reset.php';"); - $db->query("UPDATE `".TABLE_PANEL_CRONRUNS."` SET `lastrun` = '".$ts."' WHERE `cronfile` ='cron_ticketarchive.php';"); + $db->query("UPDATE `" . TABLE_PANEL_CRONRUNS . "` SET `lastrun` = '" . $ts . "' WHERE `cronfile` ='cron_traffic';"); // insert task 99 to generate a correct cron.d-file automatically - $db->query("INSERT INTO `".TABLE_PANEL_TASKS."` SET `type` = '99';"); + $db->query("INSERT INTO `" . TABLE_PANEL_TASKS . "` SET `type` = '99';"); $content .= $this->_status_message('green', 'OK'); @@ -502,39 +548,61 @@ class FroxlorInstall { * * @return string status messages */ - private function _importDatabaseData() { - + private function _importDatabaseData() + { $content = ""; $content .= $this->_status_message('begin', $this->_lng['install']['testing_new_db']); - $options = array('PDO::MYSQL_ATTR_INIT_COMMAND' => 'set names utf8'); - $dsn = "mysql:host=".$this->_data['mysql_host'].";dbname=".$this->_data['mysql_database'].";"; + $options = array( + 'PDO::MYSQL_ATTR_INIT_COMMAND' => 'SET names utf8' + ); + $dsn = "mysql:host=" . $this->_data['mysql_host'] . ";dbname=" . $this->_data['mysql_database'] . ";"; $fatal_fail = false; try { - $db = new PDO( - $dsn, $this->_data['mysql_unpriv_user'], $this->_data['mysql_unpriv_pass'], $options + $db = new PDO($dsn, $this->_data['mysql_unpriv_user'], $this->_data['mysql_unpriv_pass'], $options); + $attributes = array( + 'ATTR_ERRMODE' => 'ERRMODE_EXCEPTION' ); + // set attributes + foreach ($attributes as $k => $v) { + $db->setAttribute(constant("PDO::" . $k), constant("PDO::" . $v)); + } + $version_server = $db->getAttribute(PDO::ATTR_SERVER_VERSION); + $sql_mode = 'NO_ENGINE_SUBSTITUTION'; + if (version_compare($version_server, '8.0.11', '<')) { + $sql_mode .= ',NO_AUTO_CREATE_USER'; + } + $db->exec('SET sql_mode = "' . $sql_mode . '"'); } catch (PDOException $e) { $content .= $this->_status_message('red', $e->getMessage()); $fatal_fail = true; - }; + } - if (!$fatal_fail) { + if (! $fatal_fail) { $content .= $this->_status_message('green', 'OK'); $content .= $this->_status_message('begin', $this->_lng['install']['importing_data']); - $db_schema = dirname(dirname(__FILE__)).'/froxlor.sql'; + $db_schema = dirname(dirname(__FILE__)) . '/froxlor.sql'; $sql_query = @file_get_contents($db_schema); $sql_query = $this->_remove_remarks($sql_query); $sql_query = $this->_split_sql_file($sql_query, ';'); - for ($i = 0; $i < sizeof($sql_query); $i++) { + for ($i = 0; $i < sizeof($sql_query); $i ++) { if (trim($sql_query[$i]) != '') { - $result = $db->query($sql_query[$i]); + try { + $db->query($sql_query[$i]); + } catch (\PDOException $e) { + $content .= $this->_status_message('red', $e->getMessage()); + $fatal_fail = true; + $this->_abort = true; + break; + } } } - $db = null; - $content .= $this->_status_message('green', 'OK'); + if (! $fatal_fail) { + $content .= $this->_status_message('green', 'OK'); + } + $db = null; } return $content; @@ -547,8 +615,8 @@ class FroxlorInstall { * * @return string status messages */ - private function _createDatabaseAndUser(&$db_root) { - + private function _createDatabaseAndUser(&$db_root) + { $content = ""; // so first we have to delete the database and @@ -556,18 +624,30 @@ class FroxlorInstall { $content .= $this->_status_message('begin', $this->_lng['install']['prepare_db']); $del_stmt = $db_root->prepare("DELETE FROM `mysql`.`user` WHERE `User` = :user AND `Host` = :accesshost"); - $del_stmt->execute(array('user' => $this->_data['mysql_unpriv_user'], 'accesshost' => $this->_data['mysql_access_host'])); + $del_stmt->execute(array( + 'user' => $this->_data['mysql_unpriv_user'], + 'accesshost' => $this->_data['mysql_access_host'] + )); $del_stmt = $db_root->prepare("DELETE FROM `mysql`.`db` WHERE `User` = :user AND `Host` = :accesshost"); - $del_stmt->execute(array('user' => $this->_data['mysql_unpriv_user'], 'accesshost' => $this->_data['mysql_access_host'])); + $del_stmt->execute(array( + 'user' => $this->_data['mysql_unpriv_user'], + 'accesshost' => $this->_data['mysql_access_host'] + )); $del_stmt = $db_root->prepare("DELETE FROM `mysql`.`tables_priv` WHERE `User` = :user AND `Host` =:accesshost"); - $del_stmt->execute(array('user' => $this->_data['mysql_unpriv_user'], 'accesshost' => $this->_data['mysql_access_host'])); + $del_stmt->execute(array( + 'user' => $this->_data['mysql_unpriv_user'], + 'accesshost' => $this->_data['mysql_access_host'] + )); $del_stmt = $db_root->prepare("DELETE FROM `mysql`.`columns_priv` WHERE `User` = :user AND `Host` = :accesshost"); - $del_stmt->execute(array('user' => $this->_data['mysql_unpriv_user'], 'accesshost' => $this->_data['mysql_access_host'])); + $del_stmt->execute(array( + 'user' => $this->_data['mysql_unpriv_user'], + 'accesshost' => $this->_data['mysql_access_host'] + )); - $del_stmt = $db_root->prepare("DROP DATABASE IF EXISTS `".str_replace('`', '', $this->_data['mysql_database'])."`;"); + $del_stmt = $db_root->prepare("DROP DATABASE IF EXISTS `" . str_replace('`', '', $this->_data['mysql_database']) . "`;"); $del_stmt->execute(); $db_root->query("FLUSH PRIVILEGES;"); @@ -575,34 +655,23 @@ class FroxlorInstall { // we have to create a new user and database for the froxlor unprivileged mysql access $content .= $this->_status_message('begin', $this->_lng['install']['create_mysqluser_and_db']); - $ins_stmt = $db_root->prepare("CREATE DATABASE `".str_replace('`', '', $this->_data['mysql_database'])."` CHARACTER SET=utf8 COLLATE=utf8_general_ci"); + $ins_stmt = $db_root->prepare("CREATE DATABASE `" . str_replace('`', '', $this->_data['mysql_database']) . "` CHARACTER SET=utf8 COLLATE=utf8_general_ci"); $ins_stmt->execute(); $mysql_access_host_array = array_map('trim', explode(',', $this->_data['mysql_access_host'])); - if (in_array('127.0.0.1', $mysql_access_host_array) - && !in_array('localhost', $mysql_access_host_array) - ) { + if (in_array('127.0.0.1', $mysql_access_host_array) && ! in_array('localhost', $mysql_access_host_array)) { $mysql_access_host_array[] = 'localhost'; } - if (!in_array('127.0.0.1', $mysql_access_host_array) - && in_array('localhost', $mysql_access_host_array) - ) { + if (! in_array('127.0.0.1', $mysql_access_host_array) && in_array('localhost', $mysql_access_host_array)) { $mysql_access_host_array[] = '127.0.0.1'; } $mysql_access_host_array[] = $this->_data['serverip']; foreach ($mysql_access_host_array as $mysql_access_host) { - $_db = str_replace('`', '', $this->_data['mysql_database']); - $stmt = $db_root->prepare(" - GRANT ALL PRIVILEGES ON `" . $_db . "`.* - TO :username@:host - IDENTIFIED BY 'password'" - ); - $stmt->execute(array("username" => $this->_data['mysql_unpriv_user'], "host" => $mysql_access_host)); - $stmt = $db_root->prepare("SET PASSWORD FOR :username@:host = PASSWORD(:password)"); - $stmt->execute(array("username" => $this->_data['mysql_unpriv_user'], "host" => $mysql_access_host, "password" => $this->_data['mysql_unpriv_pass'])); + $frox_db = str_replace('`', '', $this->_data['mysql_database']); + $this->_grantDbPrivilegesTo($db_root, $frox_db, $this->_data['mysql_unpriv_user'], $this->_data['mysql_unpriv_pass'], $mysql_access_host); } $db_root->query("FLUSH PRIVILEGES;"); @@ -612,6 +681,38 @@ class FroxlorInstall { return $content; } + private function _grantDbPrivilegesTo(&$db_root, $database, $username, $password, $access_host) + { + // mysql8 compatibility + 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 + "); + $stmt->execute(array( + "password" => $password + )); + // grant privileges + $stmt = $db_root->prepare(" + GRANT ALL ON `" . $database . "`.* TO :username@:host + "); + $stmt->execute(array( + "username" => $username, + "host" => $access_host + )); + } else { + // grant privileges + $stmt = $db_root->prepare(" + GRANT ALL PRIVILEGES ON `" . $database . "`.* TO :username@:host IDENTIFIED BY :password + "); + $stmt->execute(array( + "username" => $username, + "host" => $access_host, + "password" => $password + )); + } + } + /** * Check if an old database exists and back it up if necessary * @@ -619,15 +720,17 @@ class FroxlorInstall { * * @return string status messages */ - private function _backupExistingDatabase(&$db_root) { - + private function _backupExistingDatabase(&$db_root) + { $content = ""; // check for existing of former database $tables_exist = false; $sql = "SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = :database"; $result_stmt = $db_root->prepare($sql); - $result_stmt->execute(array('database' => $this->_data['mysql_database'])); + $result_stmt->execute(array( + 'database' => $this->_data['mysql_database'] + )); $rows = $db_root->query("SELECT FOUND_ROWS()")->fetchColumn(); // check result @@ -653,12 +756,12 @@ class FroxlorInstall { } 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; + $command = $mysql_dump . " " . escapeshellarg($this->_data['mysql_database']) . " -u " . escapeshellarg($this->_data['mysql_root_user']) . " --password='" . escapeshellarg($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']); } else { - $content .= $this->_status_message('green', 'OK ('.$filename.')'); + $content .= $this->_status_message('green', 'OK (' . $filename . ')'); } } else { $content .= $this->_status_message('red', $this->_lng['install']['backup_binary_missing']); @@ -671,18 +774,18 @@ class FroxlorInstall { /** * show form to collect all needed data for the install */ - private function _showDataForm() { - + private function _showDataForm() + { $content = ""; // form action $formaction = htmlspecialchars($_SERVER['PHP_SELF']); if (isset($_GET['check'])) { - $formaction .= '?check='.(int)$_GET['check']; + $formaction .= '?check=' . (int) $_GET['check']; } // language selection $language_options = ''; - while (list($language_file, $language_name) = each($this->_languages)) { - $language_options.= makeoption($language_name, $language_file, $this->_activelng, true, true); + foreach ($this->_languages as $language_name => $language_file) { + $language_options .= \Froxlor\UI\HTML::makeoption($language_name, $language_file, $this->_activelng, true, true); } // get language-form-template eval("\$content .= \"" . $this->_getTemplate("lngform") . "\";"); @@ -701,51 +804,51 @@ class FroxlorInstall { // unpriv-user has to be different from root if ($this->_data['mysql_unpriv_user'] == $this->_data['mysql_root_user']) { $style = 'blue'; - } else { $style = ''; + } else { + $style = ''; } $formdata .= $this->_getSectionItemString('mysql_unpriv_user', true, $style); // is we posted and no password was given -> red - if (!empty($_POST['installstep']) && $this->_data['mysql_unpriv_pass'] == '') { + if (! empty($_POST['installstep']) && $this->_data['mysql_unpriv_pass'] == '') { $style = 'red'; - } else { $style = ''; + } else { + $style = ''; } $formdata .= $this->_getSectionItemString('mysql_unpriv_pass', true, $style, 'password'); // unpriv-user has to be different from root if ($this->_data['mysql_unpriv_user'] == $this->_data['mysql_root_user']) { $style = 'blue'; - } else { $style = ''; + } else { + $style = ''; } $formdata .= $this->_getSectionItemString('mysql_root_user', true, $style); // is we posted and no password was given -> red - if (!empty($_POST['installstep']) && $this->_data['mysql_root_pass'] == '') { + if (! empty($_POST['installstep']) && $this->_data['mysql_root_pass'] == '') { $style = 'red'; - } else { $style = ''; + } else { + $style = ''; } $formdata .= $this->_getSectionItemString('mysql_root_pass', true, $style, 'password'); /** * admin data - */ + */ $section = $this->_lng['install']['admin_account']; eval("\$formdata .= \"" . $this->_getTemplate("datasection") . "\";"); // user $formdata .= $this->_getSectionItemString('admin_user', true); // check for admin passwords to be equal - if (!empty($_POST['installstep']) && - ($this->_data['admin_pass1'] == '' - || $this->_data['admin_pass1'] != $this->_data['admin_pass2']) - ) { + if (! empty($_POST['installstep']) && ($this->_data['admin_pass1'] == '' || $this->_data['admin_pass1'] != $this->_data['admin_pass2'])) { $style = 'color:red;'; - } else { $style = ''; + } else { + $style = ''; } $formdata .= $this->_getSectionItemString('admin_pass1', true, $style, 'password'); // check for admin passwords to be equal - if (!empty($_POST['installstep']) && - ($this->_data['admin_pass2'] == '' - || $this->_data['admin_pass1'] != $this->_data['admin_pass2']) - ) { + if (! empty($_POST['installstep']) && ($this->_data['admin_pass2'] == '' || $this->_data['admin_pass1'] != $this->_data['admin_pass2'])) { $style = 'color:red;'; - } else { $style = ''; + } else { + $style = ''; } $formdata .= $this->_getSectionItemString('admin_pass2', true, $style, 'password'); // activate newsfeed? @@ -753,43 +856,74 @@ class FroxlorInstall { /** * Server data - */ + */ $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 + $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 . ")"; + $distributions_select_data[$dist_display] .= str_replace(".xml", "", strtolower(basename($_distribution))); + } + + // sort by distribution name + ksort($distributions_select_data); + + 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'] == '') { + if (! empty($_POST['installstep']) && $this->_data['servername'] == '') { $style = 'color:red;'; - } else { $style = ''; + } else { + $style = ''; } $formdata .= $this->_getSectionItemString('servername', true, $style); // serverip - if (!empty($_POST['installstep']) && $this->_data['serverip'] == '') { + if (! empty($_POST['installstep']) && ($this->_data['serverip'] == '' || $this->_validate_ip($this->_data['serverip']) == false)) { $style = 'color:red;'; - } else { $style = ''; + } else { + $style = ''; } $formdata .= $this->_getSectionItemString('serverip', true, $style); // webserver - if (!empty($_POST['installstep']) && $this->_data['webserver'] == '') { + if (! empty($_POST['installstep']) && $this->_data['webserver'] == '') { $websrvstyle = 'color:red;'; - } else { $websrvstyle = ''; + } else { + $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'] == '') { + if (! empty($_POST['installstep']) && $this->_data['httpuser'] == '') { $style = 'color:red;'; - } else { $style = ''; + } else { + $style = ''; } $formdata .= $this->_getSectionItemString('httpuser', true, $style); // webserver-group - if (!empty($_POST['installstep']) && $this->_data['httpgroup'] == '') { + if (! empty($_POST['installstep']) && $this->_data['httpgroup'] == '') { $style = 'color:red;'; - } else { $style = ''; + } else { + $style = ''; } $formdata .= $this->_getSectionItemString('httpgroup', true, $style); @@ -798,7 +932,10 @@ class FroxlorInstall { eval("\$content .= \"" . $this->_getTemplate("dataform2") . "\";"); $navigation = ''; - return array('pagecontent' => $content, 'pagenavigation' => $navigation); + return array( + 'pagecontent' => $content, + 'pagenavigation' => $navigation + ); } /** @@ -806,12 +943,15 @@ class FroxlorInstall { * * @param string $fieldname * @param boolean $required - * @param string $style optional css - * @param string $type optional type of input-box (default: text) - * + * @param string $style + * optional css + * @param string $type + * optional type of input-box (default: text) + * * @return string */ - private function _getSectionItemString($fieldname = null, $required = false, $style = "", $type = 'text') { + private function _getSectionItemString($fieldname = null, $required = false, $style = "", $type = 'text') + { $fieldlabel = $this->_lng['install'][$fieldname]; $fieldvalue = htmlspecialchars($this->_data[$fieldname]); if ($required) { @@ -823,7 +963,7 @@ class FroxlorInstall { } /** - * generate form radio field for webserver-selection + * generate form radio field * * @param string $fieldname * @param boolean $checked @@ -831,7 +971,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"'; @@ -841,6 +983,25 @@ 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 = "") + { + $groupname = $this->_lng['install'][$groupname]; + $fieldlabel = $this->_lng['install'][$fieldname]; + + $sectionitem = ""; + eval("\$sectionitem .= \"" . $this->_getTemplate("dataitemselect") . "\";"); + return $sectionitem; + } + /** * generate form checkbox field * @@ -850,20 +1011,22 @@ class FroxlorInstall { * * @return string */ - private function _getSectionItemYesNo($fieldname = null, $checked = false, $style = "") { - $fieldlabel = $this->_lng['install'][$fieldname]; - if ($checked) { - $checked = 'checked="checked"'; - } - $sectionitem = ""; - eval("\$sectionitem .= \"" . $this->_getTemplate("dataitemyesno") . "\";"); - return $sectionitem; + private function _getSectionItemYesNo($fieldname = null, $checked = false, $style = "") + { + $fieldlabel = $this->_lng['install'][$fieldname]; + if ($checked) { + $checked = 'checked="checked"'; + } + $sectionitem = ""; + eval("\$sectionitem .= \"" . $this->_getTemplate("dataitemyesno") . "\";"); + return $sectionitem; } /** * check for requirements froxlor needs */ - private function _requirementCheck() { + private function _requirementCheck() + { // indicator whether we need to abort or not $_die = false; @@ -873,101 +1036,78 @@ class FroxlorInstall { // check for correct php version $content .= $this->_status_message('begin', $this->_lng['requirements']['phpversion']); - if (version_compare("5.3.0", PHP_VERSION, ">=")) { - $content .= $this->_status_message('red', $this->_lng['requirements']['notfound'].' ('.PHP_VERSION.')'); + if (version_compare("7.0.0", PHP_VERSION, ">=")) { + $content .= $this->_status_message('red', $this->_lng['requirements']['notfound'] . ' (' . PHP_VERSION . ')'); $_die = true; } else { - $content .= $this->_status_message('green', PHP_VERSION); - } - - // Check if magic_quotes_runtime is active | get_magic_quotes_runtime() is always FALSE since 5.4 - if (version_compare(PHP_VERSION, "5.4.0", "<")) { - $content .= $this->_status_message('begin', $this->_lng['requirements']['phpmagic_quotes_runtime']); - if (get_magic_quotes_runtime()) { - // deactivate it - set_magic_quotes_runtime(false); - $content .= $this->_status_message('orange', $this->_lng['requirements']['not_true'] . "
". $this->_lng['requirements']['phpmagic_quotes_runtime_description']); + if (version_compare("7.1.0", PHP_VERSION, ">=")) { + $content .= $this->_status_message('orange', $this->_lng['requirements']['newerphpprefered'] . ' (' . PHP_VERSION . ')'); } else { - $content .= $this->_status_message('green', 'off'); + $content .= $this->_status_message('green', PHP_VERSION); } } // check for php_pdo and pdo_mysql $content .= $this->_status_message('begin', $this->_lng['requirements']['phppdo']); - if (!extension_loaded('pdo') || in_array("mysql", PDO::getAvailableDrivers()) == false) { + if (! extension_loaded('pdo') || in_array("mysql", PDO::getAvailableDrivers()) == false) { $content .= $this->_status_message('red', $this->_lng['requirements']['notinstalled']); $_die = true; } else { $content .= $this->_status_message('green', $this->_lng['requirements']['installed']); } + // check for session-extension + $this->_requirementCheckFor($content, $_die, 'session', false, 'phpsession'); + + // check for ctype-extension + $this->_requirementCheckFor($content, $_die, 'ctype', false, 'phpctype'); + + // check for SimpleXML-extension + $this->_requirementCheckFor($content, $_die, 'simplexml', false, 'phpsimplexml'); + // check for xml-extension - $content .= $this->_status_message('begin', $this->_lng['requirements']['phpxml']); - - if (!extension_loaded('xml')) { - $content .= $this->_status_message('red', $this->_lng['requirements']['notinstalled']); - $_die = true; - } else { - $content .= $this->_status_message('green', $this->_lng['requirements']['installed']); - } + $this->_requirementCheckFor($content, $_die, 'xml', false, 'phpxml'); // check for filter-extension - $content .= $this->_status_message('begin', $this->_lng['requirements']['phpfilter']); - - if (!extension_loaded('filter')) { - $content .= $this->_status_message('red', $this->_lng['requirements']['notinstalled']); - $_die = true; - } else { - $content .= $this->_status_message('green', $this->_lng['requirements']['installed']); - } + $this->_requirementCheckFor($content, $_die, 'filter', false, 'phpfilter'); // check for posix-extension - $content .= $this->_status_message('begin', $this->_lng['requirements']['phpposix']); + $this->_requirementCheckFor($content, $_die, 'posix', false, 'phpposix'); - if (!extension_loaded('posix')) { - $content .= $this->_status_message('red', $this->_lng['requirements']['notinstalled']); - $_die = true; - } else { - $content .= $this->_status_message('green', $this->_lng['requirements']['installed']); - } - - // check for bstring-extension - $content .= $this->_status_message('begin', $this->_lng['requirements']['phpmbstring']); - - if (!extension_loaded('mbstring')) { - $content .= $this->_status_message('red', $this->_lng['requirements']['notinstalled']); - $_die = true; - } else { - $content .= $this->_status_message('green', $this->_lng['requirements']['installed']); - } - - // check for bcmath extension - $content .= $this->_status_message('begin', $this->_lng['requirements']['phpbcmath']); - - if (!extension_loaded('bcmath')) { - $content .= $this->_status_message('orange', $this->_lng['requirements']['notinstalled'] . "
" . $this->_lng['requirements']['bcmathdescription']); - } else { - $content .= $this->_status_message('green', $this->_lng['requirements']['installed']); - } + // check for mbstring-extension + $this->_requirementCheckFor($content, $_die, 'mbstring', false, 'phpmbstring'); // check for curl extension - $content .= $this->_status_message('begin', $this->_lng['requirements']['phpcurl']); + $this->_requirementCheckFor($content, $_die, 'curl', false, 'phpcurl'); - if (!extension_loaded('curl')) { - $content .= $this->_status_message('orange', $this->_lng['requirements']['notinstalled'] . "
" . $this->_lng['requirements']['curldescription']); - } else { - $content .= $this->_status_message('green', $this->_lng['requirements']['installed']); - } + // check for json extension + $this->_requirementCheckFor($content, $_die, 'json', false, 'phpjson'); + + // check for bcmath extension + $this->_requirementCheckFor($content, $_die, 'bcmath', true, 'phpbcmath', 'bcmathdescription'); + + // check for zip extension + $this->_requirementCheckFor($content, $_die, 'zip', true, 'phpzip', 'zipdescription'); // check for open_basedir $content .= $this->_status_message('begin', $this->_lng['requirements']['openbasedir']); $php_ob = @ini_get("open_basedir"); - if (!empty($php_ob) && $php_ob != '') { + if (! empty($php_ob) && $php_ob != '') { $content .= $this->_status_message('orange', $this->_lng['requirements']['activated'] . "
" . $this->_lng['requirements']['openbasedirenabled']); } else { $content .= $this->_status_message('green', 'off'); } + + // check for mysqldump binary in order to backup existing database + $content .= $this->_status_message('begin', $this->_lng['requirements']['mysqldump']); + + if (file_exists("/usr/bin/mysqldump") || file_exists("/usr/local/bin/mysqldump")) { + $content .= $this->_status_message('green', $this->_lng['requirements']['installed']); + } else { + $content .= $this->_status_message('orange', $this->_lng['requirements']['notinstalled'] . "
" . $this->_lng['requirements']['mysqldumpmissing']); + } + $content .= ""; // check if we have unrecoverable errors @@ -980,28 +1120,47 @@ class FroxlorInstall { } else { $msgcolor = 'green'; $message = $this->_lng['requirements']['froxlor_succ_checks']; - $link = htmlspecialchars($_SERVER['PHP_SELF']).'?check=1'; + $link = htmlspecialchars($_SERVER['PHP_SELF']) . '?check=1'; $linktext = $this->_lng['click_here_to_continue']; } eval("\$navigation .= \"" . $this->_getTemplate("pagebottom") . "\";"); - return array('pagecontent' => $content, 'pagenavigation' => $navigation); + return array( + 'pagecontent' => $content, + 'pagenavigation' => $navigation + ); + } + + private function _requirementCheckFor(&$content, &$_die, $ext = '', $optional = false, $lng_txt = "", $lng_desc = "") + { + $content .= $this->_status_message('begin', $this->_lng['requirements'][$lng_txt]); + + if (! extension_loaded($ext)) { + if (! $optional) { + $content .= $this->_status_message('red', $this->_lng['requirements']['notinstalled']); + $_die = true; + } else { + $content .= $this->_status_message('orange', $this->_lng['requirements']['notinstalled'] . "
" . $this->_lng['requirements'][$lng_desc]); + } + } else { + $content .= $this->_status_message('green', $this->_lng['requirements']['installed']); + } } /** * send no-caching headers and set the default timezone */ - private function _sendHeaders() { - // no caching - header("Cache-Control: no-store, no-cache, must-revalidate"); - header("Pragma: no-cache"); - header('Last-Modified: ' . gmdate( 'D, d M Y H:i:s \G\M\T', time())); - header('Expires: ' . gmdate( 'D, d M Y H:i:s \G\M\T', time())); - + private function _sendHeaders() + { + if (@php_sapi_name() !== 'cli') { + // no caching + header("Cache-Control: no-store, no-cache, must-revalidate"); + header("Pragma: no-cache"); + header('Last-Modified: ' . gmdate('D, d M Y H:i:s \G\M\T', time())); + header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', time())); + } // ensure that default timezone is set - if (function_exists("date_default_timezone_set") - && function_exists("date_default_timezone_get") - ) { + if (function_exists("date_default_timezone_set") && function_exists("date_default_timezone_get")) { @date_default_timezone_set(@date_default_timezone_get()); } } @@ -1010,18 +1169,17 @@ class FroxlorInstall { * check for the userdata - if it exists then froxlor is * already installed and we show a nice note */ - private function _checkUserDataFile() { - $userdata = $this->_basepath.'/lib/userdata.inc.php'; + private function _checkUserDataFile() + { + $userdata = $this->_basepath . '/lib/userdata.inc.php'; if (file_exists($userdata)) { // includes the usersettings (MySQL-Username/Passwort) // to test if Froxlor is already installed - require $this->_basepath.'/lib/userdata.inc.php'; + require_once $this->_basepath . '/lib/userdata.inc.php'; - if (isset($sql) - && is_array($sql) - ) { + if (isset($sql) && is_array($sql)) { // use sparkle theme for the notice - $installed_hint = file_get_contents($this->_basepath.'/templates/Sparkle/misc/alreadyinstalledhint.tpl'); + $installed_hint = file_get_contents($this->_basepath . '/templates/Sparkle/misc/alreadyinstalledhint.tpl'); $installed_hint = str_replace("", date('Y', time()), $installed_hint); die($installed_hint); } @@ -1031,18 +1189,15 @@ class FroxlorInstall { /** * include the chose language or else default (english) */ - private function _includeLanguageFile() { + private function _includeLanguageFile() + { // set default $standardlanguage = 'english'; // check either _GET or _POST - if (isset($_GET['language']) - && isset($this->_languages[$_GET['language']]) - ) { + if (isset($_GET['language']) && isset($this->_languages[$_GET['language']])) { $this->_activelng = $_GET['language']; - } elseif (isset($_POST['language']) - && isset($this->_languages[$_POST['language']]) - ) { + } elseif (isset($_POST['language']) && isset($this->_languages[$_POST['language']])) { $this->_activelng = $_POST['language']; } else { // try to guess the right language @@ -1060,28 +1215,39 @@ class FroxlorInstall { } } - $lngfile = $this->_basepath.'/install/lng/' . $this->_activelng . '.lng.php'; + // require english base language as fallback + $lngfile = $this->_basepath . '/install/lng/' . $standardlanguage . '.lng.php'; if (file_exists($lngfile)) { // includes file /lng/$language.lng.php if it exists - require $lngfile; + require_once $lngfile; $this->_lng = $lng; } + + // require chosen language if not english + if ($this->_activelng != $standardlanguage) { + $lngfile = $this->_basepath . '/install/lng/' . $this->_activelng . '.lng.php'; + if (file_exists($lngfile)) { + // includes file /lng/$language.lng.php if it exists + require_once $lngfile; + $this->_lng = $lng; + } + } } /** * Get template from filesystem * - * @param string $template name of the template including subdirectory - * + * @param string $template + * name of the template including subdirectory + * * @return string */ - private function _getTemplate($template = null) { + private function _getTemplate($template = null) + { // build filename - $filename = $this->_basepath.'/install/templates/' . $template . '.tpl'; + $filename = $this->_basepath . '/install/templates/' . $template . '.tpl'; // check existence - if(file_exists($filename) - && is_readable($filename) - ) { + if (file_exists($filename) && is_readable($filename)) { $templatefile = addcslashes(file_get_contents($filename), '"\\'); // loop through template more than once in case we have an "if"-statement in another one while (preg_match('/(.*)(<\/if>|(.*)<\/if>)/Uis', $templatefile)) { @@ -1102,24 +1268,26 @@ class FroxlorInstall { * * @return string */ - private function _status_message($case, $text) { + private function _status_message($case, $text) + { if ($case == 'begin') { - return ''.$text; + return '' . $text; } else { - return ''.$text.''; + return '' . $text . ''; } } /** * get/guess servername */ - private function _guessServerName() { + private function _guessServerName() + { // from form? - if (!empty($_POST['servername'])) { + if (! empty($_POST['servername'])) { $this->_data['servername'] = $_POST['servername']; return; // from $_SERVER - } else if (!empty($_SERVER['SERVER_NAME'])) { + } else if (! empty($_SERVER['SERVER_NAME'])) { // no ips if ($this->_validate_ip($_SERVER['SERVER_NAME']) == false) { $this->_data['servername'] = $_SERVER['SERVER_NAME']; @@ -1133,13 +1301,14 @@ class FroxlorInstall { /** * get/guess serverip */ - private function _guessServerIP() { + private function _guessServerIP() + { // from form - if (!empty($_POST['serverip'])) { + if (! empty($_POST['serverip'])) { $this->_data['serverip'] = $_POST['serverip']; return; // from $_SERVER - } elseif(!empty($_SERVER['SERVER_ADDR'])) { + } elseif (! empty($_SERVER['SERVER_ADDR'])) { $this->_data['serverip'] = $_SERVER['SERVER_ADDR']; return; } @@ -1150,22 +1319,17 @@ class FroxlorInstall { /** * get/guess webserver-software */ - private function _guessWebserver() { + private function _guessWebserver() + { // post - if (!empty($_POST['webserver'])) { + if (! empty($_POST['webserver'])) { $this->_data['webserver'] = $_POST['webserver']; } else { - if (strtoupper(@php_sapi_name()) == "APACHE2HANDLER" - || stristr($_SERVER['SERVER_SOFTWARE'], "apache/2") - ) { - $this->_data['webserver'] = 'apache2'; - } elseif(substr(strtoupper(@php_sapi_name()), 0, 8) == "LIGHTTPD" - || stristr($_SERVER['SERVER_SOFTWARE'], "lighttpd") - ) { + if (strtoupper(@php_sapi_name()) == "APACHE2HANDLER" || stristr($_SERVER['SERVER_SOFTWARE'], "apache/2")) { + $this->_data['webserver'] = 'apache24'; + } elseif (substr(strtoupper(@php_sapi_name()), 0, 8) == "LIGHTTPD" || stristr($_SERVER['SERVER_SOFTWARE'], "lighttpd")) { $this->_data['webserver'] = 'lighttpd'; - } elseif(substr(strtoupper(@php_sapi_name()), 0, 8) == "NGINX" - || stristr($_SERVER['SERVER_SOFTWARE'], "nginx") - ) { + } elseif (substr(strtoupper(@php_sapi_name()), 0, 8) == "NGINX" || stristr($_SERVER['SERVER_SOFTWARE'], "nginx")) { $this->_data['webserver'] = 'nginx'; } else { // we don't need to bail out, since unknown does not affect any critical installation routines @@ -1174,6 +1338,42 @@ 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 = parse_ini_file('/etc/os-release', false); + 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 @@ -1182,7 +1382,8 @@ class FroxlorInstall { * @param string $default * */ - private function _getPostField($fieldname = null, $default = null) { + private function _getPostField($fieldname = null, $default = null) + { // initialize $this->_data[$fieldname] = ''; // set default @@ -1190,7 +1391,7 @@ class FroxlorInstall { $this->_data[$fieldname] = $default; } // check field - if (!empty($_POST[$fieldname])) { + if (! empty($_POST[$fieldname])) { $this->_data[$fieldname] = $_POST[$fieldname]; } } @@ -1202,11 +1403,9 @@ class FroxlorInstall { * * @return boolean|string */ - private function _validate_ip($ip = null) { - if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false - && filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false - && filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE) === false - ) { + private function _validate_ip($ip = null) + { + if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false && filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false && filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE) === false) { return false; } return $ip; @@ -1219,17 +1418,15 @@ class FroxlorInstall { * * @return string */ - private function _remove_remarks($sql) { - + private function _remove_remarks($sql) + { $lines = explode("\n", $sql); // try to keep mem. use down $sql = ""; $linecount = count($lines); $output = ""; - for ($i = 0; $i < $linecount; $i++) { - if ($i != ($linecount - 1) - || strlen($lines[$i]) > 0 - ) { + for ($i = 0; $i < $linecount; $i ++) { + if ($i != ($linecount - 1) || strlen($lines[$i]) > 0) { if (substr($lines[$i], 0, 1) != "#") { $output .= $lines[$i] . "\n"; } else { @@ -1249,7 +1446,8 @@ class FroxlorInstall { * The whole function has been taken from the phpbb installer, * copyright by the phpbb team, phpbb in summer 2004. */ - private function _split_sql_file($sql, $delimiter) { + private function _split_sql_file($sql, $delimiter) + { // Split up our string into "possible" SQL statements. $tokens = explode($delimiter, $sql); @@ -1263,11 +1461,9 @@ class FroxlorInstall { // this is faster than calling count($tokens) every time through the loop. $token_count = count($tokens); - for ($i = 0; $i < $token_count; $i++) { + for ($i = 0; $i < $token_count; $i ++) { // Don't want to add an empty string as the last thing in the array. - if (($i != ($token_count - 1)) - || (strlen($tokens[$i] > 0)) - ) { + if (($i != ($token_count - 1)) || (strlen($tokens[$i] > 0))) { // This is the total number of single quotes in the token. $total_quotes = preg_match_all("/'/", $tokens[$i], $matches); @@ -1291,7 +1487,7 @@ class FroxlorInstall { $tokens[$i] = ""; // Do we have a complete statement yet? $complete_stmt = false; - for ($j = $i + 1; (!$complete_stmt && ($j < $token_count)); $j++) { + for ($j = $i + 1; (! $complete_stmt && ($j < $token_count)); $j ++) { // This is the total number of single quotes in the token. $total_quotes = preg_match_all("/'/", $tokens[$j], $matches); // Counts single quotes that are preceded by an odd number of backslashes, @@ -1323,5 +1519,4 @@ class FroxlorInstall { } return $output; } - } diff --git a/install/lib/updateFunctions.php b/install/lib/updateFunctions.php new file mode 100644 index 00000000..2b35ee4d --- /dev/null +++ b/install/lib/updateFunctions.php @@ -0,0 +1,88 @@ + (2010-) + * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt + * @package Functions + * + */ + +/** + * Function showUpdateStep + * + * outputs and logs the current + * update progress + * + * @param + * string task/status + * @param + * bool needs_status (if false, a linebreak will be added) + * + * @return string formatted output and log-entry + */ +function showUpdateStep($task = null, $needs_status = true) +{ + set_time_limit(30); + if (! $needs_status) + echo ""; + + // output + echo $task; + + if (! $needs_status) { + echo "
"; + } + + \Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, $task); +} + +/** + * Function lastStepStatus + * + * outputs [OK] (success), [??] (warning) or [!!] (failure) + * of the last update-step + * + * @param + * int status (0 = success, 1 = warning, 2 = failure) + * + * @return string formatted output and log-entry + */ +function lastStepStatus($status = -1, $message = '') +{ + switch ($status) { + + case 0: + $status_sign = ($message != '') ? '[' . $message . ']' : '[OK]'; + $status_color = 'ok'; + break; + case 1: + $status_sign = ($message != '') ? '[' . $message . ']' : '[??]'; + $status_color = 'warn'; + break; + case 2: + $status_sign = ($message != '') ? '[' . $message . ']' : '[!!]'; + $status_color = 'err'; + break; + default: + $status_sign = '[unknown]'; + $status_color = 'unknown'; + break; + } + + // output + echo "" . $status_sign . "
"; + + if ($status == - 1 || $status == 2) { + \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 bab624aa..69c06ced 100644 --- a/install/lng/english.lng.php +++ b/install/lng/english.lng.php @@ -16,27 +16,32 @@ * @package Language * */ - $lng['requirements']['title'] = 'Checking system requirements...'; $lng['requirements']['installed'] = 'installed'; $lng['requirements']['not_true'] = 'no'; $lng['requirements']['notfound'] = 'not found'; $lng['requirements']['notinstalled'] = 'not installed'; $lng['requirements']['activated'] = 'enabled'; -$lng['requirements']['phpversion'] = 'PHP version >= 5.3'; -$lng['requirements']['phpmagic_quotes_runtime'] = 'magic_quotes_runtime...'; -$lng['requirements']['phpmagic_quotes_runtime_description'] = 'PHP setting "magic_quotes_runtime" must be set to "Off". We have disabled it temporary for now please fix the coresponding php.ini.'; +$lng['requirements']['phpversion'] = 'PHP version >= 7.0'; +$lng['requirements']['newerphpprefered'] = 'Good, but php-7.1 is prefered.'; $lng['requirements']['phppdo'] = 'PHP PDO extension and PDO-MySQL driver...'; +$lng['requirements']['phpsession'] = 'PHP session-extension...'; +$lng['requirements']['phpctype'] = 'PHP ctype-extension...'; +$lng['requirements']['phpsimplexml'] = 'PHP SimpleXML-extension...'; $lng['requirements']['phpxml'] = 'PHP XML-extension...'; $lng['requirements']['phpfilter'] = 'PHP filter-extension...'; $lng['requirements']['phpposix'] = 'PHP posix-extension...'; $lng['requirements']['phpbcmath'] = 'PHP bcmath-extension...'; $lng['requirements']['phpcurl'] = 'PHP curl-extension...'; $lng['requirements']['phpmbstring'] = 'PHP mbstring-extension...'; +$lng['requirements']['phpzip'] = 'PHP zip-extension...'; +$lng['requirements']['phpjson'] = 'PHP json-extension...'; $lng['requirements']['bcmathdescription'] = 'Traffic-calculation related functions will not work correctly!'; -$lng['requirements']['curldescription'] = 'Version-check and news-feed may 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']['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.'; $lng['requirements']['froxlor_succ_checks'] = 'All requirements are satisfied'; @@ -58,10 +63,11 @@ $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'; -$lng['install']['apache2'] = 'Apache 2'; +$lng['install']['apache2'] = 'Apache 2.2'; $lng['install']['apache24'] = 'Apache 2.4'; $lng['install']['lighttpd'] = 'LigHTTPd'; $lng['install']['nginx'] = 'NGINX'; @@ -81,8 +87,8 @@ $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 lib/.'; -$lng['install']['creating_configfile_failed'] = 'Could not create lib/userdata.inc.php, please create it manually with the following content:'; +$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.'; $lng['click_here_to_refresh'] = 'Click here to check again'; diff --git a/install/lng/french.lng.php b/install/lng/french.lng.php index ddcf815d..a3aacc6a 100644 --- a/install/lng/french.lng.php +++ b/install/lng/french.lng.php @@ -16,16 +16,13 @@ * @package Language * */ - $lng['requirements']['title'] = 'Vérification des prérequis système...'; $lng['requirements']['installed'] = 'installé'; $lng['requirements']['not_true'] = 'non'; $lng['requirements']['notfound'] = 'introuvable'; $lng['requirements']['notinstalled'] = 'non installé'; $lng['requirements']['activated'] = 'activé'; -$lng['requirements']['phpversion'] = 'PHP version >= 5.3'; -$lng['requirements']['phpmagic_quotes_runtime'] = 'magic_quotes_runtime...'; -$lng['requirements']['phpmagic_quotes_runtime_description'] = 'Le réglage PHP "magic_quotes_runtime" doit être positionné à "Off". Nous l\'avons désactivé temporairement pour l\'instant; merci de corriger le php.ini correspondant.'; +$lng['requirements']['phpversion'] = 'PHP version >= 7.0'; $lng['requirements']['phppdo'] = 'extension PHP PDO et pilote PDO-MySQL ...'; $lng['requirements']['phpxml'] = 'extension PHP XML...'; $lng['requirements']['phpfilter'] = 'extension PHP filter ...'; @@ -34,7 +31,6 @@ $lng['requirements']['phpbcmath'] = 'extension PHP bcmath ...'; $lng['requirements']['phpcurl'] = 'extension PHP curl...'; $lng['requirements']['phpmbstring'] = 'extension PHP mbstring...'; $lng['requirements']['bcmathdescription'] = 'Les fonctions de calcul de traffic ne fonctionneront pas correctement!'; -$lng['requirements']['curldescription'] = 'Les vérifications de version et les flux d\'information peuvent ne pas fonctionner correctement!'; $lng['requirements']['openbasedir'] = 'open_basedir...'; $lng['requirements']['openbasedirenabled'] = 'Froxlor ne fonctionnera pas correctement avec open_basedir activé. Merci de désactiver open_basedir pour Froxlor dans le php.ini correspondant'; $lng['requirements']['diedbecauseofrequirements'] = 'Impossible d\'installer Froxlor sans ces prérequis! Essayez de les corriger et essayez à nouveau.'; @@ -57,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'; @@ -80,8 +77,8 @@ $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 lib/.'; -$lng['install']['creating_configfile_failed'] = 'Impossible de créer lib/userdata.inc.php, merci de le créer manuellement avec le contenu suivant:'; +$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.'; $lng['click_here_to_refresh'] = 'Cliquez ici pour vérifier à nouveau'; diff --git a/install/lng/german.lng.php b/install/lng/german.lng.php index dd60e772..4c0aaf68 100644 --- a/install/lng/german.lng.php +++ b/install/lng/german.lng.php @@ -16,27 +16,32 @@ * @package Language * */ - $lng['requirements']['title'] = 'Prüfe Systemvoraussetzungen...'; $lng['requirements']['installed'] = 'installiert'; $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 >= 5.3'; -$lng['requirements']['phpmagic_quotes_runtime'] = 'magic_quotes_runtime'; -$lng['requirements']['phpmagic_quotes_runtime_description'] = 'Die PHP Einstellung "magic_quotes_runtime" muss deaktiviert sein ("Off"). Die Einstellung wurde temporär deaktiviert, bitte ändern Sie diese in der entsprechenden php.ini.'; +$lng['requirements']['phpversion'] = 'PHP Version >= 7.0'; +$lng['requirements']['newerphpprefered'] = 'Passt, aber php-7.1 wird bevorzugt.'; $lng['requirements']['phppdo'] = 'PHP PDO Erweiterung und PDO-MySQL Treiber...'; +$lng['requirements']['phpsession'] = 'PHP session-Erweiterung...'; +$lng['requirements']['phpctype'] = 'PHP ctype-Erweiterung...'; +$lng['requirements']['phpsimplexml'] = 'PHP SimpleXML-Erweiterung...'; $lng['requirements']['phpxml'] = 'PHP XML-Erweiterung...'; $lng['requirements']['phpfilter'] = 'PHP filter-Erweiterung...'; $lng['requirements']['phpposix'] = 'PHP posix-Erweiterung...'; $lng['requirements']['phpbcmath'] = 'PHP bcmath-Erweiterung...'; $lng['requirements']['phpcurl'] = 'PHP curl-Erweiterung...'; $lng['requirements']['phpmbstring'] = 'PHP mbstring-Erweiterung...'; +$lng['requirements']['phpzip'] = 'PHP zip-Erweiterung...'; +$lng['requirements']['phpjson'] = 'PHP json-Erweiterung...'; $lng['requirements']['bcmathdescription'] = 'Traffic-Berechnungs bezogene Funktionen stehen nicht vollständig zur Verfügung!'; -$lng['requirements']['curldescription'] = 'Versions-Prüfung und News-Feed stehen nicht vollständig zur Verfügung!'; +$lng['requirements']['zipdescription'] = 'Die Auto-Update Funktion benötigt die zip Erweiterung.'; $lng['requirements']['openbasedir'] = 'open_basedir genutzt wird...'; $lng['requirements']['openbasedirenabled'] = 'Froxlor wird mit aktiviertem open_basedir nicht vollständig funktionieren. Bitte deaktivieren Sie open_basedir für Froxlor in der entsprechenden php.ini'; +$lng['requirements']['mysqldump'] = 'MySQL dump Tool'; +$lng['requirements']['mysqldumpmissing'] = 'Ein automatisches Backup einer möglicherweise schon existierenden Datenbank nicht möglich. Bitte mysql-client installieren'; $lng['requirements']['diedbecauseofrequirements'] = 'Kann Froxlor ohne diese Voraussetzungen nicht installieren! Beheben Sie die angezeigten Probleme und versuchen Sie es erneut.'; $lng['requirements']['froxlor_succ_checks'] = 'Alle Vorraussetzungen sind erfüllt'; @@ -58,6 +63,7 @@ $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'; @@ -81,8 +87,8 @@ $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 lib/ verschieben.'; -$lng['install']['creating_configfile_failed'] = 'Konnte lib/userdata.inc.php nicht erstellen, bitte manuell mit folgendem Inhalt anlegen:'; +$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.'; $lng['click_here_to_refresh'] = 'Hier klicken, um erneut zu prüfen'; diff --git a/install/scripts/config-services.php b/install/scripts/config-services.php new file mode 100755 index 00000000..f95f7dc1 --- /dev/null +++ b/install/scripts/config-services.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\ConfigServicesCmd::processParameters($argc, $argv); +} catch (Exception $e) { + \Froxlor\Cli\ConfigServicesCmd::printerr($e->getMessage()); +} diff --git a/install/scripts/language-check.php b/install/scripts/language-check.php deleted file mode 100644 index 17c8463a..00000000 --- a/install/scripts/language-check.php +++ /dev/null @@ -1,160 +0,0 @@ - - * @license GPLv2 http://files.syscp.org/misc/COPYING.txt - * @package System - * - */ - -// some configs -$baseLanguage = 'english.lng.php'; - -// Check if we're in the CLI -if(@php_sapi_name() != 'cli' - && @php_sapi_name() != 'cgi' - && @php_sapi_name() != 'cgi-fcgi' -) { - die('This script will only work in the shell.'); -} - -// Check argument count -/* -if (sizeof($argv) != 2) { - print_help($argv); - exit; -} -*/ - -// Load the contents of the given path -$path = $argv[1]; -$_f = isset($argv[2]) ? $argv[2] : null; -$files = array(); - -if ($dh = opendir($path)) { - while (false !== ($file = readdir($dh))) { - if ($file != "." - && $file != ".." - && !is_dir($file) - && preg_match('/(.+)\.lng\.php/i', $file) - ) { - if (is_null($_f) || (!is_null($_f) && ($file == $_f || $file == $baseLanguage))) { - $files[$file] = str_replace('//', '/', $path . '/' . $file); - } - } - } - - closedir($dh); -} else { - print "ERROR: The path you requested cannot be read! \n "; - print "\n"; - print_help($argv); - exit; -} - -// check if there is the default language defined -if (!isset($files[$baseLanguage])) { - print "ERROR: The baselanguage cannot be found! \n"; - print "\n"; - print_help($argv); - exit; -} - -// import the baselanguage -$base = import($files[$baseLanguage]); - -// and unset it in the files, because we don't need to compare base to base -unset($files[$baseLanguage]); - -// compare each language with the baselanguage -foreach ($files as $key => $file) { - $comp = import($file); - - print "\n\nComparing " . $baseLanguage . " to " . $key . "\n"; - $result = compare($base, $comp); - - if (is_array($result) - && sizeof($result) > 0 - ) { - print " found missing strings: \n"; - foreach ($result as $value) { - print " " . $value . "\n"; - } - } else { - print " no missing strings found! \n "; - } - - print "\nReverse Checking " . $key . " to " . $baseLanguage . "\n"; - $result = compare($comp, $base); - - if (is_array($result) - && sizeof($result) > 0 - ) { - print " found strings not in basefile: \n"; - foreach ($result as $key => $value) { - print " " . $value . "\n"; - } - } else { - print " There are no strings which are not in the basefile! \n "; - } -} - -//----------------------------------------------------------------------------------------- -// FUNCTIONS -//----------------------------------------------------------------------------------------- - -/** - * prints the help screen - * - * @param array $argv - */ -function print_help($argv) { - print "Usage: php " . $argv[0] . " /PATH/TO/LNG \n"; - print " \n "; -} - -function import($file) { - - $input = file($file); - $return = array(); - - foreach ($input as $key => $value) { - - if (!preg_match('/^\$/', $value)) { - unset($input[$key]); - } else { - // generate the key - $key = preg_replace('/^\$lng\[\'(.*)=(.*)$/U', '\\1', $value); - $key = str_replace('[\'', '/', $key); - $key = trim(str_replace('\']', '', $key)); - - //generate the value - $value = trim($value); - - // set the result - $return[$key] = $value; - } - } - return $return; -} - -function compare($array1, $array2) { - - $result = array(); - - foreach ($array1 as $key => $value) { - - if (!isset($array2[$key])) { - $result[$key] = $value; - } - } - return $result; -} diff --git a/install/scripts/switch-server-ip.php b/install/scripts/switch-server-ip.php new file mode 100755 index 00000000..7727dd36 --- /dev/null +++ b/install/scripts/switch-server-ip.php @@ -0,0 +1,31 @@ +#!/usr/bin/php + (2016-) + * @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\SwitchServerIpCmd::processParameters($argc, $argv); +} catch (Exception $e) { + \Froxlor\Cli\SwitchServerIpCmd::printerr($e->getMessage()); +} diff --git a/install/scripts/update-cli.php b/install/scripts/update-cli.php new file mode 100755 index 00000000..1afd5d71 --- /dev/null +++ b/install/scripts/update-cli.php @@ -0,0 +1,32 @@ +#!/usr/bin/php + (2016-) + * @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 { + $argv[] = '--run'; + \Froxlor\Cli\UpdateCliCmd::processParameters($argc, $argv); +} catch (Exception $e) { + \Froxlor\Cli\UpdateCliCmd::printerr($e->getMessage()); +} diff --git a/install/templates/assets/css/install.css b/install/templates/assets/css/install.css index d5a3d3b0..ccc8ccba 100644 --- a/install/templates/assets/css/install.css +++ b/install/templates/assets/css/install.css @@ -1,37 +1,65 @@ @charset "UTF-8"; /* RESET */ -html,body,div,ul,ol,li,dl,dt,dd,h1,h2,h3,h4,h5,h6,pre,form,p,blockquote,fieldset,input { margin:0; padding:0; } -h1,h2,h3,h4,h5,h6,pre,code,address,caption,cite,code,em,strong,th { font-size:1em; font-weight:400; font-style:normal; } -ul,ol { list-style:none; } -fieldset,img { border:none; } -caption,th { text-align:left; } -table { border-collapse:collapse; border-spacing:0; } -article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section { display:block; } +html, body, div, ul, ol, li, dl, dt, dd, h1, h2, h3, h4, h5, h6, pre, + form, p, blockquote, fieldset, input { + margin: 0; + padding: 0; +} + +h1, h2, h3, h4, h5, h6, pre, code, address, caption, cite, code, em, + strong, th { + font-size: 1em; + font-weight: 400; + font-style: normal; +} + +ul, ol { + list-style: none; +} + +fieldset, img { + border: none; +} + +caption, th { + text-align: left; +} + +table { + border-collapse: collapse; + border-spacing: 0; +} + +article, aside, details, figcaption, figure, footer, header, hgroup, + menu, nav, section { + display: block; +} /* TYPE */ -html,body { - font:12px/18px 'Lucida Grande','Lucida Sans Unicode',Helvetica,Arial,Verdana,sans-serif; +html, body { + font: 12px/18px 'Lucida Grande', 'Lucida Sans Unicode', Helvetica, Arial, + Verdana, sans-serif; background-color: #f5f5f5; - color:#444; + color: #444; -webkit-font-smoothing: subpixel-antialiased; } body { - margin:0; - padding:0; + margin: 0; + padding: 0; } .dark { background-color: #e9edf0; - border-bottom:1px solid #d1d5d8; + border-bottom: 1px solid #d1d5d8; } header img { - padding:10px 0 10px 10px; + padding: 10px 0 10px 10px; } h1 { - display:none; + display: none; } h2, h3 { @@ -41,47 +69,43 @@ h2, h3 { } h2 { - font-size:17px; + font-size: 17px; } h3 { font-size: 15px; } - img { - border:0; - vertical-align:middle; + border: 0; + vertical-align: middle; } td a { - text-decoration:none; + text-decoration: none; } .bradius { border-radius: 5px 5px 5px 5px; - box-shadow: rgba(0, 0, 0, 0.34902) 0px 1px 3px 0px; + box-shadow: rgba(0, 0, 0, 0.34902) 0 1px 3px 0; } /* FOOTER */ footer { - clear:both; - text-align:center; + clear: both; + text-align: center; color: #888; - font-size:10px !important; + font-size: 10px !important; margin: 10px 0; } -footer a,footer a:active,footer a:visited { +footer a, footer a:active, footer a:visited { color: #888; } .install { - background-color:#fff; - margin: 20px; - margin-left: auto; - margin-right: auto; - margin-bottom: 12px; + background-color: #fff; + margin: 20px auto 12px; width: 800px; } @@ -90,14 +114,14 @@ p { } .installsec { - margin-top:10px; - padding:0; - text-align:left; + margin-top: 10px; + padding: 0; + text-align: left; } .installsec table { - width:100%; - padding:0 10px; + width: 100%; + padding: 0 10px; margin: 15px 0 15px 0; } @@ -109,42 +133,46 @@ p { } .installsec form { - width:800px; - margin:0 auto; - padding:10px 0 0; - text-align:left; + width: 800px; + margin: 0 auto; + padding: 10px 0 0; + text-align: left; } .installsec fieldset { - border:0; - float:left; - clear:left; - width:600px; - margin:0 100px 10px; - padding:0; + border: 0; + float: left; + clear: left; + width: 600px; + margin: 0 100px 10px; + padding: 0; +} + +.installsec fieldset p, .installsec fieldset h3 { + clear: both; } .installsec legend { - display:none; + display: none; } .installsec label { - float:left; - margin-right:0; - margin-top:8px; - text-align:left; + float: left; + margin-right: 0; + margin-top: 8px; + text-align: left; } p.submit { - text-align:right; - padding-right:46px; + text-align: right; + padding-right: 46px; } .installsec aside { - border-top:1px solid #d1d5d8; - clear:both; - float:none; - width:auto; + border-top: 1px solid #d1d5d8; + clear: both; + float: none; + width: auto; text-align: right; padding: 10px; } @@ -152,182 +180,183 @@ p.submit { .line { border: 0; width: 800px; - border-bottom:1px solid #d1d5d8; + border-bottom: 1px solid #d1d5d8; } .messagewrapper { - width:650px; - margin:0 auto; - padding:120px 0 0; - overflow:hidden; + width: 650px; + margin: 0 auto; + padding: 120px 0 0; + overflow: hidden; } .messagewrapperfull { - width:100%; - margin:0 auto; - padding:0; - overflow:hidden; + width: 100%; + margin: 0 auto; + padding: 0; + overflow: hidden; } .overviewsearch { - position:absolute; - top:155px; - right:36px; - font-size:80%; + position: absolute; + top: 155px; + right: 36px; + font-size: 80%; } .overviewadd { - padding:10px; - font-weight:700; + padding: 10px; + font-weight: 700; } /* * error message display */ .errorcontainer { - background:url(../img/icons/error_big.png) 10px center no-repeat #ffedef; - border:1px solid #ffc2ca; - padding:10px 10px 10px 68px!important; + background: url(../img/icons/error_big.png) 10px center no-repeat + #ffedef; + border: 1px solid #ffc2ca; + padding: 10px 10px 10px 68px !important; margin: 10px 0 10px 0 !important; - text-align:left!important; - overflow:hidden; - box-shadow: 0px 0px 0px black; + text-align: left !important; + overflow: hidden; + box-shadow: 0 0 0 black; } .errortitle { - font-weight:700; - color:#c00!important; + font-weight: 700; + color: #c00 !important; } .error { - font-weight:400!important; - color:#c00!important; + font-weight: 400 !important; + color: #c00 !important; } /* * warning message display */ -.warningcontainer,.ui-dialog { - background:url(../img/icons/warning_big.png) 10px center no-repeat #fffecc; - border:1px solid #f3c37e; - padding:10px 10px 10px 68px !important; +.warningcontainer, .ui-dialog { + background: url(../img/icons/warning_big.png) 10px center no-repeat + #fffecc; + border: 1px solid #f3c37e; + padding: 10px 10px 10px 68px !important; margin: 10px 0 10px 0 !important; - text-align:left!important; - overflow:hidden; - box-shadow: 0px 0px 0px black; + text-align: left !important; + overflow: hidden; + box-shadow: 0 0 0 black; } + .ui-dialog { padding: 10px !important; } -.warningtitle,.ui-dialog-titlebar { - font-weight:700; - color:#D57D00; +.warningtitle, .ui-dialog-titlebar { + font-weight: 700; + color: #D57D00; } -.warning,.ui-dialog-content { - color:#D57D00!important; +.warning, .ui-dialog-content { + color: #D57D00 !important; } /* * success message display */ .successcontainer { - background:url(../img/icons/ok_big.png) 10px center no-repeat #E2F9E3; - border:1px solid #9C9; - padding:10px 10px 10px 68px!important; + background: url(../img/icons/ok_big.png) 10px center no-repeat #E2F9E3; + border: 1px solid #9C9; + padding: 10px 10px 10px 68px !important; margin: 10px 0 10px 0 !important; - text-align:left!important; - overflow:hidden; - box-shadow: 0px 0px 0px black; + text-align: left !important; + overflow: hidden; + box-shadow: 0 0 0 black; } .successtitle { - font-weight:700; - color:#060!important; + font-weight: 700; + color: #060 !important; } .success { - font-weight:400!important; + font-weight: 400 !important; } /* * neutral/info message display */ .neutralcontainer { - background:url(../img/icons/info_big.png) 10px center no-repeat #d2eaf6; - border:1px solid #b7d8ed; - padding:10px 10px 10px 68px!important; + background: url(../img/icons/info_big.png) 10px center no-repeat #d2eaf6; + border: 1px solid #b7d8ed; + padding: 10px 10px 10px 68px !important; margin: 10px 0 10px 0 !important; - text-align:left!important; - overflow:hidden; - box-shadow: 0px 0px 0px black; + text-align: left !important; + overflow: hidden; + box-shadow: 0 0 0 black; } .neutraltitle { - font-weight:700; - color:#3188c1!important; + font-weight: 700; + color: #3188c1 !important; } .neutral { - font-weight:400!important; - color:#3188c1!important; + font-weight: 400 !important; + color: #3188c1 !important; } /* std hyperlink */ -a,a:active,a:visited { - color:#176fa1; - text-decoration:none; +a, a:active, a:visited { + color: #176fa1; + text-decoration: none; } a:hover { - text-decoration:underline; + text-decoration: underline; } .infotext { - font-size:11px; + font-size: 11px; } /* * main container */ .main { - margin-left:240px; - margin-right:10px; - margin-top:105px; - margin-bottom:0; - background-color:#fff; + margin: 105px 10px 0 240px; + background-color: #fff; padding: 30px 30px 30px 30px; - min-height:400px; + min-height: 400px; } .noborder { - width:100%; - border-spacing:0; - border-collapse:separate; + width: 100%; + border-spacing: 0; + border-collapse: separate; border: 0; } .noborder td { - border:0; + border: 0; } table { - width:100%; - border-spacing:0; - border:1px solid #d1d5d8; - border-collapse:separate; - box-shadow:0px 0px 0px black !important; + width: 100%; + border-spacing: 0; + border: 1px solid #d1d5d8; + border-collapse: separate; + box-shadow: 0 0 0 black !important; } table thead th, table th { border-top: 1px solid #d1d5d8; border-bottom: 1px solid #d1d5d8; height: 25px !important; - padding: 5px 0px 5px 8px; + padding: 5px 0 5px 8px; background-color: #e9edf0; font-weight: bold; } + table thead:first-child th, table:first-child th { border-top: none !important; } @@ -335,16 +364,21 @@ table thead:first-child th, table:first-child th { table th { border-top: 0; } + th a:hover { text-decoration: none; } + th a img { + } + th a:nth-child(odd) img { position: relative; top: -5px; left: 4px; } + th a:nth-child(even) img { position: relative; top: 3px; @@ -360,85 +394,83 @@ table thead:first-child th { } table tbody td { - border-bottom:1px dotted #ccc; + border-bottom: 1px dotted #ccc; } + table tbody tr:last-child td { border-bottom: 0; } .formtable { width: 100%; - border-spacing:0; - border:0; - border-collapse:separate; - margin:0 0 0; + border-spacing: 0; + border: 0; + border-collapse: separate; + margin: 0 0 0; } .formtable tbody td { - border:0; - border-bottom:1px dotted #ccc; + border: 0; + border-bottom: 1px dotted #ccc; min-height: 20px; } .formtable label { - float:none; - display:block; - padding:0; - margin:0; - width:100%; - text-align:left; + float: none; + display: block; + padding: 0; + margin: 0; + width: 100%; + text-align: left; } td { - padding-top:5px; - padding-left:10px; - padding-right: 10px; - padding-bottom:5px; + padding: 5px 10px; min-height: 20px; } table tfoot td { - height:25px; + height: 25px; border-top: 1px solid #d1d5d8; background-color: #f2f8fa; } .tfootleft { - text-align:left; + text-align: left; } .maintitle { - padding-top:20px; + padding-top: 20px; } /* input elements */ input { background: #fff url(../img/text_align_left.png) no-repeat 5px 4px; color: #333; - padding:2px 4px 2px 24px; - height:22px; + padding: 2px 4px 2px 24px; + height: 22px; border: 1px solid #d9d9d9; margin-bottom: 5px; border-radius: 3px; } textarea { - background:#fff url(../img/text_align_left.png) no-repeat 5px 4px; + background: #fff url(../img/text_align_left.png) no-repeat 5px 4px; color: #333; - padding:4px 4px 2px 24px; - border:1px solid #d9d9d9; + padding: 4px 4px 2px 24px; + border: 1px solid #d9d9d9; margin-bottom: 5px; border-radius: 3px; } input[type="password"] { - background:#fff url(../img/password.png) no-repeat 5px 4px; + background: #fff url(../img/password.png) no-repeat 5px 4px; } /* * BUTTONS */ -input[type="button"],input[type="submit"],input[type="reset"] { +input[type="button"], input[type="submit"], input[type="reset"] { margin: 0 5px; padding: 5px 14px; outline: 0; @@ -447,47 +479,57 @@ input[type="button"],input[type="submit"],input[type="reset"] { min-width: 80px; height: 26px; background-image: none; - border-width: 0px; } -.loginsec input[type="button"], .loginsec input[type="submit"], .loginsec input[type="reset"] { + +.loginsec input[type="button"], .loginsec input[type="submit"], + .loginsec input[type="reset"] { margin: 0 1px; } -input[type="button"]:hover,input[type="submit"]:hover,input[type="reset"]:hover { - color: #333; - background-color: #dcdcdc; + +input[type="button"]:hover, input[type="submit"]:hover, input[type="reset"]:hover + { + color: #333; + background-color: #dcdcdc; } -input[type="button"]:active,input[type="submit"]:active,input[type="reset"]:active { - -webkit-box-shadow: inset 0 1px 8px rgba(0, 0, 0, 0.25); - -moz-box-shadow: inset 0 1px 8px rgba(0, 0, 0, 0.25); - box-shadow: inset 0 1px 8px rgba(0, 0, 0, 0.25); - color: white !important; + +input[type="button"]:active, input[type="submit"]:active, input[type="reset"]:active + { + -webkit-box-shadow: inset 0 1px 8px rgba(0, 0, 0, 0.25); + -moz-box-shadow: inset 0 1px 8px rgba(0, 0, 0, 0.25); + box-shadow: inset 0 1px 8px rgba(0, 0, 0, 0.25); + color: white !important; } -input[type="submit"],input[class="yesbutton"] { - color: white; - background-color: #35aa47; -} -input[type="submit"]:hover,input[class="yesbutton"]:hover { + +input[type="submit"], input[class="yesbutton"] { color: white; - background-color: #1d943b; -} -input[class="submit"]:active,input[class="yesbutton"]:active { background-color: #35aa47; } -input[class="nobutton"],input[type="reset"] { - color: white; - background-color: #d84a38; -} -input[class="nobutton"]:hover,input[type="reset"]:hover { + +input[type="submit"]:hover, input[class="yesbutton"]:hover { color: white; - background-color: #c53727; -} -input[class="nobutton"]:active,input[type="reset"]:active { - background-color: #dd4b39; + background-color: #1d943b; } +input[class="submit"]:active, input[class="yesbutton"]:active { + background-color: #35aa47; +} + +input[class="nobutton"], input[type="reset"] { + color: white; + background-color: #d84a38; +} + +input[class="nobutton"]:hover, input[type="reset"]:hover { + color: white; + background-color: #c53727; +} + +input[class="nobutton"]:active, input[type="reset"]:active { + background-color: #dd4b39; +} input[type="checkbox"] { - background:#dae7ee; + background: #dae7ee; padding: 0; margin: 0 5px 0 0; vertical-align: middle; @@ -495,73 +537,101 @@ input[type="checkbox"] { } input[type="radio"] { + vertical-align: middle; margin: 0 10px 0 10px; - height:22px; + height: 22px; } select { - background:#fff; - padding:4px; + background: #fff; + padding: 4px; color: #333; - border:1px solid #d9d9d9; + border: 1px solid #d9d9d9; margin-bottom: 5px; min-width: 100px; } + select.dropdown { padding: 2px 4px 2px 24px; height: 26px; border: 1px solid #d9d9d9; margin-bottom: 5px; border-radius: 3px; - background: url(../../../../templates/Sparkle/assets/img/icons/down.png) no-repeat 9px; + background: url(../../../../templates/Sparkle/assets/img/icons/down.png) + no-repeat 9px; -webkit-appearance: none; - -moz-appearance: none; - appearance: none; + -moz-appearance: none; + appearance: none; } .maintable { - width:90%; + width: 90%; } .update_progess { - padding:2em; - text-align:left; + padding: 2em; + text-align: left; } .preconfig { - text-align:left; - margin-top:20px; - margin-bottom:5px; - margin-right:15px; - margin-left:15px; + text-align: left; + margin-top: 20px; + margin-bottom: 5px; + margin-right: 15px; + margin-left: 15px; } .preconfigitem { - padding:.15em; - border-bottom:1px solid #ccc; + padding: .15em; + border-bottom: 1px solid #ccc; } .preconfdesc { - display:block; - margin-bottom:.5em; - font-size:120%; -} -.installprogress { - width: 100%; - background-color:#e4e4e4; - height:5px; - border-bottom:1px solid #d1d5d8; -} -.installprogress .bar { - background-color: #35aa47; - height:5px; + display: block; + margin-bottom: .5em; + font-size: 120%; } -.red { color: #ff0000; } -.green { color: green; } -.orange { color: orange; } -.blue { color: blue; } -.install-block { width: 65%; } -.install-step { width: 250px; } -.install-h3 { text-align: center; } -.install-text { margin: 20px 20px 0 !important; } +.installprogress { + width: 100%; + background-color: #e4e4e4; + height: 5px; + border-bottom: 1px solid #d1d5d8; +} + +.installprogress .bar { + background-color: #35aa47; + height: 5px; +} + +.red { + color: #ff0000; +} + +.green { + color: green; +} + +.orange { + color: orange; +} + +.blue { + color: blue; +} + +.install-block { + width: 65%; +} + +.install-step { + width: 250px; +} + +.install-h3 { + text-align: center; +} + +.install-text { + margin: 20px 20px 0 !important; +} \ No newline at end of file diff --git a/install/templates/dataitem.tpl b/install/templates/dataitem.tpl index 26e63e02..845aeb11 100644 --- a/install/templates/dataitem.tpl +++ b/install/templates/dataitem.tpl @@ -1,4 +1,4 @@

-   +

diff --git a/install/templates/dataitemchk.tpl b/install/templates/dataitemchk.tpl index 9211c223..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 new file mode 100644 index 00000000..101c65e2 --- /dev/null +++ b/install/updates/froxlor/0.10/update_0.10.inc.php @@ -0,0 +1,713 @@ + (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'] == '')) { + header('Location: ../../../../index.php'); + exit(); + } +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.40.1')) { + showUpdateStep("Updating from 0.9.40.1 to 0.10.0-rc1", false); + + showUpdateStep("Adding new api keys table"); + Database::query("DROP TABLE IF EXISTS `api_keys`;"); + $sql = "CREATE TABLE `api_keys` ( + `id` int(11) NOT NULL auto_increment, + `adminid` int(11) NOT NULL default '0', + `customerid` int(11) NOT NULL default '0', + `apikey` varchar(500) NOT NULL default '', + `secret` varchar(500) NOT NULL default '', + `allowed_from` text NOT NULL, + `valid_until` int(15) NOT NULL default '0', + PRIMARY KEY (id), + KEY adminid (adminid), + KEY customerid (customerid) + ) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci;"; + Database::query($sql); + lastStepStatus(0); + + showUpdateStep("Adding new api settings"); + Settings::AddNew('api.enabled', 0); + lastStepStatus(0); + + showUpdateStep("Adding new default-ssl-ip setting"); + Settings::AddNew('system.defaultsslip', ''); + lastStepStatus(0); + + showUpdateStep("Altering admin ip's field to allow multiple ip addresses"); + // get all admins for updating the new field + $sel_stmt = Database::prepare("SELECT adminid, ip FROM `panel_admins`"); + Database::pexecute($sel_stmt); + $all_admins = $sel_stmt->fetchAll(PDO::FETCH_ASSOC); + Database::query("ALTER TABLE `panel_admins` MODIFY `ip` varchar(500) NOT NULL default '-1';"); + $upd_stmt = Database::prepare("UPDATE `panel_admins` SET `ip` = :ip WHERE `adminid` = :adminid"); + foreach ($all_admins as $adm) { + if ($adm['ip'] != '-1') { + Database::pexecute($upd_stmt, array( + 'ip' => json_encode($adm['ip']), + 'adminid' => $adm['adminid'] + )); + } + } + lastStepStatus(0); + + \Froxlor\Froxlor::updateToVersion('0.10.0-rc1'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201809280')) { + + showUpdateStep("Adding dhparams-file setting"); + Settings::AddNew("system.dhparams_file", ''); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201811180'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201811180')) { + + showUpdateStep("Adding new settings for 2FA"); + Settings::AddNew('2fa.enabled', '1', true); + lastStepStatus(0); + + showUpdateStep("Adding new fields to admin-table for 2FA"); + Database::query("ALTER TABLE `" . TABLE_PANEL_ADMINS . "` ADD `type_2fa` tinyint(1) NOT NULL default '0';"); + Database::query("ALTER TABLE `" . TABLE_PANEL_ADMINS . "` ADD `data_2fa` varchar(500) NOT NULL default '' AFTER `type_2fa`;"); + lastStepStatus(0); + + showUpdateStep("Adding new fields to customer-table for 2FA"); + Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` ADD `type_2fa` tinyint(1) NOT NULL default '0';"); + Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` ADD `data_2fa` varchar(500) NOT NULL default '' AFTER `type_2fa`;"); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201811300'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201811300')) { + + showUpdateStep("Adding new logview-flag to customers"); + Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` ADD `logviewenabled` tinyint(1) NOT NULL default '0';"); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201812010'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201812010')) { + + showUpdateStep("Adding new is_configured-flag"); + // updated systems are already configured (most likely :P) + Settings::AddNew('panel.is_configured', '1', true); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201812100'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201812100')) { + + showUpdateStep("Adding fields writeaccesslog and writeerrorlog for domains"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `writeaccesslog` tinyint(1) NOT NULL default '1';"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `writeerrorlog` tinyint(1) NOT NULL default '1';"); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201812180'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201812180')) { + + showUpdateStep("Updating cronjob table"); + Database::query("ALTER TABLE `" . TABLE_PANEL_CRONRUNS . "` ADD `cronclass` varchar(500) NOT NULL AFTER `cronfile`"); + $upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_CRONRUNS . "` SET `cronclass` = :cc WHERE `cronfile` = :cf"); + Database::pexecute($upd_stmt, array( + 'cc' => '\\Froxlor\\Cron\\System\\TasksCron', + 'cf' => 'tasks' + )); + Database::pexecute($upd_stmt, array( + 'cc' => '\\Froxlor\\Cron\\Traffic\\TrafficCron', + 'cf' => 'traffic' + )); + Database::pexecute($upd_stmt, array( + 'cc' => '\\Froxlor\\Cron\\Traffic\\ReportsCron', + 'cf' => 'usage_report' + )); + Database::pexecute($upd_stmt, array( + 'cc' => '\\Froxlor\\Cron\\System\\MailboxsizeCron', + 'cf' => 'mailboxsize' + )); + Database::pexecute($upd_stmt, array( + 'cc' => '\\Froxlor\\Cron\\Http\\LetsEncrypt\\LetsEncrypt', + 'cf' => 'letsencrypt' + )); + Database::pexecute($upd_stmt, array( + 'cc' => '\\Froxlor\\Cron\\System\\BackupCron', + 'cf' => 'backup' + )); + Database::query("DELETE FROM `" . TABLE_PANEL_CRONRUNS . "` WHERE `module` = 'froxlor/ticket'"); + lastStepStatus(0); + + showUpdateStep("Removing ticketsystem"); + Database::query("ALTER TABLE `" . TABLE_PANEL_ADMINS . "` DROP `tickets`"); + Database::query("ALTER TABLE `" . TABLE_PANEL_ADMINS . "` DROP `tickets_used`"); + Database::query("ALTER TABLE `" . TABLE_PANEL_ADMINS . "` DROP `tickets_see_all`"); + Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` DROP `tickets`"); + Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` DROP `tickets_used`"); + Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `settinggroup` = 'ticket'"); + + define('TABLE_PANEL_TICKETS', 'panel_tickets'); + define('TABLE_PANEL_TICKET_CATS', 'panel_ticket_categories'); + Database::query("DROP TABLE IF EXISTS `" . TABLE_PANEL_TICKETS . "`;"); + Database::query("DROP TABLE IF EXISTS `" . TABLE_PANEL_TICKET_CATS . "`;"); + lastStepStatus(0); + + showUpdateStep("Updating nameserver settings"); + $dns_target = 'Bind'; + if (Settings::Get('system.dns_server') != 'bind') { + $dns_target = 'PowerDNS'; + } + $upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_SETTINGS . "` SET `value` = :v WHERE `settinggroup` = 'system' AND `varname` = 'dns_server'"); + Database::pexecute($upd_stmt, array( + 'v' => $dns_target + )); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201812190'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201812190')) { + + showUpdateStep("Adding new webserver error-log-level setting"); + Settings::AddNew('system.errorlog_level', (\Froxlor\Settings::Get('system.webserver') == 'nginx' ? 'error' : 'warn')); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201902120'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201902120')) { + + showUpdateStep("Adding new ECC / ECDSA setting for Let's Encrypt"); + Settings::AddNew('system.leecc', '0'); + $upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_CRONRUNS . "` SET `cronclass` = :cc WHERE `cronfile` = :cf"); + Database::pexecute($upd_stmt, array( + 'cc' => '\\Froxlor\\Cron\\Http\\LetsEncrypt\\AcmeSh', + 'cf' => 'letsencrypt' + )); + Settings::Set('system.letsencryptkeysize', '4096', true); + lastStepStatus(0); + + showUpdateStep("Removing current Let's Encrypt certificates due to new implementation of acme.sh"); + $sel_result = Database::query("SELECT id FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `letsencrypt` = '1'"); + $domain_ids = $sel_result->fetchAll(\PDO::FETCH_ASSOC); + if (count($domain_ids) > 0) { + $domain_in = ""; + foreach ($domain_ids as $domain_id) { + $domain_in .= "'" . $domain_id['id'] . "',"; + } + $domain_in = substr($domain_in, 0, - 1); + Database::query("DELETE FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` WHERE `domainid` IN (" . $domain_in . ")"); + } + // check for froxlor domain using let's encrypt + if (Settings::Get('system.le_froxlor_enabled') == 1) { + Database::query("DELETE FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` WHERE `domainid` = '0'"); + } + lastStepStatus(0); + + showUpdateStep("Inserting job to regenerate configfiles"); + \Froxlor\System\Cronjob::inserttask('1'); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201902170'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201902170')) { + + showUpdateStep("Adding new froxlor vhost domain alias setting"); + Settings::AddNew('system.froxloraliases', ""); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201902210'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201902210')) { + + // set correct version for people that have tested 0.10.0 before + \Froxlor\Froxlor::updateToVersion('0.10.0-rc1'); + \Froxlor\Froxlor::updateToDbVersion('201904100'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201904100')) { + + showUpdateStep("Converting all MyISAM tables to InnoDB"); + Database::needRoot(true); + Database::needSqlData(); + $sql_data = Database::getSqlData(); + $result = Database::query("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '" . $sql_data['db'] . "' AND ENGINE = 'MyISAM'"); + while ($row = $result->fetch(PDO::FETCH_ASSOC)) { + Database::query("ALTER TABLE `" . $row['TABLE_NAME'] . "` ENGINE=INNODB"); + } + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201904250'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.10.0-rc1')) { + showUpdateStep("Updating from 0.10.0-rc1 to 0.10.0-rc2", false); + \Froxlor\Froxlor::updateToVersion('0.10.0-rc2'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201904250')) { + + showUpdateStep("Adding new settings for CAA"); + Settings::AddNew('caa.caa_entry', '', true); + Settings::AddNew('system.dns_createcaaentry', 1, true); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201907270'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201907270')) { + + showUpdateStep("Cleaning up old files"); + $to_clean = array( + "actions/admin/settings/000.version.php", + "actions/admin/settings/190.ticket.php", + "admin_tickets.php", + "customer_tickets.php", + "install/scripts/language-check.php", + "install/updates/froxlor/upgrade_syscp.inc.php", + "lib/classes", + "lib/configfiles/precise.xml", + "lib/cron_init.php", + "lib/cron_shutdown.php", + "lib/formfields/admin/tickets", + "lib/formfields/customer/tickets", + "lib/functions.php", + "lib/functions", + "lib/navigation/10.tickets.php", + "scripts/classes", + "scripts/jobs", + "templates/Sparkle/admin/tickets", + "templates/Sparkle/customer/tickets" + ); + $disabled = explode(',', ini_get('disable_functions')); + $exec_allowed = ! in_array('exec', $disabled); + $del_list = ""; + foreach ($to_clean as $filedir) { + $complete_filedir = \Froxlor\Froxlor::getInstallDir() . $filedir; + if (file_exists($complete_filedir)) { + if ($exec_allowed) { + Froxlor\FileDir::safe_exec("rm -rf " . escapeshellarg($complete_filedir)); + } else { + $del_list .= "rm -rf " . escapeshellarg($complete_filedir) . PHP_EOL; + } + } + } + if ($exec_allowed) { + lastStepStatus(0); + } else { + if (empty($del_list)) { + // none of the files existed + lastStepStatus(0); + } else { + lastStepStatus(1, 'manual commands needed'); + echo 'Please run the following commands manually:
' . $del_list . '

'; + } + } + + \Froxlor\Froxlor::updateToDbVersion('201909150'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.10.0-rc2')) { + showUpdateStep("Updating from 0.10.0-rc2 to 0.10.0 final", false); + \Froxlor\Froxlor::updateToVersion('0.10.0'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201909150')) { + + showUpdateStep("Adding TLSv1.3-cipherlist setting"); + Settings::AddNew("system.tlsv13_cipher_list", ''); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201910030'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201910030')) { + + showUpdateStep("Adding field api_allowed to admins and customers"); + Database::query("ALTER TABLE `" . TABLE_PANEL_ADMINS . "` ADD `api_allowed` tinyint(1) NOT NULL default '1';"); + Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` ADD `api_allowed` tinyint(1) NOT NULL default '1';"); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201910090'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.10.0')) { + showUpdateStep("Updating from 0.10.0 to 0.10.1 final", false); + \Froxlor\Froxlor::updateToVersion('0.10.1'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201910090')) { + + showUpdateStep("Adjusting Let's Encrypt API setting"); + Settings::Set("system.leapiversion", '2'); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201910110'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201910110')) { + + showUpdateStep("Adding new settings for ssl-vhost default content"); + Settings::AddNew("system.default_sslvhostconf", ''); + Settings::AddNew("system.include_default_vhostconf", '0'); + lastStepStatus(0); + + showUpdateStep("Adding new fields to ips and ports-table"); + Database::query("ALTER TABLE `" . TABLE_PANEL_IPSANDPORTS . "` ADD `ssl_specialsettings` text AFTER `docroot`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_IPSANDPORTS . "` ADD `include_specialsettings` tinyint(1) NOT NULL default '0' AFTER `ssl_specialsettings`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_IPSANDPORTS . "` ADD `ssl_default_vhostconf_domain` text AFTER `include_specialsettings`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_IPSANDPORTS . "` ADD `include_default_vhostconf_domain` tinyint(1) NOT NULL default '0' AFTER `ssl_default_vhostconf_domain`;"); + lastStepStatus(0); + + showUpdateStep("Adding new fields to domains-table"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `ssl_specialsettings` text AFTER `specialsettings`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `include_specialsettings` tinyint(1) NOT NULL default '0' AFTER `ssl_specialsettings`;"); + lastStepStatus(0); + + // select all ips/ports with specialsettings and SSL enabled to include the specialsettings in the ssl-vhost + // because the former implementation included it and users might rely on that, see https://github.com/Froxlor/Froxlor/issues/727 + $sel_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_IPSANDPORTS . "` WHERE `specialsettings` <> '' AND `ssl` = '1'"); + Database::pexecute($sel_stmt); + $upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_IPSANDPORTS . "` SET `include_specialsettings` = '1' WHERE `id` = :id"); + if ($sel_stmt->columnCount() > 0) { + showUpdateStep("Adjusting IP/port settings for downward compatibility"); + while ($row = $sel_stmt->fetch(PDO::FETCH_ASSOC)) { + Database::pexecute($upd_stmt, [ + 'id' => $row['id'] + ]); + } + lastStepStatus(0); + } + + // select all domains with an ssl IP connected and specialsettings content to include these in the ssl-vhost + // to maintain former behavior + $sel_stmt = Database::prepare(" + SELECT d.id FROM `" . TABLE_PANEL_DOMAINS . "` d + LEFT JOIN `" . TABLE_DOMAINTOIP . "` d2i ON d2i.id_domain = d.id + LEFT JOIN `" . TABLE_PANEL_IPSANDPORTS . "` i ON i.id = d2i.id_ipandports + WHERE d.specialsettings <> '' AND i.ssl = '1' + "); + Database::pexecute($sel_stmt); + $upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_DOMAINS . "` SET `include_specialsettings` = '1' WHERE `id` = :id"); + if ($sel_stmt->columnCount() > 0) { + showUpdateStep("Adjusting domain settings for downward compatibility"); + while ($row = $sel_stmt->fetch(PDO::FETCH_ASSOC)) { + Database::pexecute($upd_stmt, [ + 'id' => $row['id'] + ]); + } + lastStepStatus(0); + } + + \Froxlor\Froxlor::updateToDbVersion('201910120'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.10.1')) { + showUpdateStep("Updating from 0.10.1 to 0.10.2", false); + \Froxlor\Froxlor::updateToVersion('0.10.2'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201910120')) { + + showUpdateStep("Adding new TLS options to domains-table"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `override_tls` tinyint(1) DEFAULT '0' AFTER `writeerrorlog`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `ssl_protocols` text AFTER `override_tls`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `ssl_cipher_list` text AFTER `ssl_protocols`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `tlsv13_cipher_list` text AFTER `ssl_cipher_list`;"); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201910200'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.10.2')) { + showUpdateStep("Updating from 0.10.2 to 0.10.3", false); + \Froxlor\Froxlor::updateToVersion('0.10.3'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.10.3')) { + showUpdateStep("Updating from 0.10.3 to 0.10.4", false); + \Froxlor\Froxlor::updateToVersion('0.10.4'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.10.4')) { + showUpdateStep("Updating from 0.10.4 to 0.10.5", false); + \Froxlor\Froxlor::updateToVersion('0.10.5'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201910200')) { + + showUpdateStep("Optimizing customer and admin table for size"); + // ALTER TABLE `panel_customers` CHANGE `name` `name` VARCHAR(250) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT ''; + Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` CHANGE `zipcode` `zipcode` varchar(25) NOT NULL default '';"); + Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` CHANGE `phone` `phone` varchar(50) NOT NULL default '';"); + Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` CHANGE `fax` `fax` varchar(50) NOT NULL default '';"); + Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` CHANGE `def_language` `def_language` varchar(100) NOT NULL default '';"); + Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` CHANGE `theme` `theme` varchar(50) NOT NULL default 'Sparkle';"); + Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` CHANGE `data_2fa` `data_2fa` varchar(25) NOT NULL default '';"); + Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` CHANGE `def_language` `def_language` varchar(100) NOT NULL default '';"); + Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` DROP `leaccount`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_ADMINS . "` CHANGE `def_language` `def_language` varchar(100) NOT NULL default '';"); + Database::query("ALTER TABLE `" . TABLE_PANEL_ADMINS . "` CHANGE `theme` `theme` varchar(50) NOT NULL default 'Sparkle';"); + Database::query("ALTER TABLE `" . TABLE_PANEL_ADMINS . "` CHANGE `data_2fa` `data_2fa` varchar(25) NOT NULL default '';"); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201911130'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.10.5')) { + showUpdateStep("Updating from 0.10.5 to 0.10.6", false); + \Froxlor\Froxlor::updateToVersion('0.10.6'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201911130')) { + showUpdateStep("Adding new settings for domain edit form default values"); + Settings::AddNew("system.apply_specialsettings_default", '1'); + Settings::AddNew("system.apply_phpconfigs_default", '1'); + lastStepStatus(0); + \Froxlor\Froxlor::updateToDbVersion('201911220'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.10.6')) { + showUpdateStep("Updating from 0.10.6 to 0.10.7", false); + \Froxlor\Froxlor::updateToVersion('0.10.7'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.10.7')) { + showUpdateStep("Updating from 0.10.7 to 0.10.8", false); + \Froxlor\Froxlor::updateToVersion('0.10.8'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.10.8')) { + showUpdateStep("Updating from 0.10.8 to 0.10.9", false); + \Froxlor\Froxlor::updateToVersion('0.10.9'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201911220')) { + showUpdateStep("Adding enhanced SSL control over domains"); + // customer domains + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `ssl_enabled` tinyint(1) DEFAULT '1';"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `ssl_honorcipherorder` tinyint(1) DEFAULT '0' AFTER `ssl_enabled`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `ssl_sessiontickets` tinyint(1) DEFAULT '1' AFTER `ssl_honorcipherorder`;"); + // as setting for froxlor vhost + Settings::AddNew("system.honorcipherorder", '0'); + Settings::AddNew("system.sessiontickets", '1'); + lastStepStatus(0); + \Froxlor\Froxlor::updateToDbVersion('201912100'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.10.9')) { + showUpdateStep("Updating from 0.10.9 to 0.10.10", false); + \Froxlor\Froxlor::updateToVersion('0.10.10'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201912100')) { + showUpdateStep("Adding option to disable SSL sessiontickets for older systems"); + Settings::AddNew("system.sessionticketsenabled", '1'); + lastStepStatus(0); + \Froxlor\Froxlor::updateToDbVersion('201912310'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201912310')) { + showUpdateStep("Adding custom phpfpm pool configuration field"); + Database::query("ALTER TABLE `" . TABLE_PANEL_FPMDAEMONS . "` ADD `custom_config` text AFTER `limit_extensions`;"); + lastStepStatus(0); + \Froxlor\Froxlor::updateToDbVersion('201912311'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.10.10')) { + showUpdateStep("Updating from 0.10.10 to 0.10.11", false); + \Froxlor\Froxlor::updateToVersion('0.10.11'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201912311')) { + showUpdateStep("Migrate logfiles_format setting"); + $current_format = Settings::Set('system.logfiles_format'); + if (! empty($current_format)) { + Settings::Set('system.logfiles_format', '"' . Settings::Get('system.logfiles_format') . '"'); + lastStepStatus(0); + } else { + lastStepStatus(0, 'not needed'); + } + \Froxlor\Froxlor::updateToDbVersion('201912312'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201912312')) { + showUpdateStep("Adding option change awstats LogFormat"); + Settings::AddNew("system.awstats_logformat", '1'); + lastStepStatus(0); + \Froxlor\Froxlor::updateToDbVersion('201912313'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.10.11')) { + showUpdateStep("Updating from 0.10.11 to 0.10.12", false); + \Froxlor\Froxlor::updateToVersion('0.10.12'); +} + +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'); +} 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 6ebc6c81..4a1ed614 100644 --- a/install/updates/froxlor/0.9/update_0.9.inc.php +++ b/install/updates/froxlor/0.9/update_0.9.inc.php @@ -1,4 +1,6 @@ (2010-) - * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt - * @package Install - * + * @copyright (c) the authors + * @author Froxlor team (2010-) + * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt + * @package Install + * */ - -if (!defined('AREA') - || (defined('AREA') && AREA != 'admin') - || !isset($userinfo['loginname']) - || (isset($userinfo['loginname']) && $userinfo['loginname'] == '') -) { - header('Location: ../../../../index.php'); - exit; +if (! defined('_CRON_UPDATE')) { + if (! defined('AREA') || (defined('AREA') && AREA != 'admin') || ! isset($userinfo['loginname']) || (isset($userinfo['loginname']) && $userinfo['loginname'] == '')) { + header('Location: ../../../../index.php'); + exit(); + } } -if (isFroxlorVersion('0.9-r0')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9-r0')) { showUpdateStep("Updating from 0.9-r0 to 0.9-r1", false); showUpdateStep("Performing database updates"); // add missing database-updates if necessary (old: update/update_database.php) - if (Settings::Get('system.dbversion') !== null && (int)Settings::Get('system.dbversion') < 1) { + if (Settings::Get('system.dbversion') !== null && (int) Settings::Get('system.dbversion') < 1) { Database::query(" - ALTER TABLE `panel_databases` ADD `dbserver` INT( 11 ) UNSIGNED NOT NULL default '0';" - ); + ALTER TABLE `panel_databases` ADD `dbserver` INT( 11 ) UNSIGNED NOT NULL default '0';"); } - if (Settings::Get('system.dbversion') !== null && (int)Settings::Get('system.dbversion') < 2) { + if (Settings::Get('system.dbversion') !== null && (int) Settings::Get('system.dbversion') < 2) { Database::query("ALTER TABLE `panel_ipsandports` CHANGE `ssl_cert` `ssl_cert_file` VARCHAR( 255 ) NOT NULL, ADD `ssl_key_file` VARCHAR( 255 ) NOT NULL, ADD `ssl_ca_file` VARCHAR( 255 ) NOT NULL, @@ -46,7 +44,7 @@ if (isFroxlorVersion('0.9-r0')) { } // eof(lostuff) - //remove billing tables in database + // remove billing tables in database define('TABLE_BILLING_INVOICES', 'billing_invoices'); define('TABLE_BILLING_INVOICES_ADMINS', 'billing_invoices_admins'); define('TABLE_BILLING_INVOICE_CHANGES', 'billing_invoice_changes'); @@ -184,10 +182,10 @@ if (isFroxlorVersion('0.9-r0')) { lastStepStatus(0); - updateToVersion('0.9-r1'); + \Froxlor\Froxlor::updateToVersion('0.9-r1'); } -if (isFroxlorVersion('0.9-r1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9-r1')) { showUpdateStep("Updating from 0.9-r1 to 0.9-r2", false); showUpdateStep("Updating settings table"); @@ -195,19 +193,17 @@ if (isFroxlorVersion('0.9-r1')) { Database::query("INSERT INTO `" . TABLE_PANEL_SETTINGS . "` (`settinggroup`, `varname`, `value`) VALUES ('spf', 'spf_entry', '@ IN TXT \"v=spf1 a mx -all\"');"); Database::query("UPDATE `" . TABLE_PANEL_SETTINGS . "` SET `varname` = 'froxlor_graphic' WHERE `varname` = 'syscp_graphic'"); - if (Settings::Get('admin.syscp_graphic') !== null - && Settings::Get('admin.syscp_graphic') != '' - ){ + if (Settings::Get('admin.syscp_graphic') !== null && Settings::Get('admin.syscp_graphic') != '') { Settings::Set('admin.froxlor_graphic', Settings::Get('admin.syscp_graphic')); } else { Settings::Set('admin.froxlor_graphic', 'images/header.gif'); } lastStepStatus(0); - updateToVersion('0.9-r2'); + \Froxlor\Froxlor::updateToVersion('0.9-r2'); } -if (isFroxlorVersion('0.9-r2')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9-r2')) { showUpdateStep("Updating from 0.9-r2 to 0.9-r3", false); showUpdateStep("Updating tables"); @@ -218,10 +214,10 @@ if (isFroxlorVersion('0.9-r2')) { lastStepStatus(0); - updateToVersion('0.9-r3'); + \Froxlor\Froxlor::updateToVersion('0.9-r3'); } -if (isFroxlorVersion('0.9-r3')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9-r3')) { showUpdateStep("Updating from 0.9-r3 to 0.9-r4", false); showUpdateStep("Creating new table 'cronjobs_run'"); @@ -241,30 +237,30 @@ if (isFroxlorVersion('0.9-r3')) { // checking for active ticket-module $ticket_active = 0; - if ((int)Settings::Get('ticket.enabled') == 1) { + if ((int) Settings::Get('ticket.enabled') == 1) { $ticket_active = 1; } // checking for active aps-module $aps_active = 0; - if ((int)Settings::Get('aps.aps_active') == 1) { + if ((int) Settings::Get('aps.aps_active') == 1) { $aps_active = 1; } // checking for active autoresponder-module $ar_active = 0; - if ((int)Settings::Get('autoresponder.autoresponder_active') == 1) { + if ((int) Settings::Get('autoresponder.autoresponder_active') == 1) { $ar_active = 1; } Database::query("INSERT INTO `cronjobs_run` (`module`, `cronfile`, `interval`, `isactive`, `desc_lng_key`) VALUES ('froxlor/core', 'cron_tasks.php', '5 MINUTE', '1', 'cron_tasks');"); Database::query("INSERT INTO `cronjobs_run` (`module`, `cronfile`, `interval`, `isactive`, `desc_lng_key`) VALUES ('froxlor/core', 'cron_legacy.php', '5 MINUTE', '1', 'cron_legacy');"); - Database::query("INSERT INTO `cronjobs_run` (`module`, `cronfile`, `interval`, `isactive`, `desc_lng_key`) VALUES ('froxlor/aps', 'cron_apsinstaller.php', '5 MINUTE', ".$aps_active.", 'cron_apsinstaller');"); - Database::query("INSERT INTO `cronjobs_run` (`module`, `cronfile`, `interval`, `isactive`, `desc_lng_key`) VALUES ('froxlor/autoresponder', 'cron_autoresponder.php', '5 MINUTE', ".$ar_active.", 'cron_autoresponder');"); - Database::query("INSERT INTO `cronjobs_run` (`module`, `cronfile`, `interval`, `isactive`, `desc_lng_key`) VALUES ('froxlor/aps', 'cron_apsupdater.php', '1 HOUR', ".$aps_active.", 'cron_apsupdater');"); + Database::query("INSERT INTO `cronjobs_run` (`module`, `cronfile`, `interval`, `isactive`, `desc_lng_key`) VALUES ('froxlor/aps', 'cron_apsinstaller.php', '5 MINUTE', " . $aps_active . ", 'cron_apsinstaller');"); + Database::query("INSERT INTO `cronjobs_run` (`module`, `cronfile`, `interval`, `isactive`, `desc_lng_key`) VALUES ('froxlor/autoresponder', 'cron_autoresponder.php', '5 MINUTE', " . $ar_active . ", 'cron_autoresponder');"); + Database::query("INSERT INTO `cronjobs_run` (`module`, `cronfile`, `interval`, `isactive`, `desc_lng_key`) VALUES ('froxlor/aps', 'cron_apsupdater.php', '1 HOUR', " . $aps_active . ", 'cron_apsupdater');"); Database::query("INSERT INTO `cronjobs_run` (`module`, `cronfile`, `interval`, `isactive`, `desc_lng_key`) VALUES ('froxlor/core', 'cron_traffic.php', '1 DAY', '1', 'cron_traffic');"); - Database::query("INSERT INTO `cronjobs_run` (`module`, `cronfile`, `interval`, `isactive`, `desc_lng_key`) VALUES ('froxlor/ticket', 'cron_used_tickets_reset.php', '1 MONTH', '".$ticket_active."', 'cron_ticketsreset');"); - Database::query("INSERT INTO `cronjobs_run` (`module`, `cronfile`, `interval`, `isactive`, `desc_lng_key`) VALUES ('froxlor/ticket', 'cron_ticketarchive.php', '1 MONTH', '".$ticket_active."', 'cron_ticketarchive');"); + Database::query("INSERT INTO `cronjobs_run` (`module`, `cronfile`, `interval`, `isactive`, `desc_lng_key`) VALUES ('froxlor/ticket', 'cron_used_tickets_reset.php', '1 MONTH', '" . $ticket_active . "', 'cron_ticketsreset');"); + Database::query("INSERT INTO `cronjobs_run` (`module`, `cronfile`, `interval`, `isactive`, `desc_lng_key`) VALUES ('froxlor/ticket', 'cron_ticketarchive.php', '1 MONTH', '" . $ticket_active . "', 'cron_ticketarchive');"); lastStepStatus(0); showUpdateStep("Updating old settings values"); @@ -272,16 +268,16 @@ if (isFroxlorVersion('0.9-r3')) { Database::query("UPDATE `" . TABLE_PANEL_SETTINGS . "` SET `value` = 'Froxlor Support' WHERE `settinggroup`='ticket' AND `varname`='noreply_name' AND `value`='SysCP Support'"); lastStepStatus(0); - updateToVersion('0.9-r4'); + \Froxlor\Froxlor::updateToVersion('0.9-r4'); } -if (isFroxlorVersion('0.9-r4')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9-r4')) { showUpdateStep("Updating from 0.9-r4 to 0.9 final"); lastStepStatus(0); - updateToVersion('0.9'); + \Froxlor\Froxlor::updateToVersion('0.9'); } -if (isFroxlorVersion('0.9')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9')) { showUpdateStep("Updating from 0.9 to 0.9.1", false); @@ -289,36 +285,33 @@ if (isFroxlorVersion('0.9')) { Database::query("UPDATE `" . TABLE_PANEL_SETTINGS . "` SET `value` = 'images/header.gif' WHERE `varname` = 'froxlor_graphic' AND `value` = 'images/header.png'"); lastStepStatus(0); - updateToVersion('0.9.1'); + \Froxlor\Froxlor::updateToVersion('0.9.1'); } -if (isFroxlorVersion('0.9.1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.1')) { showUpdateStep("Updating from 0.9.1 to 0.9.2", false); showUpdateStep("Checking whether last-system-guid is sane"); - $result_stmt = Database::query("SELECT MAX(`guid`) as `latestguid` FROM `".TABLE_PANEL_CUSTOMERS."`"); + $result_stmt = Database::query("SELECT MAX(`guid`) as `latestguid` FROM `" . TABLE_PANEL_CUSTOMERS . "`"); $result = $result_stmt->fetch(PDO::FETCH_ASSOC); - if (isset($result['latestguid']) - && (int)$result['latestguid'] > 0 - && $result['latestguid'] != Settings::Get('system.lastguid') - ) { - checkLastGuid(); + if (isset($result['latestguid']) && (int) $result['latestguid'] > 0 && $result['latestguid'] != Settings::Get('system.lastguid')) { + \Froxlor\System\Cronjob::checkLastGuid(); lastStepStatus(1, 'fixed'); } else { lastStepStatus(0); } - updateToVersion('0.9.2'); + \Froxlor\Froxlor::updateToVersion('0.9.2'); } -if (isFroxlorVersion('0.9.2')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.2')) { showUpdateStep("Updating from 0.9.2 to 0.9.3"); lastStepStatus(0); - updateToVersion('0.9.3'); + \Froxlor\Froxlor::updateToVersion('0.9.3'); } -if (isFroxlorVersion('0.9.3')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.3')) { showUpdateStep("Updating from 0.9.3 to 0.9.3-svn1", false); @@ -327,10 +320,10 @@ if (isFroxlorVersion('0.9.3')) { Database::query("INSERT INTO `" . TABLE_PANEL_SETTINGS . "` (`settinggroup`, `varname`, `value`) VALUES ('system', 'store_index_file_subs', '1');"); lastStepStatus(0); - updateToVersion('0.9.3-svn1'); + \Froxlor\Froxlor::updateToVersion('0.9.3-svn1'); } -if (isFroxlorVersion('0.9.3-svn1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.3-svn1')) { showUpdateStep("Updating from 0.9.3-svn1 to 0.9.3-svn2", false); @@ -339,30 +332,30 @@ if (isFroxlorVersion('0.9.3-svn1')) { Database::query("INSERT INTO `" . TABLE_PANEL_SETTINGS . "` (`settinggroup`, `varname`, `value`) VALUES ('panel', 'adminmail_return', '');"); lastStepStatus(0); - updateToVersion('0.9.3-svn2'); + \Froxlor\Froxlor::updateToVersion('0.9.3-svn2'); } -if (isFroxlorVersion('0.9.3-svn2')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.3-svn2')) { showUpdateStep("Updating from 0.9.3-svn2 to 0.9.3-svn3", false); showUpdateStep("Correcting cron start-times"); // 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())); - Database::query("UPDATE `".TABLE_PANEL_CRONRUNS."` SET `lastrun` = '".$ts."' WHERE `cronfile` ='cron_traffic.php';"); + Database::query("UPDATE `" . TABLE_PANEL_CRONRUNS . "` SET `lastrun` = '" . $ts . "' WHERE `cronfile` ='cron_traffic.php';"); $ts = mktime(1, 0, 0, date('m', time()), date('d', time()), date('Y', time())); - Database::query("UPDATE `".TABLE_PANEL_CRONRUNS."` SET `lastrun` = '".$ts."' WHERE `cronfile` ='cron_used_tickets_reset.php';"); - Database::query("UPDATE `".TABLE_PANEL_CRONRUNS."` SET `lastrun` = '".$ts."' WHERE `cronfile` ='cron_ticketarchive.php';"); + Database::query("UPDATE `" . TABLE_PANEL_CRONRUNS . "` SET `lastrun` = '" . $ts . "' WHERE `cronfile` ='cron_used_tickets_reset.php';"); + Database::query("UPDATE `" . TABLE_PANEL_CRONRUNS . "` SET `lastrun` = '" . $ts . "' WHERE `cronfile` ='cron_ticketarchive.php';"); lastStepStatus(0); showUpdateStep("Adding new language: Polish"); - Database::query("INSERT INTO `".TABLE_PANEL_LANGUAGE."` SET `language` = 'Polski', `file` = 'lng/polish.lng.php'"); + Database::query("INSERT INTO `" . TABLE_PANEL_LANGUAGE . "` SET `language` = 'Polski', `file` = 'lng/polish.lng.php'"); lastStepStatus(0); - updateToVersion('0.9.3-svn3'); + \Froxlor\Froxlor::updateToVersion('0.9.3-svn3'); } -if (isFroxlorVersion('0.9.3-svn3')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.3-svn3')) { showUpdateStep("Updating from 0.9.3-svn3 to 0.9.3-svn4", false); @@ -375,10 +368,10 @@ if (isFroxlorVersion('0.9.3-svn3')) { Database::query("INSERT INTO `" . TABLE_PANEL_SETTINGS . "` (`settinggroup`, `varname`, `value`) VALUES ('dkim', 'dkim_notes', '');"); lastStepStatus(0); - updateToVersion('0.9.3-svn4'); + \Froxlor\Froxlor::updateToVersion('0.9.3-svn4'); } -if (isFroxlorVersion('0.9.3-svn4')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.3-svn4')) { showUpdateStep("Updating from 0.9.3-svn4 to 0.9.3-svn5", false); @@ -386,16 +379,16 @@ if (isFroxlorVersion('0.9.3-svn4')) { Database::query("INSERT INTO `" . TABLE_PANEL_SETTINGS . "` (`settinggroup`, `varname`, `value`) VALUES ('system', 'stdsubdomain', '');"); lastStepStatus(0); - updateToVersion('0.9.3-svn5'); + \Froxlor\Froxlor::updateToVersion('0.9.3-svn5'); } -if (isFroxlorVersion('0.9.3-svn5')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.3-svn5')) { showUpdateStep("Updating from 0.9.3-svn5 to 0.9.4 final"); lastStepStatus(0); - updateToVersion('0.9.4'); + \Froxlor\Froxlor::updateToVersion('0.9.4'); } -if (isFroxlorVersion('0.9.4')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.4')) { showUpdateStep("Updating from 0.9.4 to 0.9.4-svn1", false); @@ -403,38 +396,30 @@ if (isFroxlorVersion('0.9.4')) { * some users might still have the setting in their database * because we already had this back in older versions. * To not confuse Froxlor, we just update old settings. - */ - if(Settings::Get('system.awstats_path') !== null - && Settings::Get('system.awstats_path') != '' - ) { + */ + if (Settings::Get('system.awstats_path') !== null && Settings::Get('system.awstats_path') != '') { showUpdateStep("Updating awstats path setting"); Database::query("UPDATE `" . TABLE_PANEL_SETTINGS . "` SET `value` = '/usr/bin/' WHERE `settinggroup` = 'system' AND `varname` = 'awstats_path';"); lastStepStatus(0); - } - elseif(Settings::Get('system.awstats_path') == null) - { + } elseif (Settings::Get('system.awstats_path') == null) { showUpdateStep("Adding new awstats path setting"); Database::query("INSERT INTO `" . TABLE_PANEL_SETTINGS . "` (`settinggroup`, `varname`, `value`) VALUES ('system', 'awstats_path', '/usr/bin/');"); lastStepStatus(0); } - if(Settings::Get('system.awstats_domain_file') !== null - && Settings::Get('system.awstats_domain_file') != '' - ) { + if (Settings::Get('system.awstats_domain_file') !== null && Settings::Get('system.awstats_domain_file') != '') { showUpdateStep("Updating awstats configuration path setting"); Database::query("UPDATE `" . TABLE_PANEL_SETTINGS . "` SET `varname` = 'awstats_conf' WHERE `varname` = 'awstats_domain_file';"); - } - else - { + } else { showUpdateStep("Adding awstats configuration path settings"); Database::query("INSERT INTO `" . TABLE_PANEL_SETTINGS . "` (`settinggroup`, `varname`, `value`) VALUES ('system', 'awstats_conf', '/etc/awstats/');"); } lastStepStatus(0); - updateToVersion('0.9.4-svn1'); + \Froxlor\Froxlor::updateToVersion('0.9.4-svn1'); } -if (isFroxlorVersion('0.9.4-svn1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.4-svn1')) { showUpdateStep("Updating from 0.9.4-svn1 to 0.9.4-svn2", false); @@ -446,15 +431,15 @@ if (isFroxlorVersion('0.9.4-svn1')) { if ($update_domains == 1) { showUpdateStep("Updating domains with iswildcarddomain=yes"); - $query = "SELECT `d`.`id` FROM `".TABLE_PANEL_DOMAINS."` `d`, `".TABLE_PANEL_CUSTOMERS."` `c` "; - $query.= "WHERE `parentdomainid`='0' AND `email_only` = '0' AND `d`.`customerid` = `c`.`customerid` AND `d`.`id` <> `c`.`standardsubdomain`"; + $query = "SELECT `d`.`id` FROM `" . TABLE_PANEL_DOMAINS . "` `d`, `" . TABLE_PANEL_CUSTOMERS . "` `c` "; + $query .= "WHERE `parentdomainid`='0' AND `email_only` = '0' AND `d`.`customerid` = `c`.`customerid` AND `d`.`id` <> `c`.`standardsubdomain`"; $result = Database::query($query); $updated_domains = 0; while ($domain = $result->fetch(PDO::FETCH_ASSOC)) { - Database::query("UPDATE `".TABLE_PANEL_DOMAINS."` SET `iswildcarddomain` = '1' WHERE `id` ='".(int)$domain['id']."'"); - $updated_domains++; + Database::query("UPDATE `" . TABLE_PANEL_DOMAINS . "` SET `iswildcarddomain` = '1' WHERE `id` ='" . (int) $domain['id'] . "'"); + $updated_domains ++; } - lastStepStatus(0, 'Updated '.$updated_domains.' domain(s)'); + lastStepStatus(0, 'Updated ' . $updated_domains . ' domain(s)'); } else { showUpdateStep("Won't update domains with iswildcarddomain=yes as requested"); lastStepStatus(1); @@ -464,16 +449,16 @@ if (isFroxlorVersion('0.9.4-svn1')) { Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` MODIFY `iswildcarddomain` tinyint(1) NOT NULL default '1';"); lastStepStatus(0); - updateToVersion('0.9.4-svn2'); + \Froxlor\Froxlor::updateToVersion('0.9.4-svn2'); } -if (isFroxlorVersion('0.9.4-svn2')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.4-svn2')) { showUpdateStep("Updating from 0.9.4-svn2 to 0.9.5 final"); lastStepStatus(0); - updateToVersion('0.9.5'); + \Froxlor\Froxlor::updateToVersion('0.9.5'); } -if (isFroxlorVersion('0.9.5')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.5')) { showUpdateStep("Updating from 0.9.5 to 0.9.6-svn1", false); @@ -485,37 +470,38 @@ if (isFroxlorVersion('0.9.5')) { Database::query("ALTER TABLE `" . TABLE_PANEL_TICKET_CATS . "` ADD `logicalorder` int(3) NOT NULL default '1' AFTER `adminid`;"); lastStepStatus(0); - updateToVersion('0.9.6-svn1'); + \Froxlor\Froxlor::updateToVersion('0.9.6-svn1'); } -if (isFroxlorVersion('0.9.6-svn1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.6-svn1')) { showUpdateStep("Updating from 0.9.6-svn1 to 0.9.6-svn2", false); - $update_adminmail = isset($_POST['update_adminmail']) ? validate($_POST['update_adminmail'], 'update_adminmail') : false; + $update_adminmail = isset($_POST['update_adminmail']) ? Froxlor\Validate\Validate::validate($_POST['update_adminmail'], 'update_adminmail') : false; $do_update = true; if ($update_adminmail !== false) { showUpdateStep("Checking newly entered admin-mail"); - if (!PHPMailer::ValidateAddress($update_adminmail)) { + if (! \PHPMailer\PHPMailer\PHPMailer::ValidateAddress($update_adminmail)) { $do_update = false; lastStepStatus(2, 'E-Mail still not valid, go back and try again'); } else { $stmt = Database::prepare(" UPDATE `" . TABLE_PANEL_SETTINGS . "` SET `value` = :adminmail - WHERE `settinggroup` = 'panel' AND `varname` = 'adminmail';" - ); - Database::pexecute($stmt, array('adminmail' => $update_adminmail)); + WHERE `settinggroup` = 'panel' AND `varname` = 'adminmail';"); + Database::pexecute($stmt, array( + 'adminmail' => $update_adminmail + )); lastStepStatus(0); } } if ($do_update) { - updateToVersion('0.9.6-svn2'); + \Froxlor\Froxlor::updateToVersion('0.9.6-svn2'); } } -if (isFroxlorVersion('0.9.6-svn2')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.6-svn2')) { showUpdateStep("Updating from 0.9.6-svn2 to 0.9.6-svn3", false); @@ -534,91 +520,94 @@ if (isFroxlorVersion('0.9.6-svn2')) { INSERT INTO `" . TABLE_PANEL_SETTINGS . "` SET `settinggroup` = 'defaultwebsrverrhandler', `varname` = :varname, - `value` = :err" - ); + `value` = :err"); - if (isset($_POST['update_deferr_500']) - && trim($_POST['update_deferr_500']) != '' - ) { - Database::pexecute($stmt, array('varname' => 'err500', 'err' => $_POST['update_deferr_500'])); + if (isset($_POST['update_deferr_500']) && trim($_POST['update_deferr_500']) != '') { + Database::pexecute($stmt, array( + 'varname' => 'err500', + 'err' => $_POST['update_deferr_500'] + )); $err500 = true; } - if(isset($_POST['update_deferr_401']) - && trim($_POST['update_deferr_401']) != '' - ) { - Database::pexecute($stmt, array('varname' => 'err401', 'err' => $_POST['update_deferr_401'])); + if (isset($_POST['update_deferr_401']) && trim($_POST['update_deferr_401']) != '') { + Database::pexecute($stmt, array( + 'varname' => 'err401', + 'err' => $_POST['update_deferr_401'] + )); $err401 = true; } - if(isset($_POST['update_deferr_403']) - && trim($_POST['update_deferr_403']) != '' - ) { - Database::pexecute($stmt, array('varname' => 'err403', 'err' => $_POST['update_deferr_403'])); + if (isset($_POST['update_deferr_403']) && trim($_POST['update_deferr_403']) != '') { + Database::pexecute($stmt, array( + 'varname' => 'err403', + 'err' => $_POST['update_deferr_403'] + )); $err403 = true; } - if(isset($_POST['update_deferr_404']) - && trim($_POST['update_deferr_404']) != '' - ) { - Database::pexecute($stmt, array('varname' => 'err404', 'err' => $_POST['update_deferr_404'])); + if (isset($_POST['update_deferr_404']) && trim($_POST['update_deferr_404']) != '') { + Database::pexecute($stmt, array( + 'varname' => 'err404', + 'err' => $_POST['update_deferr_404'] + )); $err404 = true; } } - if(!$update_deferr_enable) { + if (! $update_deferr_enable) { Database::query("INSERT INTO `" . TABLE_PANEL_SETTINGS . "` (`settinggroup`, `varname`, `value`) VALUES ('defaultwebsrverrhandler', 'enabled', '0');"); } - if(!$err401) { + if (! $err401) { Database::query("INSERT INTO `" . TABLE_PANEL_SETTINGS . "` (`settinggroup`, `varname`, `value`) VALUES ('defaultwebsrverrhandler', 'err401', '');"); } - if(!$err403) { + if (! $err403) { Database::query("INSERT INTO `" . TABLE_PANEL_SETTINGS . "` (`settinggroup`, `varname`, `value`) VALUES ('defaultwebsrverrhandler', 'err403', '');"); } - if(!$err404) { + if (! $err404) { Database::query("INSERT INTO `" . TABLE_PANEL_SETTINGS . "` (`settinggroup`, `varname`, `value`) VALUES ('defaultwebsrverrhandler', 'err404', '');"); } - if(!$err500) { + if (! $err500) { Database::query("INSERT INTO `" . TABLE_PANEL_SETTINGS . "` (`settinggroup`, `varname`, `value`) VALUES ('defaultwebsrverrhandler', 'err500', '');"); } lastStepStatus(0); - updateToVersion('0.9.6-svn3'); + \Froxlor\Froxlor::updateToVersion('0.9.6-svn3'); } -if (isFroxlorVersion('0.9.6-svn3')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.6-svn3')) { showUpdateStep("Updating from 0.9.6-svn3 to 0.9.6-svn4", false); $update_deftic_priority = isset($_POST['update_deftic_priority']) ? intval($_POST['update_deftic_priority']) : 2; showUpdateStep("Setting default support-ticket priority"); - Database::query("INSERT INTO `" . TABLE_PANEL_SETTINGS . "` (`settinggroup`, `varname`, `value`) VALUES ('ticket', 'default_priority', '".(int)$update_deftic_priority."');"); + Database::query("INSERT INTO `" . TABLE_PANEL_SETTINGS . "` (`settinggroup`, `varname`, `value`) VALUES ('ticket', 'default_priority', '" . (int) $update_deftic_priority . "');"); lastStepStatus(0); - updateToVersion('0.9.6-svn4'); + \Froxlor\Froxlor::updateToVersion('0.9.6-svn4'); } -if (isFroxlorVersion('0.9.6-svn4')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.6-svn4')) { showUpdateStep("Updating from 0.9.6-svn4 to 0.9.6-svn5", false); $update_defsys_phpconfig = isset($_POST['update_defsys_phpconfig']) ? intval($_POST['update_defsys_phpconfig']) : 1; - if($update_defsys_phpconfig != 1) { - showUpdateStep("Setting default php-configuration to user defined config #".$update_defsys_phpconfig); + if ($update_defsys_phpconfig != 1) { + showUpdateStep("Setting default php-configuration to user defined config #" . $update_defsys_phpconfig); } else { showUpdateStep("Adding default php-configuration setting to the database"); } - Database::query("INSERT INTO `" . TABLE_PANEL_SETTINGS . "` (`settinggroup`, `varname`, `value`) VALUES ('system', 'mod_fcgid_defaultini', '".(int)$update_defsys_phpconfig."');"); + Database::query("INSERT INTO `" . TABLE_PANEL_SETTINGS . "` (`settinggroup`, `varname`, `value`) VALUES ('system', 'mod_fcgid_defaultini', '" . (int) $update_defsys_phpconfig . "');"); lastStepStatus(0); - updateToVersion('0.9.6-svn5'); + \Froxlor\Froxlor::updateToVersion('0.9.6-svn5'); } -if (isFroxlorVersion('0.9.6-svn5')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.6-svn5')) { showUpdateStep("Updating from 0.9.6-svn5 to 0.9.6-svn6", false); @@ -627,7 +616,9 @@ if (isFroxlorVersion('0.9.6-svn5')) { // add ftp server setting $stmt = Database::prepare("INSERT INTO `panel_settings` SET `settinggroup` = 'system', `varname` = 'ftpserver', `value` = :value;"); - Database::pexecute($stmt, array('value' => $update_defsys_ftpserver)); + Database::pexecute($stmt, array( + 'value' => $update_defsys_ftpserver + )); // add proftpd quota Database::query("CREATE TABLE `ftp_quotalimits` (`name` varchar(30) default NULL, `quota_type` enum('user','group','class','all') NOT NULL default 'user', `per_session` enum('false','true') NOT NULL default 'false', `limit_type` enum('soft','hard') NOT NULL default 'hard', `bytes_in_avail` float NOT NULL, `bytes_out_avail` float NOT NULL, `bytes_xfer_avail` float NOT NULL, `files_in_avail` int(10) unsigned NOT NULL, `files_out_avail` int(10) unsigned NOT NULL, `files_xfer_avail` int(10) unsigned NOT NULL) ENGINE=MyISAM;"); @@ -640,28 +631,27 @@ if (isFroxlorVersion('0.9.6-svn5')) { while ($row_ftp_users = $result_ftp_users_stmt->fetch(PDO::FETCH_ASSOC)) { $result_ftp_quota_stmt = Database::query(" SELECT diskspace_used FROM `" . TABLE_PANEL_CUSTOMERS . "` - WHERE loginname = SUBSTRING_INDEX('" . $row_ftp_users['username'] . "', '" . Settings::Get('customer.ftpprefix') . "', 1);" - ); + WHERE loginname = SUBSTRING_INDEX('" . $row_ftp_users['username'] . "', '" . Settings::Get('customer.ftpprefix') . "', 1);"); $row_ftp_quota = $result_ftp_quota_stmt->fetch(PDO::FETCH_ASSOC); Database::query("INSERT INTO `ftp_quotatallies` (`name`, `quota_type`, `bytes_in_used`, `bytes_out_used`, `bytes_xfer_used`, `files_in_used`, `files_out_used`, `files_xfer_used`) VALUES ('" . $row_ftp_users['username'] . "', 'user', '" . $row_ftp_quota['diskspace_used'] . "'*1024, '0', '0', '0', '0', '0');"); } lastStepStatus(0); - updateToVersion('0.9.6-svn6'); + \Froxlor\Froxlor::updateToVersion('0.9.6-svn6'); } -if (isFroxlorVersion('0.9.6-svn6')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.6-svn6')) { showUpdateStep("Updating from 0.9.6-svn6 to 0.9.6 final"); lastStepStatus(0); - updateToVersion('0.9.6'); + \Froxlor\Froxlor::updateToVersion('0.9.6'); } -if (isFroxlorVersion('0.9.6')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.6')) { showUpdateStep("Updating from 0.9.6 to 0.9.7-svn1", false); $update_customredirect_enable = isset($_POST['update_customredirect_enable']) ? 1 : 0; - $update_customredirect_default = isset($_POST['update_customredirect_default']) ? (int)$_POST['update_customredirect_default'] : 1; + $update_customredirect_default = isset($_POST['update_customredirect_default']) ? (int) $_POST['update_customredirect_default'] : 1; showUpdateStep("Adding new tables to database"); Database::query("CREATE TABLE IF NOT EXISTS `redirect_codes` ( @@ -687,17 +677,17 @@ if (isFroxlorVersion('0.9.6')) { lastStepStatus(0); showUpdateStep("Updating domains"); - $res = Database::query("SELECT `id` FROM `".TABLE_PANEL_DOMAINS."` ORDER BY `id` ASC"); + $res = Database::query("SELECT `id` FROM `" . TABLE_PANEL_DOMAINS . "` ORDER BY `id` ASC"); $updated_domains = 0; while ($d = $res->fetch(PDO::FETCH_ASSOC)) { - Database::query("INSERT INTO `domain_redirect_codes` (`rid`, `did`) VALUES ('".(int)$update_customredirect_default."', '".(int)$d['id']."');"); - $updated_domains++; + Database::query("INSERT INTO `domain_redirect_codes` (`rid`, `did`) VALUES ('" . (int) $update_customredirect_default . "', '" . (int) $d['id'] . "');"); + $updated_domains ++; } - lastStepStatus(0, 'Updated '.$updated_domains.' domain(s)'); + lastStepStatus(0, 'Updated ' . $updated_domains . ' domain(s)'); showUpdateStep("Adding new settings"); - Database::query("INSERT INTO `" . TABLE_PANEL_SETTINGS . "` (`settinggroup`, `varname`, `value`) VALUES ('customredirect', 'enabled', '".(int)$update_customredirect_enable."');"); - Database::query("INSERT INTO `" . TABLE_PANEL_SETTINGS . "` (`settinggroup`, `varname`, `value`) VALUES ('customredirect', 'default', '".(int)$update_customredirect_default."');"); + Database::query("INSERT INTO `" . TABLE_PANEL_SETTINGS . "` (`settinggroup`, `varname`, `value`) VALUES ('customredirect', 'enabled', '" . (int) $update_customredirect_enable . "');"); + Database::query("INSERT INTO `" . TABLE_PANEL_SETTINGS . "` (`settinggroup`, `varname`, `value`) VALUES ('customredirect', 'default', '" . (int) $update_customredirect_default . "');"); lastStepStatus(0); // need to fix default-error-copy-and-paste-shizzle @@ -713,24 +703,24 @@ if (isFroxlorVersion('0.9.6')) { } lastStepStatus(0); - updateToVersion('0.9.7-svn1'); + \Froxlor\Froxlor::updateToVersion('0.9.7-svn1'); } -if (isFroxlorVersion('0.9.7-svn1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.7-svn1')) { showUpdateStep("Updating from 0.9.7-svn1 to 0.9.7-svn2", false); showUpdateStep("Updating open_basedir due to security - issue"); $result = Database::query("SELECT `id` FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `documentroot` LIKE '%:%' AND `documentroot` NOT LIKE 'http://%' AND `openbasedir_path` = '0' AND `openbasedir` = '1'"); while ($row = $result->fetch(PDO::FETCH_ASSOC)) { - Database::query("UPDATE `".TABLE_PANEL_DOMAINS."` SET `openbasedir_path` = '1' WHERE `id` = '" . (int)$row['id']."'"); + Database::query("UPDATE `" . TABLE_PANEL_DOMAINS . "` SET `openbasedir_path` = '1' WHERE `id` = '" . (int) $row['id'] . "'"); } lastStepStatus(0); - updateToVersion('0.9.7-svn2'); + \Froxlor\Froxlor::updateToVersion('0.9.7-svn2'); } -if (isFroxlorVersion('0.9.7-svn2')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.7-svn2')) { showUpdateStep("Updating from 0.9.7-svn2 to 0.9.7-svn3", false); @@ -746,40 +736,40 @@ if (isFroxlorVersion('0.9.7-svn2')) { Database::query("UPDATE `redirect_codes` SET `desc` = 'rc_tempred' WHERE `code` = '307';"); lastStepStatus(0); - updateToVersion('0.9.7-svn3'); + \Froxlor\Froxlor::updateToVersion('0.9.7-svn3'); } -if (isFroxlorVersion('0.9.7-svn3')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.7-svn3')) { showUpdateStep("Updating from 0.9.7-svn3 to 0.9.7 final"); lastStepStatus(0); - updateToVersion('0.9.7'); + \Froxlor\Froxlor::updateToVersion('0.9.7'); } -if (isFroxlorVersion('0.9.7')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.7')) { showUpdateStep("Updating from 0.9.7 to 0.9.8 final"); lastStepStatus(0); - updateToVersion('0.9.8'); + \Froxlor\Froxlor::updateToVersion('0.9.8'); } -if (isFroxlorVersion('0.9.8')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.8')) { showUpdateStep("Updating from 0.9.8 to 0.9.9-svn1", false); $update_defdns_mailentry = isset($_POST['update_defdns_mailentry']) ? '1' : '0'; showUpdateStep("Adding new settings"); - Database::query("INSERT INTO `" . TABLE_PANEL_SETTINGS . "` (`settinggroup`, `varname`, `value`) VALUES ('system', 'dns_createmailentry', '".(int)$update_defdns_mailentry."');"); + Database::query("INSERT INTO `" . TABLE_PANEL_SETTINGS . "` (`settinggroup`, `varname`, `value`) VALUES ('system', 'dns_createmailentry', '" . (int) $update_defdns_mailentry . "');"); lastStepStatus(0); - updateToVersion('0.9.9-svn1'); + \Froxlor\Froxlor::updateToVersion('0.9.9-svn1'); } -if (isFroxlorVersion('0.9.9-svn1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.9-svn1')) { showUpdateStep("Updating from 0.9.9-svn1 to 0.9.9 final"); lastStepStatus(0); - updateToVersion('0.9.9'); + \Froxlor\Froxlor::updateToVersion('0.9.9'); } -if (isFroxlorVersion('0.9.9')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.9')) { showUpdateStep("Updating from 0.9.9 to 0.9.10-svn1", false); @@ -796,9 +786,10 @@ if (isFroxlorVersion('0.9.9')) { INSERT INTO `" . TABLE_PANEL_SETTINGS . "` SET `settinggroup` = 'system', `varname` = 'httpuser', - `value` = :user" - ); - Database::pexecute($stmt, array(':user' => $update_httpuser)); + `value` = :user"); + Database::pexecute($stmt, array( + ':user' => $update_httpuser + )); lastStepStatus(0); Settings::Set('system.httpuser', $update_httpuser); } @@ -810,9 +801,10 @@ if (isFroxlorVersion('0.9.9')) { INSERT INTO `" . TABLE_PANEL_SETTINGS . "` SET `settinggroup` = 'system', `varname` = 'httpgroup', - `value` = :grp" - ); - Database::pexecute($stmt, array(':grp' => $update_httpgroup)); + `value` = :grp"); + Database::pexecute($stmt, array( + ':grp' => $update_httpgroup + )); lastStepStatus(0); Settings::Set('system.httpgroup', $update_httpgroup); } @@ -820,7 +812,7 @@ if (isFroxlorVersion('0.9.9')) { $result_stmt = Database::query("SELECT * FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `settinggroup` = 'system' AND `varname` = 'debug_cron'"); $result = $result_stmt->fetch(PDO::FETCH_ASSOC); - if (!isset($result) || !isset($result['value'])) { + if (! isset($result) || ! isset($result['value'])) { $nonefound = false; showUpdateStep("Adding missing setting 'debug_cron'"); Database::query("INSERT INTO `" . TABLE_PANEL_SETTINGS . "` (`settinggroup`, `varname`, `value`) VALUES ('system', 'debug_cron', '0');"); @@ -832,10 +824,10 @@ if (isFroxlorVersion('0.9.9')) { lastStepStatus(0); } - updateToVersion('0.9.10-svn1'); + \Froxlor\Froxlor::updateToVersion('0.9.10-svn1'); } -if (isFroxlorVersion('0.9.10-svn1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.10-svn1')) { showUpdateStep("Updating from 0.9.10-svn1 to 0.9.10-svn2", false); @@ -860,41 +852,40 @@ if (isFroxlorVersion('0.9.10-svn1')) { `databasename` = :dbname, `description` = :dbdesc, `dbserver` = '0', - `apsdb` = '1'" - ); + `apsdb` = '1'"); Database::pexecute($result, array( 'cid' => $cid, 'dbname' => $row['Database'], - 'dbdesc' => $databasedescription, + 'dbdesc' => $databasedescription )); - Database::query('UPDATE `' . TABLE_PANEL_CUSTOMERS . '` SET `mysqls_used`=`mysqls_used`+1 WHERE `customerid`="' . (int)$cid . '"'); - $count_dbupdates++; + Database::query('UPDATE `' . TABLE_PANEL_CUSTOMERS . '` SET `mysqls_used`=`mysqls_used`+1 WHERE `customerid`="' . (int) $cid . '"'); + $count_dbupdates ++; } } if ($count_dbupdates > 0) { - lastStepStatus(0, "Found ".$count_dbupdates." customer APS databases"); + lastStepStatus(0, "Found " . $count_dbupdates . " customer APS databases"); } else { lastStepStatus(0, "None found"); } - updateToVersion('0.9.10-svn2'); + \Froxlor\Froxlor::updateToVersion('0.9.10-svn2'); } -if (isFroxlorVersion('0.9.10-svn2')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.10-svn2')) { showUpdateStep("Updating from 0.9.10-svn2 to 0.9.10", false); - $update_directlyviahostname = isset($_POST['update_directlyviahostname']) ? (int)$_POST['update_directlyviahostname'] : '0'; + $update_directlyviahostname = isset($_POST['update_directlyviahostname']) ? (int) $_POST['update_directlyviahostname'] : '0'; showUpdateStep("Adding new settings"); - Database::query("INSERT INTO `" . TABLE_PANEL_SETTINGS . "` (`settinggroup`, `varname`, `value`) VALUES ('system', 'froxlordirectlyviahostname', '".(int)$update_directlyviahostname."');"); + Database::query("INSERT INTO `" . TABLE_PANEL_SETTINGS . "` (`settinggroup`, `varname`, `value`) VALUES ('system', 'froxlordirectlyviahostname', '" . (int) $update_directlyviahostname . "');"); lastStepStatus(0); - updateToVersion('0.9.10'); + \Froxlor\Froxlor::updateToVersion('0.9.10'); } -if (isFroxlorVersion('0.9.10')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.10')) { showUpdateStep("Updating from 0.9.10 to 0.9.11-svn1", false); $update_pwdregex = isset($_POST['update_pwdregex']) ? $_POST['update_pwdregex'] : ''; @@ -904,26 +895,27 @@ if (isFroxlorVersion('0.9.10')) { INSERT INTO `" . TABLE_PANEL_SETTINGS . "` SET `settinggroup` = 'panel', `varname` = 'password_regex', - `value` = :regex" - ); - Database::pexecute($stmt, array('regex' => $update_pwdregex)); + `value` = :regex"); + Database::pexecute($stmt, array( + 'regex' => $update_pwdregex + )); lastStepStatus(0); - updateToVersion('0.9.11-svn1'); + \Froxlor\Froxlor::updateToVersion('0.9.11-svn1'); } -if (isFroxlorVersion('0.9.11-svn1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.11-svn1')) { showUpdateStep("Updating from 0.9.11-svn1 to 0.9.11-svn2", false); showUpdateStep("Adding perl/CGI directory fields"); - Database::query("ALTER TABLE `".TABLE_PANEL_HTACCESS."` ADD `options_cgi` tinyint(1) NOT NULL default '0' AFTER `error401path`;"); - Database::query("ALTER TABLE `".TABLE_PANEL_CUSTOMERS."` ADD `perlenabled` tinyint(1) NOT NULL default '0' AFTER `aps_packages_used`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_HTACCESS . "` ADD `options_cgi` tinyint(1) NOT NULL default '0' AFTER `error401path`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` ADD `perlenabled` tinyint(1) NOT NULL default '0' AFTER `aps_packages_used`;"); lastStepStatus(0); - updateToVersion('0.9.11-svn2'); + \Froxlor\Froxlor::updateToVersion('0.9.11-svn2'); } -if (isFroxlorVersion('0.9.11-svn2')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.11-svn2')) { showUpdateStep("Updating from 0.9.11-svn2 to 0.9.11-svn3", false); $update_perlpath = isset($_POST['update_perlpath']) ? $_POST['update_perlpath'] : '/usr/bin/perl'; @@ -933,31 +925,32 @@ if (isFroxlorVersion('0.9.11-svn2')) { INSERT INTO `" . TABLE_PANEL_SETTINGS . "` SET `settinggroup` = 'system', `varname` = 'perl_path', - `value` = :path" - ); - Database::pexecute($stmt, array('path' => $update_perlpath)); + `value` = :path"); + Database::pexecute($stmt, array( + 'path' => $update_perlpath + )); lastStepStatus(0); - updateToVersion('0.9.11-svn3'); + \Froxlor\Froxlor::updateToVersion('0.9.11-svn3'); } -if (isFroxlorVersion('0.9.11-svn3')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.11-svn3')) { showUpdateStep("Updating from 0.9.11-svn3 to 0.9.11 final"); lastStepStatus(0); - updateToVersion('0.9.11'); + \Froxlor\Froxlor::updateToVersion('0.9.11'); } -if (isFroxlorVersion('0.9.11')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.11')) { showUpdateStep("Updating from 0.9.11 to 0.9.12-svn1", false); - $update_fcgid_ownvhost = isset($_POST['update_fcgid_ownvhost']) ? (int)$_POST['update_fcgid_ownvhost'] : '0'; + $update_fcgid_ownvhost = isset($_POST['update_fcgid_ownvhost']) ? (int) $_POST['update_fcgid_ownvhost'] : '0'; $update_fcgid_httpuser = isset($_POST['update_fcgid_httpuser']) ? $_POST['update_fcgid_httpuser'] : 'froxlorlocal'; $update_fcgid_httpgroup = isset($_POST['update_fcgid_httpgroup']) ? $_POST['update_fcgid_httpgroup'] : 'froxlorlocal'; - if($update_fcgid_httpuser == '') { + if ($update_fcgid_httpuser == '') { $update_fcgid_httpuser = 'froxlorlocal'; } - if($update_fcgid_httpgroup == '') { + if ($update_fcgid_httpgroup == '') { $update_fcgid_httpgroup = 'froxlorlocal'; } @@ -966,24 +959,32 @@ if (isFroxlorVersion('0.9.11')) { INSERT INTO `" . TABLE_PANEL_SETTINGS . "` SET `settinggroup` = 'system', `varname` = :varname, - `value` = :value" - ); - Database::pexecute($stmt, array('varname' => 'mod_fcgid_ownvhost', 'value' => $update_fcgid_ownvhost)); - Database::pexecute($stmt, array('varname' => 'mod_fcgid_httpuser', 'value' => $update_fcgid_httpuser)); - Database::pexecute($stmt, array('varname' => 'mod_fcgid_httpgroup', 'value' => $update_fcgid_httpgroup)); + `value` = :value"); + Database::pexecute($stmt, array( + 'varname' => 'mod_fcgid_ownvhost', + 'value' => $update_fcgid_ownvhost + )); + Database::pexecute($stmt, array( + 'varname' => 'mod_fcgid_httpuser', + 'value' => $update_fcgid_httpuser + )); + Database::pexecute($stmt, array( + 'varname' => 'mod_fcgid_httpgroup', + 'value' => $update_fcgid_httpgroup + )); lastStepStatus(0); - updateToVersion('0.9.12-svn1'); + \Froxlor\Froxlor::updateToVersion('0.9.12-svn1'); } -if (isFroxlorVersion('0.9.12-svn1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.12-svn1')) { showUpdateStep("Updating from 0.9.12-svn1 to 0.9.12-svn2", false); - $update_perl_suexecworkaround = isset($_POST['update_perl_suexecworkaround']) ? (int)$_POST['update_perl_suexecworkaround'] : '0'; - $update_perl_suexecpath = isset($_POST['update_perl_suexecpath']) ? makeCorrectDir($_POST['update_perl_suexecpath']) : '/var/www/cgi-bin/'; + $update_perl_suexecworkaround = isset($_POST['update_perl_suexecworkaround']) ? (int) $_POST['update_perl_suexecworkaround'] : '0'; + $update_perl_suexecpath = isset($_POST['update_perl_suexecpath']) ? \Froxlor\FileDir::makeCorrectDir($_POST['update_perl_suexecpath']) : '/var/www/cgi-bin/'; - if($update_perl_suexecpath == '') { + if ($update_perl_suexecpath == '') { $update_perl_suexecpath = '/var/www/cgi-bin/'; } @@ -992,46 +993,52 @@ if (isFroxlorVersion('0.9.12-svn1')) { INSERT INTO `" . TABLE_PANEL_SETTINGS . "` SET `settinggroup` = 'perl', `varname` = :varname, - `value` = :value" - ); - Database::pexecute($stmt, array('varname' => 'suexecworkaround', 'value' => $update_perl_suexecworkaround)); - Database::pexecute($stmt, array('varname' => 'suexecpath', 'value' => $update_perl_suexecpath)); + `value` = :value"); + Database::pexecute($stmt, array( + 'varname' => 'suexecworkaround', + 'value' => $update_perl_suexecworkaround + )); + Database::pexecute($stmt, array( + 'varname' => 'suexecpath', + 'value' => $update_perl_suexecpath + )); lastStepStatus(0); - updateToVersion('0.9.12-svn2'); + \Froxlor\Froxlor::updateToVersion('0.9.12-svn2'); } -if (isFroxlorVersion('0.9.12-svn2')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.12-svn2')) { showUpdateStep("Updating from 0.9.12-svn2 to 0.9.12-svn3", false); showUpdateStep("Adding new field to domain table"); - Database::query("ALTER TABLE `".TABLE_PANEL_DOMAINS."` ADD `ismainbutsubto` int(11) unsigned NOT NULL default '0' AFTER `mod_fcgid_maxrequests`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `ismainbutsubto` int(11) unsigned NOT NULL default '0' AFTER `mod_fcgid_maxrequests`;"); lastStepStatus(0); - updateToVersion('0.9.12-svn3'); + \Froxlor\Froxlor::updateToVersion('0.9.12-svn3'); } -if (isFroxlorVersion('0.9.12-svn3')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.12-svn3')) { showUpdateStep("Updating from 0.9.12-svn3 to 0.9.12-svn4", false); - $update_awstats_awstatspath = isset($_POST['update_awstats_awstatspath']) ? makeCorrectDir($_POST['update_awstats_awstatspath']) : Settings::Get('system.awstats_path'); + $update_awstats_awstatspath = isset($_POST['update_awstats_awstatspath']) ? \Froxlor\FileDir::makeCorrectDir($_POST['update_awstats_awstatspath']) : Settings::Get('system.awstats_path'); showUpdateStep("Adding new settings for awstats"); $stmt = Database::prepare(" INSERT INTO `" . TABLE_PANEL_SETTINGS . "` SET `settinggroup` = 'system', `varname` = 'awstats_awstatspath', - `value` = :value" - ); - Database::pexecute($stmt, array('value' => $update_awstats_awstatspath)); + `value` = :value"); + Database::pexecute($stmt, array( + 'value' => $update_awstats_awstatspath + )); lastStepStatus(0); - updateToVersion('0.9.12-svn4'); + \Froxlor\Froxlor::updateToVersion('0.9.12-svn4'); } -if (isFroxlorVersion('0.9.12-svn4')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.12-svn4')) { showUpdateStep("Updating from 0.9.12-svn4 to 0.9.12-svn5", false); @@ -1039,44 +1046,44 @@ if (isFroxlorVersion('0.9.12-svn4')) { Database::query("UPDATE `cronjobs_run` SET `interval`='1 DAY' WHERE `cronfile`='cron_used_tickets_reset.php';"); lastStepStatus(0); - updateToVersion('0.9.12-svn5'); + \Froxlor\Froxlor::updateToVersion('0.9.12-svn5'); } -if (isFroxlorVersion('0.9.12-svn5')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.12-svn5')) { showUpdateStep("Updating from 0.9.12-svn5 to 0.9.12-svn6", false); showUpdateStep("Adding new field to table 'panel_htpasswds'"); - Database::query("ALTER TABLE `".TABLE_PANEL_HTPASSWDS."` ADD `authname` varchar(255) NOT NULL default 'Restricted Area' AFTER `password`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_HTPASSWDS . "` ADD `authname` varchar(255) NOT NULL default 'Restricted Area' AFTER `password`;"); lastStepStatus(0); - updateToVersion('0.9.12-svn6'); + \Froxlor\Froxlor::updateToVersion('0.9.12-svn6'); } -if (isFroxlorVersion('0.9.12-svn6')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.12-svn6')) { showUpdateStep("Updating from 0.9.12-svn6 to 0.9.12 final"); lastStepStatus(0); - updateToVersion('0.9.12'); + \Froxlor\Froxlor::updateToVersion('0.9.12'); } -if (isFroxlorVersion('0.9.12')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.12')) { showUpdateStep("Updating from 0.9.12 to 0.9.13-svn1", false); showUpdateStep("Adding new fields to admin-table"); - Database::query("ALTER TABLE `".TABLE_PANEL_ADMINS."` ADD `email_autoresponder` int(5) NOT NULL default '0' AFTER `aps_packages_used`;"); - Database::query("ALTER TABLE `".TABLE_PANEL_ADMINS."` ADD `email_autoresponder_used` int(5) NOT NULL default '0' AFTER `email_autoresponder`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_ADMINS . "` ADD `email_autoresponder` int(5) NOT NULL default '0' AFTER `aps_packages_used`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_ADMINS . "` ADD `email_autoresponder_used` int(5) NOT NULL default '0' AFTER `email_autoresponder`;"); lastStepStatus(0); showUpdateStep("Adding new fields to customer-table"); - Database::query("ALTER TABLE `".TABLE_PANEL_CUSTOMERS."` ADD `email_autoresponder` int(5) NOT NULL default '0' AFTER `perlenabled`;"); - Database::query("ALTER TABLE `".TABLE_PANEL_CUSTOMERS."` ADD `email_autoresponder_used` int(5) NOT NULL default '0' AFTER `email_autoresponder`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` ADD `email_autoresponder` int(5) NOT NULL default '0' AFTER `perlenabled`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` ADD `email_autoresponder_used` int(5) NOT NULL default '0' AFTER `email_autoresponder`;"); lastStepStatus(0); - if ((int)Settings::Get('autoresponder.autoresponder_active') == 1) { - $update_autoresponder_default = isset($_POST['update_autoresponder_default']) ? intval_ressource($_POST['update_autoresponder_default']) : 0; + if ((int) Settings::Get('autoresponder.autoresponder_active') == 1) { + $update_autoresponder_default = isset($_POST['update_autoresponder_default']) ? (int)($_POST['update_autoresponder_default']) : 0; if (isset($_POST['update_autoresponder_default_ul'])) { - $update_autoresponder_default = -1; + $update_autoresponder_default = - 1; } } else { $update_autoresponder_default = 0; @@ -1084,84 +1091,88 @@ if (isFroxlorVersion('0.9.12')) { showUpdateStep("Setting default amount of autoresponders"); // admin gets unlimited - Database::query("UPDATE `".TABLE_PANEL_ADMINS."` SET `email_autoresponder`='-1' WHERE `adminid` = '".(int)$userinfo['adminid']."'"); + Database::query("UPDATE `" . TABLE_PANEL_ADMINS . "` SET `email_autoresponder`='-1' WHERE `adminid` = '" . (int) $userinfo['adminid'] . "'"); // customers - Database::query("UPDATE `".TABLE_PANEL_CUSTOMERS."` SET `email_autoresponder`='".(int)$update_autoresponder_default."' WHERE `deactivated` = '0'"); + Database::query("UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET `email_autoresponder`='" . (int) $update_autoresponder_default . "' WHERE `deactivated` = '0'"); lastStepStatus(0); - updateToVersion('0.9.13-svn1'); + \Froxlor\Froxlor::updateToVersion('0.9.13-svn1'); } -if (isFroxlorVersion('0.9.13-svn1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.13-svn1')) { showUpdateStep("Updating from 0.9.13-svn1 to 0.9.13 final"); lastStepStatus(0); - updateToVersion('0.9.13'); + \Froxlor\Froxlor::updateToVersion('0.9.13'); } -if (isFroxlorVersion('0.9.13')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.13')) { showUpdateStep("Updating from 0.9.13 to 0.9.13.1 final", false); - $update_defaultini_ownvhost = isset($_POST['update_defaultini_ownvhost']) ? (int)$_POST['update_defaultini_ownvhost'] : 1; + $update_defaultini_ownvhost = isset($_POST['update_defaultini_ownvhost']) ? (int) $_POST['update_defaultini_ownvhost'] : 1; showUpdateStep("Adding settings for Froxlor-vhost's PHP-configuration"); $stmt = Database::prepare(" INSERT INTO `" . TABLE_PANEL_SETTINGS . "` SET `settinggroup` = 'system', `varname` = 'mod_fcgid_defaultini_ownvhost', - `value` = :value" - ); - Database::pexecute($stmt, array('value' => $update_defaultini_ownvhost)); + `value` = :value"); + Database::pexecute($stmt, array( + 'value' => $update_defaultini_ownvhost + )); lastStepStatus(0); - updateToVersion('0.9.13.1'); + \Froxlor\Froxlor::updateToVersion('0.9.13.1'); } /** * be compatible with the few who already use 0.9.14-svn1 */ -if (isFroxlorVersion('0.9.14-svn1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.14-svn1')) { showUpdateStep("Resetting version 0.9.14-svn1 to 0.9.13.1"); lastStepStatus(0); - updateToVersion('0.9.13.1'); + \Froxlor\Froxlor::updateToVersion('0.9.13.1'); } -if (isFroxlorVersion('0.9.13.1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.13.1')) { showUpdateStep("Updating from 0.9.13.1 to 0.9.14-svn2", false); if (Settings::Get('ticket.enabled') == '1') { showUpdateStep("Setting INTERVAL for used-tickets cronjob"); - setCycleOfCronjob(null, null, Settings::Get('ticket.reset_cycle'), null); + if (function_exists("setCycleOfCronjob")) { + setCycleOfCronjob(null, null, Settings::Get('ticket.reset_cycle'), null); + } lastStepStatus(0); } - updateToVersion('0.9.14-svn2'); + \Froxlor\Froxlor::updateToVersion('0.9.14-svn2'); } -if (isFroxlorVersion('0.9.14-svn2')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.14-svn2')) { showUpdateStep("Updating from 0.9.14-svn2 to 0.9.14-svn3", false); - $update_awstats_icons = isset($_POST['update_awstats_icons']) ? makeCorrectDir($_POST['update_awstats_icons']) : Settings::Get('system.awstats_icons'); + $update_awstats_icons = isset($_POST['update_awstats_icons']) ? \Froxlor\FileDir::makeCorrectDir($_POST['update_awstats_icons']) : Settings::Get('system.awstats_icons'); showUpdateStep("Adding AWStats icons path to the settings"); $stmt = Database::prepare(" INSERT INTO `" . TABLE_PANEL_SETTINGS . "` SET `settinggroup` = 'system', `varname` = 'awstats_icons', - `value` = :value" - ); - Database::pexecute($stmt, array('value' => $update_awstats_icons)); + `value` = :value"); + Database::pexecute($stmt, array( + 'value' => $update_awstats_icons + )); lastStepStatus(0); - updateToVersion('0.9.14-svn3'); + \Froxlor\Froxlor::updateToVersion('0.9.14-svn3'); } -if (isFroxlorVersion('0.9.14-svn3')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.14-svn3')) { showUpdateStep("Updating from 0.9.14-svn3 to 0.9.14-svn4", false); $update_ssl_cert_chainfile = isset($_POST['update_ssl_cert_chainfile']) ? $_POST['update_ssl_cert_chainfile'] : ''; if ($update_ssl_cert_chainfile != '') { - $update_ssl_cert_chainfile = makeCorrectFile($update_ssl_cert_chainfile); + $update_ssl_cert_chainfile = \Froxlor\FileDir::makeCorrectFile($update_ssl_cert_chainfile); } showUpdateStep("Adding SSLCertificateChainFile to the settings"); @@ -1169,48 +1180,50 @@ if (isFroxlorVersion('0.9.14-svn3')) { INSERT INTO `" . TABLE_PANEL_SETTINGS . "` SET `settinggroup` = 'system', `varname` = 'ssl_cert_chainfile', - `value` = :value" - ); - Database::pexecute($stmt, array('value' => $update_ssl_cert_chainfile)); + `value` = :value"); + Database::pexecute($stmt, array( + 'value' => $update_ssl_cert_chainfile + )); lastStepStatus(0); showUpdateStep("Adding new field to IPs and ports for SSLCertificateChainFile"); - Database::query("ALTER TABLE `".TABLE_PANEL_IPSANDPORTS."` ADD `ssl_cert_chainfile` varchar(255) NOT NULL AFTER `default_vhostconf_domain`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_IPSANDPORTS . "` ADD `ssl_cert_chainfile` varchar(255) NOT NULL AFTER `default_vhostconf_domain`;"); lastStepStatus(0); - updateToVersion('0.9.14-svn4'); + \Froxlor\Froxlor::updateToVersion('0.9.14-svn4'); } -if (isFroxlorVersion('0.9.14-svn4')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.14-svn4')) { showUpdateStep("Updating from 0.9.14-svn4 to 0.9.14-svn5", false); showUpdateStep("Adding docroot-field to IPs and ports for custom-docroot settings"); - Database::query("ALTER TABLE `".TABLE_PANEL_IPSANDPORTS."` ADD `docroot` varchar(255) NOT NULL default '' AFTER `ssl_cert_chainfile`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_IPSANDPORTS . "` ADD `docroot` varchar(255) NOT NULL default '' AFTER `ssl_cert_chainfile`;"); lastStepStatus(0); - updateToVersion('0.9.14-svn5'); + \Froxlor\Froxlor::updateToVersion('0.9.14-svn5'); } -if (isFroxlorVersion('0.9.14-svn5')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.14-svn5')) { showUpdateStep("Updating from 0.9.14-svn5 to 0.9.14-svn6", false); - $update_allow_domain_login = isset($_POST['update_allow_domain_login']) ? (int)$_POST['update_allow_domain_login'] : '0'; + $update_allow_domain_login = isset($_POST['update_allow_domain_login']) ? (int) $_POST['update_allow_domain_login'] : '0'; showUpdateStep("Adding domain-login switch to the settings"); $stmt = Database::prepare(" INSERT INTO `" . TABLE_PANEL_SETTINGS . "` SET `settinggroup` = 'login', `varname` = 'domain_login', - `value` = :value" - ); - Database::pexecute($stmt, array('value' => $update_allow_domain_login)); + `value` = :value"); + Database::pexecute($stmt, array( + 'value' => $update_allow_domain_login + )); lastStepStatus(0); - updateToVersion('0.9.14-svn6'); + \Froxlor\Froxlor::updateToVersion('0.9.14-svn6'); } -if (isFroxlorVersion('0.9.14-svn6')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.14-svn6')) { showUpdateStep("Updating from 0.9.14-svn6 to 0.9.14-svn10", false); // remove deprecated realtime-feature @@ -1234,60 +1247,60 @@ if (isFroxlorVersion('0.9.14-svn6')) { lastStepStatus(0); showUpdateStep("Removing deprecated legacy-cronjob from database"); - Database::query("DELETE FROM `".TABLE_PANEL_CRONRUNS."` WHERE `cronfile` ='cron_legacy.php';"); + Database::query("DELETE FROM `" . TABLE_PANEL_CRONRUNS . "` WHERE `cronfile` ='cron_legacy.php';"); lastStepStatus(0); - updateToVersion('0.9.14-svn10'); + \Froxlor\Froxlor::updateToVersion('0.9.14-svn10'); } /* * revert database changes we did for multiserver-support -* before branching - sorry guys :/ -*/ -if (isFroxlorVersion('0.9.14-svn9')) { + * before branching - sorry guys :/ + */ +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.14-svn9')) { showUpdateStep("Reverting multiserver-patches (svn)", false); - $update_allow_domain_login = isset($_POST['update_allow_domain_login']) ? (int)$_POST['update_allow_domain_login'] : '0'; + $update_allow_domain_login = isset($_POST['update_allow_domain_login']) ? (int) $_POST['update_allow_domain_login'] : '0'; showUpdateStep("Reverting database table-changes"); - Database::query("ALTER TABLE `".TABLE_PANEL_SETTINGS."` DROP `sid`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_SETTINGS . "` DROP `sid`;"); showUpdateStep("."); - Database::query("ALTER TABLE `".TABLE_PANEL_CUSTOMERS."` DROP `sid`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` DROP `sid`;"); showUpdateStep("."); - Database::query("ALTER TABLE `".TABLE_MAIL_VIRTUAL."` DROP `sid`;"); + Database::query("ALTER TABLE `" . TABLE_MAIL_VIRTUAL . "` DROP `sid`;"); showUpdateStep("."); - Database::query("ALTER TABLE `".TABLE_FTP_USERS."` DROP `sid`;"); + Database::query("ALTER TABLE `" . TABLE_FTP_USERS . "` DROP `sid`;"); showUpdateStep("."); - Database::query("ALTER TABLE `".TABLE_PANEL_TASKS."` DROP `sid`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_TASKS . "` DROP `sid`;"); showUpdateStep("."); - Database::query("ALTER TABLE `".TABLE_APS_TASKS."` DROP `sid`;"); + Database::query("ALTER TABLE `" . TABLE_APS_TASKS . "` DROP `sid`;"); showUpdateStep("."); - Database::query("ALTER TABLE `".TABLE_PANEL_LOG."` DROP `sid`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_LOG . "` DROP `sid`;"); showUpdateStep("."); - Database::query("ALTER TABLE `".TABLE_PANEL_PHPCONFIGS."` DROP `sid`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_PHPCONFIGS . "` DROP `sid`;"); lastStepStatus(0); showUpdateStep("Removing froxlor-clients table"); Database::query("DROP TABLE IF EXISTS `froxlor_clients`"); lastStepStatus(0); - updateToVersion('0.9.14-svn10'); + \Froxlor\Froxlor::updateToVersion('0.9.14-svn10'); } -if (isFroxlorVersion('0.9.14-svn10')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.14-svn10')) { showUpdateStep("Updating from 0.9.14-svn10 to 0.9.14 final"); lastStepStatus(0); - updateToVersion('0.9.14'); + \Froxlor\Froxlor::updateToVersion('0.9.14'); } -if (isFroxlorVersion('0.9.14')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.14')) { showUpdateStep("Updating from 0.9.14 to 0.9.15-svn1", false); showUpdateStep("Adding new settings for Nginx support"); @@ -1295,39 +1308,47 @@ if (isFroxlorVersion('0.9.14')) { INSERT INTO `" . TABLE_PANEL_SETTINGS . "` SET `settinggroup` = 'system', `varname` = :varname, - `value` = :value" - ); - Database::pexecute($stmt, array('varname' => 'nginx_php_backend', 'value' => '127.0.0.1:8888')); - Database::pexecute($stmt, array('varname' => 'perl_server', 'value' => 'unix:/var/run/nginx/cgiwrap-dispatch.sock')); - Database::pexecute($stmt, array('varname' => 'phpreload_command', 'value' => '')); + `value` = :value"); + Database::pexecute($stmt, array( + 'varname' => 'nginx_php_backend', + 'value' => '127.0.0.1:8888' + )); + Database::pexecute($stmt, array( + 'varname' => 'perl_server', + 'value' => 'unix:/var/run/nginx/cgiwrap-dispatch.sock' + )); + Database::pexecute($stmt, array( + 'varname' => 'phpreload_command', + 'value' => '' + )); lastStepStatus(0); - updateToVersion('0.9.15-svn1'); + \Froxlor\Froxlor::updateToVersion('0.9.15-svn1'); } -if (isFroxlorVersion('0.9.15-svn1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.15-svn1')) { showUpdateStep("Updating from 0.9.15-svn1 to 0.9.15 final"); lastStepStatus(0); - updateToVersion('0.9.15'); + \Froxlor\Froxlor::updateToVersion('0.9.15'); } -if (isFroxlorVersion('0.9.15')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.15')) { showUpdateStep("Updating from 0.9.15 to 0.9.16-svn1", false); - $update_phpfpm_enabled = isset($_POST['update_phpfpm_enabled']) ? (int)$_POST['update_phpfpm_enabled'] : '0'; - $update_phpfpm_configdir = isset($_POST['update_phpfpm_configdir']) ? makeCorrectDir($_POST['update_phpfpm_configdir']) : '/etc/php-fpm.d/'; - $update_phpfpm_tmpdir = isset($_POST['update_phpfpm_tmpdir']) ? makeCorrectDir($_POST['update_phpfpm_tmpdir']) : '/var/customers/tmp'; - $update_phpfpm_peardir = isset($_POST['update_phpfpm_peardir']) ? makeCorrectDir($_POST['update_phpfpm_peardir']) : '/usr/share/php/:/usr/share/php5/'; + $update_phpfpm_enabled = isset($_POST['update_phpfpm_enabled']) ? (int) $_POST['update_phpfpm_enabled'] : '0'; + $update_phpfpm_configdir = isset($_POST['update_phpfpm_configdir']) ? \Froxlor\FileDir::makeCorrectDir($_POST['update_phpfpm_configdir']) : '/etc/php-fpm.d/'; + $update_phpfpm_tmpdir = isset($_POST['update_phpfpm_tmpdir']) ? \Froxlor\FileDir::makeCorrectDir($_POST['update_phpfpm_tmpdir']) : '/var/customers/tmp'; + $update_phpfpm_peardir = isset($_POST['update_phpfpm_peardir']) ? \Froxlor\FileDir::makeCorrectDir($_POST['update_phpfpm_peardir']) : '/usr/share/php/:/usr/share/php5/'; $update_phpfpm_reload = isset($_POST['update_phpfpm_reload']) ? $_POST['update_phpfpm_reload'] : '/etc/init.d/php-fpm restart'; $update_phpfpm_pm = isset($_POST['update_phpfpm_pm']) ? $_POST['update_phpfpm_pm'] : 'static'; - $update_phpfpm_max_children = isset($_POST['update_phpfpm_max_children']) ? (int)$_POST['update_phpfpm_max_children'] : '1'; - $update_phpfpm_max_requests = isset($_POST['update_phpfpm_max_requests']) ? (int)$_POST['update_phpfpm_max_requests'] : '0'; + $update_phpfpm_max_children = isset($_POST['update_phpfpm_max_children']) ? (int) $_POST['update_phpfpm_max_children'] : '1'; + $update_phpfpm_max_requests = isset($_POST['update_phpfpm_max_requests']) ? (int) $_POST['update_phpfpm_max_requests'] : '0'; if ($update_phpfpm_pm == 'dynamic') { - $update_phpfpm_start_servers = isset($_POST['update_phpfpm_start_servers']) ? (int)$_POST['update_phpfpm_start_servers'] : '20'; - $update_phpfpm_min_spare_servers = isset($_POST['update_phpfpm_min_spare_servers']) ? (int)$_POST['update_phpfpm_min_spare_servers'] : '5'; - $update_phpfpm_max_spare_servers = isset($_POST['update_phpfpm_max_spare_servers']) ? (int)$_POST['update_phpfpm_max_spare_servers'] : '35'; + $update_phpfpm_start_servers = isset($_POST['update_phpfpm_start_servers']) ? (int) $_POST['update_phpfpm_start_servers'] : '20'; + $update_phpfpm_min_spare_servers = isset($_POST['update_phpfpm_min_spare_servers']) ? (int) $_POST['update_phpfpm_min_spare_servers'] : '5'; + $update_phpfpm_max_spare_servers = isset($_POST['update_phpfpm_max_spare_servers']) ? (int) $_POST['update_phpfpm_max_spare_servers'] : '35'; } else { $update_phpfpm_start_servers = 20; $update_phpfpm_min_spare_servers = 5; @@ -1346,28 +1367,60 @@ if (isFroxlorVersion('0.9.15')) { INSERT INTO `" . TABLE_PANEL_SETTINGS . "` SET `settinggroup` = 'phpfpm', `varname` = :varname, - `value` = :value" - ); - Database::pexecute($stmt, array('varname' => 'enabled', 'value' => $update_phpfpm_enabled)); - Database::pexecute($stmt, array('varname' => 'configdir', 'value' => $update_phpfpm_configdir)); - Database::pexecute($stmt, array('varname' => 'reload', 'value' => $update_phpfpm_reload)); - Database::pexecute($stmt, array('varname' => 'pm', 'value' => $update_phpfpm_pm)); - Database::pexecute($stmt, array('varname' => 'max_children', 'value' => $update_phpfpm_max_children)); - Database::pexecute($stmt, array('varname' => 'max_requests', 'value' => $update_phpfpm_max_requests)); - Database::pexecute($stmt, array('varname' => 'start_servers', 'value' => $update_phpfpm_start_servers)); - Database::pexecute($stmt, array('varname' => 'min_spare_servers', 'value' => $update_phpfpm_min_spare_servers)); - Database::pexecute($stmt, array('varname' => 'max_spare_servers', 'value' => $update_phpfpm_max_spare_servers)); - Database::pexecute($stmt, array('varname' => 'tmpdir', 'value' => $update_phpfpm_tmpdir)); - Database::pexecute($stmt, array('varname' => 'peardir', 'value' => $update_phpfpm_peardir)); + `value` = :value"); + Database::pexecute($stmt, array( + 'varname' => 'enabled', + 'value' => $update_phpfpm_enabled + )); + Database::pexecute($stmt, array( + 'varname' => 'configdir', + 'value' => $update_phpfpm_configdir + )); + Database::pexecute($stmt, array( + 'varname' => 'reload', + 'value' => $update_phpfpm_reload + )); + Database::pexecute($stmt, array( + 'varname' => 'pm', + 'value' => $update_phpfpm_pm + )); + Database::pexecute($stmt, array( + 'varname' => 'max_children', + 'value' => $update_phpfpm_max_children + )); + Database::pexecute($stmt, array( + 'varname' => 'max_requests', + 'value' => $update_phpfpm_max_requests + )); + Database::pexecute($stmt, array( + 'varname' => 'start_servers', + 'value' => $update_phpfpm_start_servers + )); + Database::pexecute($stmt, array( + 'varname' => 'min_spare_servers', + 'value' => $update_phpfpm_min_spare_servers + )); + Database::pexecute($stmt, array( + 'varname' => 'max_spare_servers', + 'value' => $update_phpfpm_max_spare_servers + )); + Database::pexecute($stmt, array( + 'varname' => 'tmpdir', + 'value' => $update_phpfpm_tmpdir + )); + Database::pexecute($stmt, array( + 'varname' => 'peardir', + 'value' => $update_phpfpm_peardir + )); lastStepStatus(0); - updateToVersion('0.9.16-svn1'); + \Froxlor\Froxlor::updateToVersion('0.9.16-svn1'); } -if (isFroxlorVersion('0.9.16-svn1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.16-svn1')) { showUpdateStep("Updating from 0.9.16-svn1 to 0.9.16-svn2", false); - $update_phpfpm_enabled_ownvhost = isset($_POST['update_phpfpm_enabled_ownvhost']) ? (int)$_POST['update_phpfpm_enabled_ownvhost'] : '0'; + $update_phpfpm_enabled_ownvhost = isset($_POST['update_phpfpm_enabled_ownvhost']) ? (int) $_POST['update_phpfpm_enabled_ownvhost'] : '0'; $update_phpfpm_httpuser = isset($_POST['update_phpfpm_httpuser']) ? $_POST['update_phpfpm_httpuser'] : 'froxlorlocal'; $update_phpfpm_httpgroup = isset($_POST['update_phpfpm_httpgroup']) ? $_POST['update_phpfpm_httpgroup'] : 'froxlorlocal'; @@ -1383,40 +1436,56 @@ if (isFroxlorVersion('0.9.16-svn1')) { INSERT INTO `" . TABLE_PANEL_SETTINGS . "` SET `settinggroup` = 'phpfpm', `varname` = :varname, - `value` = :value" - ); - Database::pexecute($stmt, array('varname' => 'enabled_ownvhost', 'value' => $update_phpfpm_enabled_ownvhost)); - Database::pexecute($stmt, array('varname' => 'vhost_httpuser', 'value' => $update_phpfpm_httpuser)); - Database::pexecute($stmt, array('varname' => 'vhost_httpgroup', 'value' => $update_phpfpm_httpgroup)); + `value` = :value"); + Database::pexecute($stmt, array( + 'varname' => 'enabled_ownvhost', + 'value' => $update_phpfpm_enabled_ownvhost + )); + Database::pexecute($stmt, array( + 'varname' => 'vhost_httpuser', + 'value' => $update_phpfpm_httpuser + )); + Database::pexecute($stmt, array( + 'varname' => 'vhost_httpgroup', + 'value' => $update_phpfpm_httpgroup + )); lastStepStatus(0); - updateToVersion('0.9.16-svn2'); + \Froxlor\Froxlor::updateToVersion('0.9.16-svn2'); } -if (isFroxlorVersion('0.9.16-svn2')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.16-svn2')) { showUpdateStep("Updating from 0.9.16-svn2 to 0.9.16 final"); lastStepStatus(0); - updateToVersion('0.9.16'); + \Froxlor\Froxlor::updateToVersion('0.9.16'); } -if (isFroxlorVersion('0.9.16')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.16')) { showUpdateStep("Updating from 0.9.16 to 0.9.17-svn1", false); - $update_system_report_enable = isset($_POST['update_system_report_enable']) ? (int)$_POST['update_system_report_enable'] : '1'; - $update_system_report_webmax = isset($_POST['update_system_report_webmax']) ? (int)$_POST['update_system_report_webmax'] : '90'; - $update_system_report_trafficmax = isset($_POST['update_system_report_trafficmax']) ? (int)$_POST['update_system_report_trafficmax'] : '90'; + $update_system_report_enable = isset($_POST['update_system_report_enable']) ? (int) $_POST['update_system_report_enable'] : '1'; + $update_system_report_webmax = isset($_POST['update_system_report_webmax']) ? (int) $_POST['update_system_report_webmax'] : '90'; + $update_system_report_trafficmax = isset($_POST['update_system_report_trafficmax']) ? (int) $_POST['update_system_report_trafficmax'] : '90'; showUpdateStep("Adding new settings for web- and traffic-reporting"); $stmt = Database::prepare(" INSERT INTO `" . TABLE_PANEL_SETTINGS . "` SET `settinggroup` = 'system', `varname` = :varname, - `value` = :value" - ); - Database::pexecute($stmt, array('varname' => 'report_enable', 'value' => $update_system_report_enable)); - Database::pexecute($stmt, array('varname' => 'report_webmax', 'value' => $update_system_report_webmax)); - Database::pexecute($stmt, array('varname' => 'report_trafficmax', 'value' => $update_system_report_trafficmax)); + `value` = :value"); + Database::pexecute($stmt, array( + 'varname' => 'report_enable', + 'value' => $update_system_report_enable + )); + Database::pexecute($stmt, array( + 'varname' => 'report_webmax', + 'value' => $update_system_report_webmax + )); + Database::pexecute($stmt, array( + 'varname' => 'report_trafficmax', + 'value' => $update_system_report_trafficmax + )); lastStepStatus(0); showUpdateStep("Adding new cron-module for web- and traffic-reporting"); @@ -1428,43 +1497,39 @@ if (isFroxlorVersion('0.9.16')) { `interval` = '1 DAY', `desc_lng_key` = 'cron_usage_report', `lastrun` = :lastrun, - `isactive` = :isactive" - ); - Database::pexecute($stmt, array('lastrun' => $clastrun, 'isactive' => $update_system_report_enable)); + `isactive` = :isactive"); + Database::pexecute($stmt, array( + 'lastrun' => $clastrun, + 'isactive' => $update_system_report_enable + )); lastStepStatus(0); showUpdateStep("Updating various database-fields"); Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `settinggroup` = 'system' AND `varname` = 'last_traffic_report_run';"); $check_stmt = Database::query(" - SELECT `varname` FROM `" . TABLE_PANEL_TEMPLATES . "` WHERE `varname` = 'trafficninetypercent_subject';" - ); + SELECT `varname` FROM `" . TABLE_PANEL_TEMPLATES . "` WHERE `varname` = 'trafficninetypercent_subject';"); Database::pexecute($check_stmt); $check = $check_stmt->fetch(PDO::FETCH_ASSOC); - if (isset($check['varname']) - && $check['varname'] == 'trafficninetypercent_subject' - ) { + if (isset($check['varname']) && $check['varname'] == 'trafficninetypercent_subject') { Database::query("UPDATE `" . TABLE_PANEL_TEMPLATES . "` SET `varname` = 'trafficmaxpercent_subject' WHERE `varname` = 'trafficninetypercent_subject';"); } $check_stmt = Database::query(" - SELECT `varname` FROM `" . TABLE_PANEL_TEMPLATES . "` WHERE `varname` = 'trafficninetypercent_mailbody';" - ); + SELECT `varname` FROM `" . TABLE_PANEL_TEMPLATES . "` WHERE `varname` = 'trafficninetypercent_mailbody';"); Database::pexecute($check_stmt); $check = $check_stmt->fetch(PDO::FETCH_ASSOC); - if (isset($check['varname']) - && $check['varname'] == 'trafficninetypercent_mailbody' - ) { + if (isset($check['varname']) && $check['varname'] == 'trafficninetypercent_mailbody') { Database::query("UPDATE `" . TABLE_PANEL_TEMPLATES . "` SET `varname` = 'trafficmaxpercent_mailbody' WHERE `varname` = 'trafficninetypercent_mailbody';"); } lastStepStatus(0); - updateToVersion('0.9.17-svn1'); + \Froxlor\Froxlor::updateToVersion('0.9.17-svn1'); } -if (isFroxlorVersion('0.9.17-svn1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.17-svn1')) { showUpdateStep("Updating from 0.9.17-svn1 to 0.9.17-svn2", false); @@ -1483,16 +1548,16 @@ if (isFroxlorVersion('0.9.17-svn1')) { ) ENGINE=MyISAM;"); lastStepStatus(0); - updateToVersion('0.9.17-svn2'); + \Froxlor\Froxlor::updateToVersion('0.9.17-svn2'); } -if (isFroxlorVersion('0.9.17-svn2')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.17-svn2')) { showUpdateStep("Updating from 0.9.17-svn2 to 0.9.17 final"); lastStepStatus(0); - updateToVersion('0.9.17'); + \Froxlor\Froxlor::updateToVersion('0.9.17'); } -if (isFroxlorVersion('0.9.17')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.17')) { showUpdateStep("Updating from 0.9.17 to 0.9.18-svn1", false); @@ -1502,16 +1567,17 @@ if (isFroxlorVersion('0.9.17')) { $result_stmt = Database::query("SELECT * FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `settinggroup` = 'system' AND `varname` = 'httpgroup'"); $result = $result_stmt->fetch(PDO::FETCH_ASSOC); - if (!isset($result) || !isset($result['value'])) { + if (! isset($result) || ! isset($result['value'])) { $nonefound = false; showUpdateStep("Adding missing setting 'httpgroup'"); $stmt = Database::prepare(" INSERT INTO `" . TABLE_PANEL_SETTINGS . "` SET `settinggroup` = 'system', `varname` = 'httpgroup', - `value` = :value" - ); - Database::pexecute($stmt, array('value' => Settings::Get('system.httpuser'))); + `value` = :value"); + Database::pexecute($stmt, array( + 'value' => Settings::Get('system.httpuser') + )); lastStepStatus(0); } @@ -1520,10 +1586,10 @@ if (isFroxlorVersion('0.9.17')) { lastStepStatus(0); } - updateToVersion('0.9.18-svn1'); + \Froxlor\Froxlor::updateToVersion('0.9.18-svn1'); } -if (isFroxlorVersion('0.9.18-svn1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.18-svn1')) { showUpdateStep("Updating from 0.9.18-svn1 to 0.9.18-svn2", false); @@ -1534,9 +1600,10 @@ if (isFroxlorVersion('0.9.18-svn1')) { INSERT INTO `" . TABLE_PANEL_SETTINGS . "` SET `settinggroup` = 'panel', `varname` = 'default_theme', - `value` = :value" - ); - Database::pexecute($stmt, array('value' => $update_default_theme)); + `value` = :value"); + Database::pexecute($stmt, array( + 'value' => $update_default_theme + )); lastStepStatus(0); showUpdateStep("Delete old setting for header-graphic"); @@ -1544,33 +1611,33 @@ if (isFroxlorVersion('0.9.18-svn1')) { lastStepStatus(0); showUpdateStep("Updating table layouts"); - Database::query("ALTER TABLE `".TABLE_PANEL_ADMINS."` ADD `theme` varchar(255) NOT NULL default 'Froxlor' AFTER `email_autoresponder_used`;"); - Database::query("ALTER TABLE `".TABLE_PANEL_CUSTOMERS."` ADD `theme` varchar(255) NOT NULL default 'Froxlor' AFTER `email_autoresponder_used`;"); - Database::query("ALTER TABLE `".TABLE_PANEL_SESSIONS."` ADD `theme` varchar(255) NOT NULL default '' AFTER `adminsession`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_ADMINS . "` ADD `theme` varchar(255) NOT NULL default 'Froxlor' AFTER `email_autoresponder_used`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` ADD `theme` varchar(255) NOT NULL default 'Froxlor' AFTER `email_autoresponder_used`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_SESSIONS . "` ADD `theme` varchar(255) NOT NULL default '' AFTER `adminsession`;"); lastStepStatus(0); - updateToVersion('0.9.18-svn2'); + \Froxlor\Froxlor::updateToVersion('0.9.18-svn2'); } -if (isFroxlorVersion('0.9.18-svn2')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.18-svn2')) { showUpdateStep("Updating from 0.9.18-svn2 to 0.9.18 final"); lastStepStatus(0); - updateToVersion('0.9.18'); + \Froxlor\Froxlor::updateToVersion('0.9.18'); } -if (isFroxlorVersion('0.9.18')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.18')) { showUpdateStep("Updating from 0.9.18 to 0.9.18.1"); lastStepStatus(0); - updateToVersion('0.9.18.1'); + \Froxlor\Froxlor::updateToVersion('0.9.18.1'); } -if (isFroxlorVersion('0.9.18.1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.18.1')) { showUpdateStep("Updating from 0.9.18.1 to 0.9.19"); lastStepStatus(0); - updateToVersion('0.9.19'); + \Froxlor\Froxlor::updateToVersion('0.9.19'); } -if (isFroxlorVersion('0.9.19')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.19')) { showUpdateStep("Updating from 0.9.19 to 0.9.20-svn1"); lastStepStatus(0); @@ -1579,14 +1646,13 @@ if (isFroxlorVersion('0.9.19')) { INSERT INTO `" . TABLE_PANEL_SETTINGS . "` SET `settinggroup` = 'system', `varname` = 'validate_domain', - `value` = '1'" - ); + `value` = '1'"); lastStepStatus(0); - updateToVersion('0.9.20-svn1'); + \Froxlor\Froxlor::updateToVersion('0.9.20-svn1'); } -if (isFroxlorVersion('0.9.20-svn1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.20-svn1')) { showUpdateStep("Updating from 0.9.20-svn1 to 0.9.20-svn2"); @@ -1605,22 +1671,22 @@ if (isFroxlorVersion('0.9.20-svn1')) { Database::query("INSERT INTO `" . TABLE_PANEL_CRONRUNS . "` (`module`, `cronfile`, `interval`, `isactive`, `desc_lng_key`) VALUES ('froxlor/backup', 'cron_backup.php', '1 DAY', '1', 'cron_backup');"); lastStepStatus(0); - updateToVersion('0.9.20-svn2'); + \Froxlor\Froxlor::updateToVersion('0.9.20-svn2'); } -if (isFroxlorVersion('0.9.20-svn2')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.20-svn2')) { showUpdateStep("Updating from 0.9.20-svn2 to 0.9.20"); lastStepStatus(0); - updateToVersion('0.9.20'); + \Froxlor\Froxlor::updateToVersion('0.9.20'); } -if (isFroxlorVersion('0.9.20')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.20')) { showUpdateStep("Updating from 0.9.20 to 0.9.20.1"); lastStepStatus(0); - updateToVersion('0.9.20.1'); + \Froxlor\Froxlor::updateToVersion('0.9.20.1'); } -if (isFroxlorVersion('0.9.20.1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.20.1')) { showUpdateStep("Updating from 0.9.20.1 to 0.9.20.1-svn1"); lastStepStatus(0); @@ -1635,7 +1701,7 @@ if (isFroxlorVersion('0.9.20.1')) { $columnfound = 1; } } - if (!$columnfound) { + if (! $columnfound) { Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` ADD `backup_allowed` TINYINT( 1 ) NOT NULL DEFAULT '1'"); Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` ADD `backup_enabled` TINYINT( 1 ) NOT NULL DEFAULT '0'"); } @@ -1654,10 +1720,10 @@ if (isFroxlorVersion('0.9.20.1')) { } lastStepStatus(0); - updateToVersion('0.9.20.1-svn1'); + \Froxlor\Froxlor::updateToVersion('0.9.20.1-svn1'); } -if (isFroxlorVersion('0.9.20.1-svn1') || isFroxlorVersion('0.9.20.2-svn1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.20.1-svn1') || \Froxlor\Froxlor::isFroxlorVersion('0.9.20.2-svn1')) { showUpdateStep("Updating from 0.9.20.1-svn1 to 0.9.21-svn1"); lastStepStatus(0); @@ -1667,10 +1733,10 @@ if (isFroxlorVersion('0.9.20.1-svn1') || isFroxlorVersion('0.9.20.2-svn1')) { Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` ADD `gender` INT( 1 ) NOT NULL DEFAULT '0' AFTER `firstname`"); lastStepStatus(0); - updateToVersion('0.9.21-svn1'); + \Froxlor\Froxlor::updateToVersion('0.9.21-svn1'); } -if (isFroxlorVersion('0.9.21-svn1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.21-svn1')) { showUpdateStep("Updating from 0.9.21-svn1 to 0.9.21-svn2"); lastStepStatus(0); @@ -1680,16 +1746,16 @@ if (isFroxlorVersion('0.9.21-svn1')) { Database::query("INSERT INTO `" . TABLE_PANEL_SETTINGS . "` (`settinggroup`, `varname`, `value`) VALUES ('system', 'backup_ftp_passive', '1')"); lastStepStatus(0); - updateToVersion('0.9.21-svn2'); + \Froxlor\Froxlor::updateToVersion('0.9.21-svn2'); } -if (isFroxlorVersion('0.9.21-svn2')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.21-svn2')) { showUpdateStep("Updating from 0.9.21-svn2 to 0.9.21"); lastStepStatus(0); - updateToVersion('0.9.21'); + \Froxlor\Froxlor::updateToVersion('0.9.21'); } -if (isFroxlorVersion('0.9.21')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.21')) { showUpdateStep("Updating from 0.9.21 to 0.9.22-svn1"); lastStepStatus(0); @@ -1702,10 +1768,10 @@ if (isFroxlorVersion('0.9.21')) { Database::query("INSERT INTO `" . TABLE_PANEL_SETTINGS . "` (`settinggroup`, `varname`, `value`) VALUES ('system', 'diskquota_customer_partition', '/dev/root');"); lastStepStatus(0); - updateToVersion('0.9.22-svn1'); + \Froxlor\Froxlor::updateToVersion('0.9.22-svn1'); } -if (isFroxlorVersion('0.9.22-svn1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.22-svn1')) { showUpdateStep("Updating from 0.9.22-svn1 to 0.9.22-svn2"); lastStepStatus(0); @@ -1713,34 +1779,34 @@ if (isFroxlorVersion('0.9.22-svn1')) { /* fix backup_dir for #186 */ Database::query("UPDATE `" . TABLE_PANEL_SETTINGS . "` SET `value` = '/var/customers/backups/' WHERE `varname` = 'backup_dir';"); - updateToVersion('0.9.22-svn2'); + \Froxlor\Froxlor::updateToVersion('0.9.22-svn2'); } -if (isFroxlorVersion('0.9.22-svn2')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.22-svn2')) { showUpdateStep("Updating from 0.9.22-svn2 to 0.9.22-rc1"); lastStepStatus(0); - updateToVersion('0.9.22-rc1'); + \Froxlor\Froxlor::updateToVersion('0.9.22-rc1'); } -if (isFroxlorVersion('0.9.22-rc1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.22-rc1')) { showUpdateStep("Updating from 0.9.22-rc1 to 0.9.22"); lastStepStatus(0); - updateToVersion('0.9.22'); + \Froxlor\Froxlor::updateToVersion('0.9.22'); } -if (isFroxlorVersion('0.9.22')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.22')) { showUpdateStep("Updating from 0.9.22 to 0.9.23-rc1"); lastStepStatus(0); - updateToVersion('0.9.23-rc1'); + \Froxlor\Froxlor::updateToVersion('0.9.23-rc1'); } -if (isFroxlorVersion('0.9.23-rc1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.23-rc1')) { showUpdateStep("Updating from 0.9.23-rc1 to 0.9.23"); lastStepStatus(0); - updateToVersion('0.9.23'); + \Froxlor\Froxlor::updateToVersion('0.9.23'); } -if (isFroxlorVersion('0.9.23')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.23')) { showUpdateStep("Updating from 0.9.23 to 0.9.24-svn1"); lastStepStatus(0); @@ -1753,54 +1819,54 @@ if (isFroxlorVersion('0.9.23')) { Database::query("INSERT INTO `" . TABLE_PANEL_SETTINGS . "` (`settinggroup`, `varname`, `value`) VALUES ('system', 'logrotate_keep', '4');"); lastStepStatus(0); - updateToVersion('0.9.24-svn1'); + \Froxlor\Froxlor::updateToVersion('0.9.24-svn1'); } -if (isFroxlorVersion('0.9.24-svn1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.24-svn1')) { showUpdateStep("Updating from 0.9.24-svn1 to 0.9.24-rc1"); lastStepStatus(0); - updateToVersion('0.9.24-rc1'); + \Froxlor\Froxlor::updateToVersion('0.9.24-rc1'); } -if (isFroxlorVersion('0.9.24-rc1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.24-rc1')) { showUpdateStep("Updating from 0.9.24-rc1 to 0.9.24"); lastStepStatus(0); - updateToVersion('0.9.24'); + \Froxlor\Froxlor::updateToVersion('0.9.24'); } -if (isFroxlorVersion('0.9.24')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.24')) { showUpdateStep("Updating from 0.9.24 to 0.9.25-rc1"); lastStepStatus(0); - updateToVersion('0.9.25-rc1'); + \Froxlor\Froxlor::updateToVersion('0.9.25-rc1'); } -if (isFroxlorVersion('0.9.25-rc1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.25-rc1')) { showUpdateStep("Updating from 0.9.25-rc1 to 0.9.25"); lastStepStatus(0); - updateToVersion('0.9.25'); + \Froxlor\Froxlor::updateToVersion('0.9.25'); } -if (isFroxlorVersion('0.9.25')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.25')) { showUpdateStep("Updating from 0.9.25 to 0.9.26-svn1"); lastStepStatus(0); // enable bind by default Database::query("INSERT INTO `panel_settings` (`settinggroup`, `varname`, `value`) VALUES ('system', 'bind_enable', '1')"); - updateToVersion('0.9.26-svn1'); + \Froxlor\Froxlor::updateToVersion('0.9.26-svn1'); } -if (isFroxlorVersion('0.9.26-svn1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.26-svn1')) { showUpdateStep("Updating from 0.9.26-svn1 to 0.9.26-rc1"); lastStepStatus(0); - updateToVersion('0.9.26-rc1'); + \Froxlor\Froxlor::updateToVersion('0.9.26-rc1'); } -if (isFroxlorVersion('0.9.26-rc1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.26-rc1')) { showUpdateStep("Updating from 0.9.26-rc1 to 0.9.26"); lastStepStatus(0); - updateToVersion('0.9.26'); + \Froxlor\Froxlor::updateToVersion('0.9.26'); } -if (isFroxlorVersion('0.9.26')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.26')) { showUpdateStep("Updating from 0.9.26 to 0.9.27-svn1"); lastStepStatus(0); @@ -1827,15 +1893,16 @@ if (isFroxlorVersion('0.9.26')) { INSERT INTO `" . TABLE_PANEL_SETTINGS . "` SET `settinggroup` = 'system', `varname` = 'backup_ftp_enabled', - `value` = :value" - ); - Database::pexecute($stmt, array('value' => $state)); + `value` = :value"); + Database::pexecute($stmt, array( + 'value' => $state + )); } - updateToVersion('0.9.27-svn1'); + \Froxlor\Froxlor::updateToVersion('0.9.27-svn1'); } -if (isFroxlorVersion('0.9.27-svn1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.27-svn1')) { showUpdateStep("Updating from 0.9.27-svn1 to 0.9.27-svn2"); lastStepStatus(0); @@ -1856,22 +1923,22 @@ if (isFroxlorVersion('0.9.27-svn1')) { Database::query("INSERT INTO `panel_settings` (`settinggroup`, `varname`, `value`) VALUES ('phpfpm', 'idle_timeout', '30');"); } - updateToVersion('0.9.27-svn2'); + \Froxlor\Froxlor::updateToVersion('0.9.27-svn2'); } -if (isFroxlorVersion('0.9.27-svn2')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.27-svn2')) { showUpdateStep("Updating from 0.9.27-svn2 to 0.9.27-rc1"); lastStepStatus(0); - updateToVersion('0.9.27-rc1'); + \Froxlor\Froxlor::updateToVersion('0.9.27-rc1'); } -if (isFroxlorVersion('0.9.27-rc1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.27-rc1')) { showUpdateStep("Updating from 0.9.27-rc1 to 0.9.27"); lastStepStatus(0); - updateToVersion('0.9.27'); + \Froxlor\Froxlor::updateToVersion('0.9.27'); } -if (isFroxlorVersion('0.9.27')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.27')) { showUpdateStep("Updating from 0.9.27 to 0.9.28-svn1"); lastStepStatus(0); @@ -1884,10 +1951,10 @@ if (isFroxlorVersion('0.9.27')) { Database::query("INSERT INTO `panel_settings` (`settinggroup`, `varname`, `value`) VALUES ('phpfpm', 'aliasconfigdir', '/var/www/php-fpm/');"); } - updateToVersion('0.9.28-svn1'); + \Froxlor\Froxlor::updateToVersion('0.9.28-svn1'); } -if (isFroxlorVersion('0.9.28-svn1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.28-svn1')) { showUpdateStep("Updating from 0.9.28-svn1 to 0.9.28-svn2"); lastStepStatus(0); @@ -1951,14 +2018,14 @@ if (isFroxlorVersion('0.9.28-svn1')) { Database::query("UPDATE `panel_languages` SET `iso`='pl' WHERE `language` = 'Polski'"); break; default: - showUpdateStep("Sorry, but I don't know the ISO-639 language code for ".$language.". Please update the entry in `panel_languages` manually.\n"); + showUpdateStep("Sorry, but I don't know the ISO-639 language code for " . $language . ". Please update the entry in `panel_languages` manually.\n"); } } - updateToVersion('0.9.28-svn2'); + \Froxlor\Froxlor::updateToVersion('0.9.28-svn2'); } -if (isFroxlorVersion('0.9.28-svn2')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.28-svn2')) { showUpdateStep("Updating from 0.9.28-svn2 to 0.9.28-svn3"); lastStepStatus(0); @@ -1973,17 +2040,15 @@ if (isFroxlorVersion('0.9.28-svn2')) { Database::query("INSERT INTO `panel_settings` (`settinggroup`, `varname`, `value`) VALUES ('system', 'vmail_maildirname', 'Maildir');"); } - updateToVersion('0.9.28-svn3'); + \Froxlor\Froxlor::updateToVersion('0.9.28-svn3'); } -if (isFroxlorVersion('0.9.28-svn3')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.28-svn3')) { showUpdateStep("Updating from 0.9.28-svn3 to 0.9.28-svn4", true); lastStepStatus(0); - if (isset($_POST['classic_theme_replacement']) - && $_POST['classic_theme_replacement'] != '' - ) { + if (isset($_POST['classic_theme_replacement']) && $_POST['classic_theme_replacement'] != '') { $classic_theme_replacement = $_POST['classic_theme_replacement']; } else { $classic_theme_replacement = 'Froxlor'; @@ -1995,34 +2060,38 @@ if (isFroxlorVersion('0.9.28-svn3')) { $upd_stmt = Database::prepare(" UPDATE `" . TABLE_PANEL_SETTINGS . "` SET `value` = :theme - WHERE `varname` = 'default_theme';" - ); - Database::pexecute($upd_stmt, array('theme' => $classic_theme_replacement)); + WHERE `varname` = 'default_theme';"); + Database::pexecute($upd_stmt, array( + 'theme' => $classic_theme_replacement + )); } // Updating admin's theme setting $upd_stmt = Database::prepare(" UPDATE `" . TABLE_PANEL_ADMINS . "` SET `theme` = :theme - WHERE `theme` = 'Classic';" - ); - Database::pexecute($upd_stmt, array('theme' => $classic_theme_replacement)); + WHERE `theme` = 'Classic';"); + Database::pexecute($upd_stmt, array( + 'theme' => $classic_theme_replacement + )); // Updating customer's theme setting $upd_stmt = Database::prepare(" UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET `theme` = :theme - WHERE `theme` = 'Classic';" - ); - Database::pexecute($upd_stmt, array('theme' => $classic_theme_replacement)); + WHERE `theme` = 'Classic';"); + Database::pexecute($upd_stmt, array( + 'theme' => $classic_theme_replacement + )); // Updating theme setting of active sessions $upd_stmt = Database::prepare(" UPDATE `" . TABLE_PANEL_SESSIONS . "` SET `theme` = :theme - WHERE `theme` = 'Classic';" - ); - Database::pexecute($upd_stmt, array('theme' => $classic_theme_replacement)); + WHERE `theme` = 'Classic';"); + Database::pexecute($upd_stmt, array( + 'theme' => $classic_theme_replacement + )); lastStepStatus(0); @@ -2039,10 +2108,10 @@ if (isFroxlorVersion('0.9.28-svn3')) { lastStepStatus(0); - updateToVersion('0.9.28-svn4'); + \Froxlor\Froxlor::updateToVersion('0.9.28-svn4'); } -if (isFroxlorVersion('0.9.28-svn4')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.28-svn4')) { showUpdateStep("Updating from 0.9.28-svn4 to 0.9.28-svn5"); @@ -2051,24 +2120,25 @@ if (isFroxlorVersion('0.9.28-svn4')) { Database::query("INSERT INTO `panel_settings` (`settinggroup`, `varname`, `value`) VALUES ('catchall', 'catchall_enabled', '1');"); lastStepStatus(0); - updateToVersion('0.9.28-svn5'); + \Froxlor\Froxlor::updateToVersion('0.9.28-svn5'); } -if (isFroxlorVersion('0.9.28-svn5')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.28-svn5')) { showUpdateStep("Updating from 0.9.28-svn5 to 0.9.28-svn6", true); lastStepStatus(0); - $update_system_apache24 = isset($_POST['update_system_apache24']) ? (int)$_POST['update_system_apache24'] : '0'; + $update_system_apache24 = isset($_POST['update_system_apache24']) ? (int) $_POST['update_system_apache24'] : '0'; showUpdateStep('Setting value for apache-2.4 modification', true); // support for Apache-2.4 $stmt = Database::prepare(" INSERT INTO `" . TABLE_PANEL_SETTINGS . "` SET `settinggroup` = 'system', `varname` = 'apache24', - `value` = :value" - ); - Database::pexecute($stmt, array('value' => $update_system_apache24)); + `value` = :value"); + Database::pexecute($stmt, array( + 'value' => $update_system_apache24 + )); lastStepStatus(0); showUpdateStep("Inserting new tickets-see-all field to panel_admins", true); @@ -2079,9 +2149,10 @@ if (isFroxlorVersion('0.9.28-svn5')) { $stmt = Database::prepare(" UPDATE `" . TABLE_PANEL_ADMINS . "` SET `tickets_see_all` = '1' - WHERE `adminid` = :adminid" - ); - Database::pexecute($stmt, array('adminid' => $userinfo['adminid'])); + WHERE `adminid` = :adminid"); + Database::pexecute($stmt, array( + 'adminid' => $userinfo['adminid'] + )); lastStepStatus(0); showUpdateStep("Inserting new panel webfont-settings (default: off)", true); @@ -2092,75 +2163,78 @@ if (isFroxlorVersion('0.9.28-svn5')) { showUpdateStep("Inserting settings for nginx fastcgi-params file", true); $fastcgiparams = '/etc/nginx/fastcgi_params'; if (isset($_POST['nginx_fastcgi_params']) && $_POST['nginx_fastcgi_params'] != '') { - $fastcgiparams = makeCorrectFile($_POST['nginx_fastcgi_params']); + $fastcgiparams = \Froxlor\FileDir::makeCorrectFile($_POST['nginx_fastcgi_params']); } $stmt = Database::prepare(" INSERT INTO `" . TABLE_PANEL_SETTINGS . "` SET `settinggroup` = 'nginx', `varname` = 'fastcgiparams', - `value` = :value" - ); - Database::pexecute($stmt, array('value' => $fastcgiparams)); + `value` = :value"); + Database::pexecute($stmt, array( + 'value' => $fastcgiparams + )); lastStepStatus(0); - updateToVersion('0.9.28-svn6'); + \Froxlor\Froxlor::updateToVersion('0.9.28-svn6'); } -if (isFroxlorVersion('0.9.28-svn6')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.28-svn6')) { showUpdateStep("Updating from 0.9.28-svn6 to 0.9.28 release candidate 1"); lastStepStatus(0); - updateToVersion('0.9.28-rc1'); + \Froxlor\Froxlor::updateToVersion('0.9.28-rc1'); } -if (isFroxlorVersion('0.9.28-rc1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.28-rc1')) { showUpdateStep("Updating from 0.9.28-rc1 to 0.9.28-rc2", true); lastStepStatus(0); - $update_system_documentroot_use_default_value = isset($_POST['update_system_documentroot_use_default_value']) ? (int)$_POST['update_system_documentroot_use_default_value'] : '0'; + $update_system_documentroot_use_default_value = isset($_POST['update_system_documentroot_use_default_value']) ? (int) $_POST['update_system_documentroot_use_default_value'] : '0'; showUpdateStep("Adding new settings for using domain name as default value for DocumentRoot path", true); $stmt = Database::prepare(" INSERT INTO `" . TABLE_PANEL_SETTINGS . "` SET `settinggroup` = 'system', `varname` = 'documentroot_use_default_value', - `value` = :value" - ); - Database::pexecute($stmt, array('value' => $update_system_documentroot_use_default_value)); + `value` = :value"); + Database::pexecute($stmt, array( + 'value' => $update_system_documentroot_use_default_value + )); lastStepStatus(0); - updateToVersion('0.9.28-rc2'); + \Froxlor\Froxlor::updateToVersion('0.9.28-rc2'); } -if (isFroxlorVersion('0.9.28-rc2')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.28-rc2')) { showUpdateStep("Updating from 0.9.28-rc2 to 0.9.28 final", true); Database::query("DELETE FROM `panel_settings` WHERE `settinggroup`='system' AND `varname`='mod_log_sql'"); Database::query("DELETE FROM `panel_settings` WHERE `settinggroup`='system' AND `varname`='openssl_cnf'"); Database::query("ALTER TABLE `panel_domains` DROP `safemode`"); lastStepStatus(0); - updateToVersion('0.9.28'); + \Froxlor\Froxlor::updateToVersion('0.9.28'); } -if (isFroxlorVersion('0.9.28')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.28')) { showUpdateStep("Updating from 0.9.28 final to 0.9.28.1"); lastStepStatus(0); - updateToVersion('0.9.28.1'); + \Froxlor\Froxlor::updateToVersion('0.9.28.1'); } -if (isFroxlorVersion('0.9.28.1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.28.1')) { showUpdateStep("Updating from 0.9.28.1 to 0.9.29-dev1", true); lastStepStatus(0); - $hide_stdsubdomains = isset($_POST['hide_stdsubdomains']) ? (int)$_POST['hide_stdsubdomains'] : '0'; + $hide_stdsubdomains = isset($_POST['hide_stdsubdomains']) ? (int) $_POST['hide_stdsubdomains'] : '0'; showUpdateStep('Setting value for "hide standard subdomains"', true); $stmt = Database::prepare(" INSERT INTO `" . TABLE_PANEL_SETTINGS . "` SET `settinggroup` = 'panel', `varname` = 'phpconfigs_hidestdsubdomain', - `value` = :value" - ); - Database::pexecute($stmt, array('value' => $hide_stdsubdomains)); + `value` = :value"); + Database::pexecute($stmt, array( + 'value' => $hide_stdsubdomains + )); lastStepStatus(0); // don't advertise security questions - just set a default silently @@ -2169,39 +2243,45 @@ if (isFroxlorVersion('0.9.28.1')) { $fastcgiparams = Settings::Get('nginx.fastcgiparams'); // check the faulty value explicitly if ($fastcgiparams == '/etc/nginx/fastcgi_params/') { - $fastcgiparams = makeCorrectFile(substr($fastcgiparams,0,-1)); + $fastcgiparams = \Froxlor\FileDir::makeCorrectFile(substr($fastcgiparams, 0, - 1)); $stmt = Database::prepare(" UPDATE `" . TABLE_PANEL_SETTINGS . "` SET `value` = :value - WHERE `varname` = 'fastcgiparams'" - ); - Database::pexecute($stmt, array('value' => $fastcgiparams)); + WHERE `varname` = 'fastcgiparams'"); + Database::pexecute($stmt, array( + 'value' => $fastcgiparams + )); } - updateToVersion('0.9.29-dev1'); + \Froxlor\Froxlor::updateToVersion('0.9.29-dev1'); } -if (isFroxlorVersion('0.9.29-dev1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.29-dev1')) { showUpdateStep("Updating from 0.9.29-dev1 to 0.9.29-dev2", true); lastStepStatus(0); - $allow_themechange_c = isset($_POST['allow_themechange_c']) ? (int)$_POST['allow_themechange_c'] : '1'; - $allow_themechange_a = isset($_POST['allow_themechange_a']) ? (int)$_POST['allow_themechange_a'] : '1'; + $allow_themechange_c = isset($_POST['allow_themechange_c']) ? (int) $_POST['allow_themechange_c'] : '1'; + $allow_themechange_a = isset($_POST['allow_themechange_a']) ? (int) $_POST['allow_themechange_a'] : '1'; showUpdateStep("Inserting new setting to allow/disallow theme changes (default: on)", true); $stmt = Database::prepare(" INSERT INTO `" . TABLE_PANEL_SETTINGS . "` SET `settinggroup` = 'panel', `varname` = :varname, - `value` = :value" - ); - Database::pexecute($stmt, array('varname' => 'allow_theme_change_admin', 'value' => $allow_themechange_a)); - Database::pexecute($stmt, array('varname' => 'allow_theme_change_customer', 'value' => $allow_themechange_c)); + `value` = :value"); + Database::pexecute($stmt, array( + 'varname' => 'allow_theme_change_admin', + 'value' => $allow_themechange_a + )); + Database::pexecute($stmt, array( + 'varname' => 'allow_theme_change_customer', + 'value' => $allow_themechange_c + )); lastStepStatus(0); - updateToVersion('0.9.29-dev2'); + \Froxlor\Froxlor::updateToVersion('0.9.29-dev2'); } -if (isFroxlorVersion('0.9.29-dev2')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.29-dev2')) { showUpdateStep("Updating from 0.9.29-dev2 to 0.9.29-dev3", true); lastStepStatus(0); @@ -2222,15 +2302,16 @@ if (isFroxlorVersion('0.9.29-dev2')) { INSERT INTO `" . TABLE_PANEL_SETTINGS . "` SET `settinggroup` = 'system', `varname` = 'axfrservers', - `value` = :value" - ); - Database::pexecute($stmt, array('value' => $system_axfrservers)); + `value` = :value"); + Database::pexecute($stmt, array( + 'value' => $system_axfrservers + )); lastStepStatus(0); - updateToVersion('0.9.29-dev3'); + \Froxlor\Froxlor::updateToVersion('0.9.29-dev3'); } -if (isFroxlorVersion('0.9.29-dev3')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.29-dev3')) { showUpdateStep("Updating from 0.9.29-dev3 to 0.9.29-dev4", true); lastStepStatus(0); @@ -2247,7 +2328,7 @@ if (isFroxlorVersion('0.9.29-dev3')) { ) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci;"); lastStepStatus(0); - $system_customersslpath = isset($_POST['system_customersslpath']) ? makeCorrectDir($_POST['system_customersslpath']) : '/etc/ssl/froxlor-custom/'; + $system_customersslpath = isset($_POST['system_customersslpath']) ? \Froxlor\FileDir::makeCorrectDir($_POST['system_customersslpath']) : '/etc/ssl/froxlor-custom/'; if (trim($system_customersslpath) == '/') { // prevent users from specifying nonsense here $system_customersslpath = '/etc/ssl/froxlor-custom/'; @@ -2256,13 +2337,14 @@ if (isFroxlorVersion('0.9.29-dev3')) { INSERT INTO `" . TABLE_PANEL_SETTINGS . "` SET `settinggroup` = 'system', `varname` = 'customer_ssl_path', - `value` = :value" - ); - Database::pexecute($stmt, array('value' => $system_customersslpath)); - updateToVersion('0.9.29-dev4'); + `value` = :value"); + Database::pexecute($stmt, array( + 'value' => $system_customersslpath + )); + \Froxlor\Froxlor::updateToVersion('0.9.29-dev4'); } -if (isFroxlorVersion('0.9.29-dev4')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.29-dev4')) { showUpdateStep("Updating from 0.9.29-dev4 to 0.9.29-rc1", true); lastStepStatus(0); @@ -2277,31 +2359,36 @@ if (isFroxlorVersion('0.9.29-dev4')) { INSERT INTO `" . TABLE_PANEL_SETTINGS . "` SET `settinggroup` = 'phpfpm', `varname` = :varname, - `value` = :value" - ); + `value` = :value"); $dval = (Settings::Get('system.mod_fcgid_defaultini') !== null ? Settings::Get('system.mod_fcgid_defaultini') : '1'); - Database::pexecute($stmt, array('varname' => 'defaultini', 'value' => $dval)); + Database::pexecute($stmt, array( + 'varname' => 'defaultini', + 'value' => $dval + )); $dval = (Settings::Get('system.mod_fcgid_ownvhost') !== null ? Settings::Get('system.mod_fcgid_ownvhost') : '1'); - Database::pexecute($stmt, array('varname' => 'vhost_defaultini', 'value' => $dval)); + Database::pexecute($stmt, array( + 'varname' => 'vhost_defaultini', + 'value' => $dval + )); lastStepStatus(0); - updateToVersion('0.9.29-rc1'); + \Froxlor\Froxlor::updateToVersion('0.9.29-rc1'); } -if (isFroxlorVersion('0.9.29-rc1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.29-rc1')) { showUpdateStep("Updating from 0.9.29-rc1 to 0.9.29 final", true); lastStepStatus(0); - updateToVersion('0.9.29'); + \Froxlor\Froxlor::updateToVersion('0.9.29'); } -if (isFroxlorVersion('0.9.29')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.29')) { showUpdateStep("Updating from 0.9.29 to 0.9.29.1-dev1", true); lastStepStatus(0); showUpdateStep("Adding new ip to domain - mapping-table"); Database::query("DROP TABLE IF EXISTS `panel_domaintoip`;"); - $sql = "CREATE TABLE `".TABLE_DOMAINTOIP."` ( + $sql = "CREATE TABLE `" . TABLE_DOMAINTOIP . "` ( `id_domain` int(11) unsigned NOT NULL, `id_ipandports` int(11) unsigned NOT NULL, PRIMARY KEY (`id_domain`, `id_ipandports`) @@ -2314,54 +2401,49 @@ if (isFroxlorVersion('0.9.29')) { while ($row = $result->fetch(PDO::FETCH_ASSOC)) { - if ((int)$row['ipandport'] != 0) { - Database::query("INSERT INTO `".TABLE_DOMAINTOIP."` SET - `id_domain` = " . (int)$row['id'] . ", - `id_ipandports` = " . (int)$row['ipandport']); + if ((int) $row['ipandport'] != 0) { + Database::query("INSERT INTO `" . TABLE_DOMAINTOIP . "` SET + `id_domain` = " . (int) $row['id'] . ", + `id_ipandports` = " . (int) $row['ipandport']); } - if ((int)$row['ssl_ipandport'] != 0) { - Database::query("INSERT INTO `".TABLE_DOMAINTOIP."` SET - `id_domain` = " . (int)$row['id'] . ", - `id_ipandports` = " . (int)$row['ssl_ipandport']); - } - // Subdomains also have ssl ports if the parent has - elseif ((int)$row['ssl_ipandport'] == 0 - && (int)$row['ssl_redirect'] != 0 - && (int)$row['parentdomainid'] != 0 - ) { - Database::query("INSERT INTO `".TABLE_DOMAINTOIP."` SET - `id_domain` = " . (int)$row['id'] . ", + if ((int) $row['ssl_ipandport'] != 0) { + Database::query("INSERT INTO `" . TABLE_DOMAINTOIP . "` SET + `id_domain` = " . (int) $row['id'] . ", + `id_ipandports` = " . (int) $row['ssl_ipandport']); + } // Subdomains also have ssl ports if the parent has + elseif ((int) $row['ssl_ipandport'] == 0 && (int) $row['ssl_redirect'] != 0 && (int) $row['parentdomainid'] != 0) { + Database::query("INSERT INTO `" . TABLE_DOMAINTOIP . "` SET + `id_domain` = " . (int) $row['id'] . ", `id_ipandports` = ( SELECT `ssl_ipandport` FROM `" . TABLE_PANEL_DOMAINS . "` - WHERE `id` = '".(int)$row['parentdomainid']."');" - ); + WHERE `id` = '" . (int) $row['parentdomainid'] . "');"); } } lastStepStatus(0); showUpdateStep("Updating table layouts"); - Database::query("ALTER TABLE `".TABLE_PANEL_DOMAINS."` DROP `ipandport`;"); - Database::query("ALTER TABLE `".TABLE_PANEL_DOMAINS."` DROP `ssl`;"); - Database::query("ALTER TABLE `".TABLE_PANEL_DOMAINS."` DROP `ssl_ipandport`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` DROP `ipandport`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` DROP `ssl`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` DROP `ssl_ipandport`;"); lastStepStatus(0); - updateToVersion('0.9.29.1-dev1'); + \Froxlor\Froxlor::updateToVersion('0.9.29.1-dev1'); } -if (isFroxlorVersion('0.9.29.1-dev1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.29.1-dev1')) { showUpdateStep("Updating from 0.9.29.1-dev1 to 0.9.29.1-dev2", true); lastStepStatus(0); showUpdateStep("Updating table layouts and contents"); - Database::query("ALTER TABLE `".TABLE_MAIL_USERS."` ADD `mboxsize` bigint(30) NOT NULL default '0' AFTER `imap`;"); + Database::query("ALTER TABLE `" . TABLE_MAIL_USERS . "` ADD `mboxsize` bigint(30) NOT NULL default '0' AFTER `imap`;"); Database::query("INSERT INTO `cronjobs_run` SET `module` = 'froxlor/core', `cronfile` = 'cron_mailboxsize.php', `interval` = '6 HOUR', `isactive` = '1', `desc_lng_key` = 'cron_mailboxsize';"); lastStepStatus(0); - updateToVersion('0.9.29.1-dev2'); + \Froxlor\Froxlor::updateToVersion('0.9.29.1-dev2'); } -if (isFroxlorVersion('0.9.29.1-dev2')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.29.1-dev2')) { showUpdateStep("Updating from 0.9.29.1-dev2 to 0.9.29.1-dev3", true); lastStepStatus(0); @@ -2373,40 +2455,40 @@ if (isFroxlorVersion('0.9.29.1-dev2')) { Database::query("DELETE FROM `panel_settings` WHERE `varname` = 'logrotate_keep';"); lastStepStatus(0); - updateToVersion('0.9.29.1-dev3'); + \Froxlor\Froxlor::updateToVersion('0.9.29.1-dev3'); } -if (isFroxlorVersion('0.9.29.1-dev3')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.29.1-dev3')) { showUpdateStep("Updating from 0.9.29.1-dev3 to 0.9.29.1-dev4", true); lastStepStatus(0); // If you upgraded from SysCP the edit_billingdata field has been // removed in one of the first upgrades to froxlor. Sadly, one field - // remained in the install.sql so we remove it now if it exists - $bd_exists = Database::query("SHOW COLUMNS FROM `".TABLE_PANEL_ADMINS."` LIKE 'edit_billingdata';"); + // remained in the install.sql so we remove it now if it exists + $bd_exists = Database::query("SHOW COLUMNS FROM `" . TABLE_PANEL_ADMINS . "` LIKE 'edit_billingdata';"); if (Database::num_rows() > 0) { showUpdateStep("Removing old billing-field from admin-users"); - Database::query("ALTER TABLE `".TABLE_PANEL_ADMINS."` DROP `edit_billingdata`"); + Database::query("ALTER TABLE `" . TABLE_PANEL_ADMINS . "` DROP `edit_billingdata`"); lastStepStatus(0); } - updateToVersion('0.9.29.1-dev4'); + \Froxlor\Froxlor::updateToVersion('0.9.29.1-dev4'); } -if (isFroxlorVersion('0.9.29.1-dev4')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.29.1-dev4')) { showUpdateStep("Updating from 0.9.29.1-dev4 to 0.9.30-dev1", true); lastStepStatus(0); - updateToVersion('0.9.30-dev1'); + \Froxlor\Froxlor::updateToVersion('0.9.30-dev1'); } -if (isFroxlorVersion('0.9.30-dev1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.30-dev1')) { showUpdateStep("Updating from 0.9.30-dev1 to 0.9.30-rc1", true); lastStepStatus(0); - updateToVersion('0.9.30-rc1'); + \Froxlor\Froxlor::updateToVersion('0.9.30-rc1'); } -if (isFroxlorVersion('0.9.30-rc1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.30-rc1')) { showUpdateStep("Updating from 0.9.30-rc1 to 0.9.30 final", true); lastStepStatus(0); @@ -2415,10 +2497,10 @@ if (isFroxlorVersion('0.9.30-rc1')) { Database::query("INSERT INTO `panel_settings` SET `settinggroup` = 'system', `varname` = 'ssl_cipher_list', `value` = 'ECDHE-RSA-AES128-SHA256:AES128-GCM-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH'"); lastStepStatus(0); - updateToVersion('0.9.30'); + \Froxlor\Froxlor::updateToVersion('0.9.30'); } -if (isFroxlorVersion('0.9.30')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.30')) { showUpdateStep("Updating from 0.9.30 to 0.9.31-dev1", true); lastStepStatus(0); @@ -2428,17 +2510,17 @@ if (isFroxlorVersion('0.9.30')) { Database::query("DROP TABLE IF EXISTS `domain_docrootsettings`;"); lastStepStatus(0); - updateToVersion('0.9.31-dev1'); + \Froxlor\Froxlor::updateToVersion('0.9.31-dev1'); } -if (isFroxlorVersion('0.9.31-dev1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.31-dev1')) { showUpdateStep("Updating from 0.9.31-dev1 to 0.9.31-dev2", true); lastStepStatus(0); showUpdateStep("Adding new phpfpm-ipcdir setting"); $ins_stmt = Database::prepare(" - INSERT INTO `".TABLE_PANEL_SETTINGS."` SET `settinggroup` = 'phpfpm', `varname` = 'fastcgi_ipcdir', `value` = :value + INSERT INTO `" . TABLE_PANEL_SETTINGS . "` SET `settinggroup` = 'phpfpm', `varname` = 'fastcgi_ipcdir', `value` = :value "); $params = array(); // set default for apache (which will suite in most cases) @@ -2451,16 +2533,16 @@ if (isFroxlorVersion('0.9.31-dev1')) { Database::pexecute($ins_stmt, $params); lastStepStatus(0); - updateToVersion('0.9.31-dev2'); + \Froxlor\Froxlor::updateToVersion('0.9.31-dev2'); } -if (isFroxlorVersion('0.9.31-dev2')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.31-dev2')) { showUpdateStep("Updating from 0.9.31-dev2 to 0.9.31-dev3", true); lastStepStatus(0); - updateToVersion('0.9.31-dev3'); + \Froxlor\Froxlor::updateToVersion('0.9.31-dev3'); } -if (isFroxlorVersion('0.9.31-dev3')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.31-dev3')) { showUpdateStep("Updating from 0.9.31-dev3 to 0.9.31-dev4", true); lastStepStatus(0); @@ -2477,20 +2559,20 @@ if (isFroxlorVersion('0.9.31-dev3')) { Database::query($sql); lastStepStatus(0); - updateToVersion('0.9.31-dev4'); + \Froxlor\Froxlor::updateToVersion('0.9.31-dev4'); } -if (isFroxlorVersion('0.9.31-dev4')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.31-dev4')) { showUpdateStep("Updating from 0.9.31-dev4 to 0.9.31-dev5", true); lastStepStatus(0); - $update_error_report_admin = isset($_POST['update_error_report_admin']) ? (int)$_POST['update_error_report_admin'] : '1'; - $update_error_report_customer = isset($_POST['update_error_report_customer']) ? (int)$_POST['update_error_report_customer'] : '0'; + $update_error_report_admin = isset($_POST['update_error_report_admin']) ? (int) $_POST['update_error_report_admin'] : '1'; + $update_error_report_customer = isset($_POST['update_error_report_customer']) ? (int) $_POST['update_error_report_customer'] : '0'; showUpdateStep("Adding new error-reporting options"); $ins_stmt = Database::prepare(" - INSERT INTO `".TABLE_PANEL_SETTINGS."` SET `settinggroup` = 'system', `varname` = :varname, `value` = :value + INSERT INTO `" . TABLE_PANEL_SETTINGS . "` SET `settinggroup` = 'system', `varname` = :varname, `value` = :value "); $params = array(); // admins @@ -2504,45 +2586,47 @@ if (isFroxlorVersion('0.9.31-dev4')) { lastStepStatus(0); - updateToVersion('0.9.31-dev5'); + \Froxlor\Froxlor::updateToVersion('0.9.31-dev5'); } -if (isFroxlorVersion('0.9.31-dev5')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.31-dev5')) { showUpdateStep("Updating from 0.9.31-dev5 to 0.9.31-dev6", true); lastStepStatus(0); showUpdateStep("Adding new fpm-configuration options (slowlog)"); - Database::query("ALTER TABLE `".TABLE_PANEL_PHPCONFIGS."` ADD `fpm_slowlog` tinyint(1) NOT NULL default '0' AFTER `mod_fcgid_maxrequests`;"); - Database::query("ALTER TABLE `".TABLE_PANEL_PHPCONFIGS."` ADD `fpm_reqterm` varchar(15) NOT NULL default '60s' AFTER `fpm_slowlog`;"); - Database::query("ALTER TABLE `".TABLE_PANEL_PHPCONFIGS."` ADD `fpm_reqslow` varchar(15) NOT NULL default '5s' AFTER `fpm_reqterm`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_PHPCONFIGS . "` ADD `fpm_slowlog` tinyint(1) NOT NULL default '0' AFTER `mod_fcgid_maxrequests`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_PHPCONFIGS . "` ADD `fpm_reqterm` varchar(15) NOT NULL default '60s' AFTER `fpm_slowlog`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_PHPCONFIGS . "` ADD `fpm_reqslow` varchar(15) NOT NULL default '5s' AFTER `fpm_reqterm`;"); lastStepStatus(0); - updateToVersion('0.9.31-dev6'); + \Froxlor\Froxlor::updateToVersion('0.9.31-dev6'); } -if (isFroxlorVersion('0.9.31-dev6')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.31-dev6')) { showUpdateStep("Updating from 0.9.31-dev6 to 0.9.31-rc1"); lastStepStatus(0); - updateToVersion('0.9.31-rc1'); + \Froxlor\Froxlor::updateToVersion('0.9.31-rc1'); } -if (isFroxlorVersion('0.9.31-rc1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.31-rc1')) { showUpdateStep("Updating from 0.9.31-rc1 to 0.9.31-rc2"); lastStepStatus(0); - $update_admin_news_feed = isset($_POST['update_admin_news_feed']) ? (int)$_POST['update_admin_news_feed'] : '1'; + $update_admin_news_feed = isset($_POST['update_admin_news_feed']) ? (int) $_POST['update_admin_news_feed'] : '1'; showUpdateStep("Adding new news-feed option"); $ins_stmt = Database::prepare(" - INSERT INTO `".TABLE_PANEL_SETTINGS."` SET `settinggroup` = 'admin', `varname` = 'show_news_feed', `value` = :value + INSERT INTO `" . TABLE_PANEL_SETTINGS . "` SET `settinggroup` = 'admin', `varname` = 'show_news_feed', `value` = :value "); - Database::pexecute($ins_stmt, array('value' => $update_admin_news_feed)); + Database::pexecute($ins_stmt, array( + 'value' => $update_admin_news_feed + )); lastStepStatus(0); - updateToVersion('0.9.31-rc2'); + \Froxlor\Froxlor::updateToVersion('0.9.31-rc2'); } -if (isFroxlorVersion('0.9.31-rc2')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.31-rc2')) { showUpdateStep("Updating from 0.9.31-rc2 to 0.9.31-rc3"); lastStepStatus(0); @@ -2557,163 +2641,182 @@ if (isFroxlorVersion('0.9.31-rc2')) { // update default vhosts-config for froxlor if they are on the system-default if (Settings::Get('system.mod_fcgid_defaultini_ownvhost') == '1') { $upd_stmt = Database::prepare(" - UPDATE `".TABLE_PANEL_SETTINGS."` SET `value` = :value WHERE `settinggroup` = 'system' AND `varname` = 'mod_fcgid_defaultini_ownvhost' + UPDATE `" . TABLE_PANEL_SETTINGS . "` SET `value` = :value WHERE `settinggroup` = 'system' AND `varname` = 'mod_fcgid_defaultini_ownvhost' "); - Database::pexecute($upd_stmt, array('value' => $frxvhostconfid)); + Database::pexecute($upd_stmt, array( + 'value' => $frxvhostconfid + )); } if (Settings::Get('phpfpm.vhost_defaultini') == '1') { $upd_stmt = Database::prepare(" - UPDATE `".TABLE_PANEL_SETTINGS."` SET `value` = :value WHERE `settinggroup` = 'phpfpm' AND `varname` = 'vhost_defaultini' + UPDATE `" . TABLE_PANEL_SETTINGS . "` SET `value` = :value WHERE `settinggroup` = 'phpfpm' AND `varname` = 'vhost_defaultini' "); - Database::pexecute($upd_stmt, array('value' => $frxvhostconfid)); + Database::pexecute($upd_stmt, array( + 'value' => $frxvhostconfid + )); } lastStepStatus(0); - updateToVersion('0.9.31-rc3'); + \Froxlor\Froxlor::updateToVersion('0.9.31-rc3'); } -if (isFroxlorVersion('0.9.31-rc3')) { - showUpdateStep("Updating from 0.9.31-rc3 to 0.9.31 final", true); - lastStepStatus(0); - updateToVersion('0.9.31'); +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.31-rc3')) { + showUpdateStep("Updating from 0.9.31-rc3 to 0.9.31 final", true); + lastStepStatus(0); + \Froxlor\Froxlor::updateToVersion('0.9.31'); } -if (isFroxlorVersion('0.9.31')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.31')) { showUpdateStep("Updating from 0.9.31 to 0.9.31.1 final", true); lastStepStatus(0); - updateToVersion('0.9.31.1'); + \Froxlor\Froxlor::updateToVersion('0.9.31.1'); } -if (isFroxlorVersion('0.9.31.1')) { - showUpdateStep("Updating from 0.9.31.1 to 0.9.31.2 final", true); - lastStepStatus(0); - updateToVersion('0.9.31.2'); +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.31.1')) { + showUpdateStep("Updating from 0.9.31.1 to 0.9.31.2 final", true); + lastStepStatus(0); + \Froxlor\Froxlor::updateToVersion('0.9.31.2'); } -if (isFroxlorVersion('0.9.31.2')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.31.2')) { showUpdateStep("Updating from 0.9.31.2 to 0.9.32-dev1"); lastStepStatus(0); showUpdateStep("Removing APS-module (deprecated)"); - Database::query("DELETE FROM `".TABLE_PANEL_SETTINGS."` WHERE `settinggroup` = 'aps';"); - Database::query("ALTER TABLE `".TABLE_PANEL_ADMINS."` DROP `can_manage_aps_packages`;"); - Database::query("ALTER TABLE `".TABLE_PANEL_ADMINS."` DROP `aps_packages`;"); - Database::query("ALTER TABLE `".TABLE_PANEL_ADMINS."` DROP `aps_packages_used`;"); - Database::query("ALTER TABLE `".TABLE_PANEL_CUSTOMERS."` DROP `aps_packages`;"); - Database::query("ALTER TABLE `".TABLE_PANEL_CUSTOMERS."` DROP `aps_packages_used`;"); - Database::query("ALTER TABLE `".TABLE_PANEL_DATABASES."` DROP `apsdb`;"); + Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `settinggroup` = 'aps';"); + Database::query("ALTER TABLE `" . TABLE_PANEL_ADMINS . "` DROP `can_manage_aps_packages`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_ADMINS . "` DROP `aps_packages`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_ADMINS . "` DROP `aps_packages_used`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` DROP `aps_packages`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` DROP `aps_packages_used`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DATABASES . "` DROP `apsdb`;"); Database::query("DROP TABLE IF EXISTS `aps_packages`;"); Database::query("DROP TABLE IF EXISTS `aps_instances`;"); Database::query("DROP TABLE IF EXISTS `aps_settings`;"); Database::query("DROP TABLE IF EXISTS `aps_tasks`;"); Database::query("DROP TABLE IF EXISTS `aps_temp_settings`;"); - Database::query("DELETE FROM `".TABLE_PANEL_CRONRUNS."` WHERE `module` = 'froxlor/aps';"); + Database::query("DELETE FROM `" . TABLE_PANEL_CRONRUNS . "` WHERE `module` = 'froxlor/aps';"); lastStepStatus(0); showUpdateStep("Removing backup-module (deprecated)"); - Database::query("DELETE FROM `".TABLE_PANEL_SETTINGS."` WHERE `varname` = 'backup_enabled';"); - Database::query("DELETE FROM `".TABLE_PANEL_SETTINGS."` WHERE `varname` = 'backup_dir';"); - Database::query("DELETE FROM `".TABLE_PANEL_SETTINGS."` WHERE `varname` = 'backup_mysqldump_path';"); - Database::query("DELETE FROM `".TABLE_PANEL_SETTINGS."` WHERE `varname` = 'backup_count';"); - Database::query("DELETE FROM `".TABLE_PANEL_SETTINGS."` WHERE `varname` = 'backup_bigfile';"); - Database::query("DELETE FROM `".TABLE_PANEL_SETTINGS."` WHERE `varname` = 'backup_ftp_enabled';"); - Database::query("DELETE FROM `".TABLE_PANEL_SETTINGS."` WHERE `varname` = 'backup_ftp_server';"); - Database::query("DELETE FROM `".TABLE_PANEL_SETTINGS."` WHERE `varname` = 'backup_ftp_user';"); - Database::query("DELETE FROM `".TABLE_PANEL_SETTINGS."` WHERE `varname` = 'backup_ftp_pass';"); - Database::query("DELETE FROM `".TABLE_PANEL_SETTINGS."` WHERE `varname` = 'backup_ftp_passive';"); - Database::query("ALTER TABLE `".TABLE_PANEL_CUSTOMERS."` DROP `backup_allowed`;"); - Database::query("ALTER TABLE `".TABLE_PANEL_CUSTOMERS."` DROP `backup_enabled`;"); - Database::query("DELETE FROM `".TABLE_PANEL_CRONRUNS."` WHERE `module` = 'froxlor/backup';"); + Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `varname` = 'backup_enabled';"); + Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `varname` = 'backup_dir';"); + Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `varname` = 'backup_mysqldump_path';"); + Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `varname` = 'backup_count';"); + Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `varname` = 'backup_bigfile';"); + Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `varname` = 'backup_ftp_enabled';"); + Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `varname` = 'backup_ftp_server';"); + Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `varname` = 'backup_ftp_user';"); + Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `varname` = 'backup_ftp_pass';"); + Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `varname` = 'backup_ftp_passive';"); + Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` DROP `backup_allowed`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` DROP `backup_enabled`;"); + Database::query("DELETE FROM `" . TABLE_PANEL_CRONRUNS . "` WHERE `module` = 'froxlor/backup';"); lastStepStatus(0); showUpdateStep("Removing autoresponder-module (deprecated)"); - Database::query("DELETE FROM `".TABLE_PANEL_SETTINGS."` WHERE `settinggroup` = 'autoresponder';"); - Database::query("ALTER TABLE `".TABLE_PANEL_ADMINS."` DROP `email_autoresponder`;"); - Database::query("ALTER TABLE `".TABLE_PANEL_ADMINS."` DROP `email_autoresponder_used`;"); - Database::query("ALTER TABLE `".TABLE_PANEL_CUSTOMERS."` DROP `email_autoresponder`;"); - Database::query("ALTER TABLE `".TABLE_PANEL_CUSTOMERS."` DROP `email_autoresponder_used`;"); + Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `settinggroup` = 'autoresponder';"); + Database::query("ALTER TABLE `" . TABLE_PANEL_ADMINS . "` DROP `email_autoresponder`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_ADMINS . "` DROP `email_autoresponder_used`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` DROP `email_autoresponder`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` DROP `email_autoresponder_used`;"); Database::query("DROP TABLE IF EXISTS `mail_autoresponder`;"); lastStepStatus(0); showUpdateStep("Updating ftp-groups entries"); - Database::query("UPDATE `".TABLE_FTP_GROUPS."` SET `members` = CONCAT(`members`, ',".Settings::Get('system.httpuser')."');"); + Database::query("UPDATE `" . TABLE_FTP_GROUPS . "` SET `members` = CONCAT(`members`, '," . Settings::Get('system.httpuser') . "');"); lastStepStatus(0); - updateToVersion('0.9.32-dev1'); + \Froxlor\Froxlor::updateToVersion('0.9.32-dev1'); } -if (isFroxlorVersion('0.9.32-dev1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.32-dev1')) { showUpdateStep("Updating from 0.9.32-dev1 to 0.9.32-dev2"); lastStepStatus(0); showUpdateStep("Adding mailserver - settings for traffic analysis"); $ins_stmt = Database::prepare(" - INSERT INTO `".TABLE_PANEL_SETTINGS."` SET `settinggroup` = 'system', `varname` = :varname, `value` = :value + INSERT INTO `" . TABLE_PANEL_SETTINGS . "` SET `settinggroup` = 'system', `varname` = :varname, `value` = :value "); - Database::pexecute($ins_stmt, array('varname' => 'mailtraffic_enabled', 'value' => isset($_POST['mailtraffic_enabled']) ? (int)$_POST['mailtraffic_enabled'] : '1')); - Database::pexecute($ins_stmt, array('varname' => 'mdalog', 'value' => isset($_POST['mdalog']) ? $_POST['mdalog'] : '/var/log/mail.log')); - Database::pexecute($ins_stmt, array('varname' => 'mtalog', 'value' => isset($_POST['mtalog']) ? $_POST['mtalog'] : '/var/log/mail.log')); - Database::pexecute($ins_stmt, array('varname' => 'mdaserver', 'value' => isset($_POST['mdaserver']) ? $_POST['mdaserver'] : 'dovecot')); - Database::pexecute($ins_stmt, array('varname' => 'mtaserver', 'value' => isset($_POST['mtaserver']) ? $_POST['mtaserver'] : 'postfix')); + Database::pexecute($ins_stmt, array( + 'varname' => 'mailtraffic_enabled', + 'value' => isset($_POST['mailtraffic_enabled']) ? (int) $_POST['mailtraffic_enabled'] : '1' + )); + Database::pexecute($ins_stmt, array( + 'varname' => 'mdalog', + 'value' => isset($_POST['mdalog']) ? $_POST['mdalog'] : '/var/log/mail.log' + )); + Database::pexecute($ins_stmt, array( + 'varname' => 'mtalog', + 'value' => isset($_POST['mtalog']) ? $_POST['mtalog'] : '/var/log/mail.log' + )); + Database::pexecute($ins_stmt, array( + 'varname' => 'mdaserver', + 'value' => isset($_POST['mdaserver']) ? $_POST['mdaserver'] : 'dovecot' + )); + Database::pexecute($ins_stmt, array( + 'varname' => 'mtaserver', + 'value' => isset($_POST['mtaserver']) ? $_POST['mtaserver'] : 'postfix' + )); lastStepStatus(0); - updateToVersion('0.9.32-dev2'); + \Froxlor\Froxlor::updateToVersion('0.9.32-dev2'); } -if (isFroxlorVersion('0.9.32-dev2')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.32-dev2')) { showUpdateStep("Updating from 0.9.32-dev2 to 0.9.32-dev3"); lastStepStatus(0); showUpdateStep("Updating froxlor - theme"); - Database::query("UPDATE `".TABLE_PANEL_ADMINS."` SET `theme` = 'Sparkle_froxlor' WHERE `theme` = 'Froxlor';"); - Database::query("UPDATE `".TABLE_PANEL_CUSTOMERS."` SET `theme` = 'Sparkle_froxlor' WHERE `theme` = 'Froxlor';"); - Database::query("UPDATE `".TABLE_PANEL_SESSIONS."` SET `theme` = 'Sparkle_froxlor' WHERE `theme` = 'Froxlor';"); + Database::query("UPDATE `" . TABLE_PANEL_ADMINS . "` SET `theme` = 'Sparkle_froxlor' WHERE `theme` = 'Froxlor';"); + Database::query("UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET `theme` = 'Sparkle_froxlor' WHERE `theme` = 'Froxlor';"); + Database::query("UPDATE `" . TABLE_PANEL_SESSIONS . "` SET `theme` = 'Sparkle_froxlor' WHERE `theme` = 'Froxlor';"); if (Settings::Get('panel.default_theme') == 'Froxlor') { Settings::Set('panel.default_theme', 'Sparkle_froxlor'); } lastStepStatus(0); - updateToVersion('0.9.32-dev3'); + \Froxlor\Froxlor::updateToVersion('0.9.32-dev3'); } -if (isFroxlorVersion('0.9.32-dev3')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.32-dev3')) { showUpdateStep("Updating from 0.9.32-dev3 to 0.9.32-dev4"); lastStepStatus(0); showUpdateStep("Adding new FTP-description field"); - Database::query("ALTER TABLE `".TABLE_FTP_USERS."` ADD `description` varchar(255) NOT NULL DEFAULT '' AFTER `customerid`;"); + Database::query("ALTER TABLE `" . TABLE_FTP_USERS . "` ADD `description` varchar(255) NOT NULL DEFAULT '' AFTER `customerid`;"); lastStepStatus(0); - updateToVersion('0.9.32-dev4'); + \Froxlor\Froxlor::updateToVersion('0.9.32-dev4'); } -if (isFroxlorVersion('0.9.32-dev4')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.32-dev4')) { showUpdateStep("Updating from 0.9.32-dev4 to 0.9.32-dev5"); lastStepStatus(0); showUpdateStep("Updating cronjob table"); - Database::query("UPDATE `".TABLE_PANEL_CRONRUNS."` SET `cronfile` = REPLACE( REPLACE(`cronfile`, 'cron_', ''), '.php', '')"); + Database::query("UPDATE `" . TABLE_PANEL_CRONRUNS . "` SET `cronfile` = REPLACE( REPLACE(`cronfile`, 'cron_', ''), '.php', '')"); lastStepStatus(0); showUpdateStep("Adding new settings for cron"); // get user-chosen value $crondfile = isset($_POST['crondfile']) ? $_POST['crondfile'] : "/etc/cron.d/froxlor"; - $crondfile = makeCorrectFile($crondfile); + $crondfile = \Froxlor\FileDir::makeCorrectFile($crondfile); Settings::AddNew("system.cronconfig", $crondfile); // add task to generate cron.d-file - inserttask('99'); + \Froxlor\System\Cronjob::inserttask('99'); lastStepStatus(0); - updateToVersion('0.9.32-dev5'); + \Froxlor\Froxlor::updateToVersion('0.9.32-dev5'); } -if (isFroxlorVersion('0.9.32-dev5')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.32-dev5')) { showUpdateStep("Updating from 0.9.32-dev5 to 0.9.32-dev6", false); @@ -2722,29 +2825,29 @@ if (isFroxlorVersion('0.9.32-dev5')) { $crondreload = isset($_POST['crondreload']) ? $_POST['crondreload'] : "/etc/init.d/cron reload"; Settings::AddNew("system.crondreload", $crondreload); // add task to generate cron.d-file - inserttask('99'); + \Froxlor\System\Cronjob::inserttask('99'); lastStepStatus(0); - updateToVersion('0.9.32-dev6'); + \Froxlor\Froxlor::updateToVersion('0.9.32-dev6'); } -if (isFroxlorVersion('0.9.32-dev6')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.32-dev6')) { showUpdateStep("Updating from 0.9.32-dev6 to 0.9.32-rc1", false); showUpdateStep("Enhancing tasks-table"); - Database::query("ALTER TABLE `".TABLE_PANEL_TASKS."` MODIFY `data` text NOT NULL default ''"); + Database::query("ALTER TABLE `" . TABLE_PANEL_TASKS . "` MODIFY `data` text NOT NULL default ''"); lastStepStatus(0); - updateToVersion('0.9.32-rc1'); + \Froxlor\Froxlor::updateToVersion('0.9.32-rc1'); } -if (isFroxlorVersion('0.9.32-rc1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.32-rc1')) { showUpdateStep("Updating from 0.9.32-rc1 to 0.9.32-rc2", false); showUpdateStep("Removing autoresponder-cronjob (deprecated)"); - Database::query("DELETE FROM `".TABLE_PANEL_CRONRUNS."` WHERE `module` = 'froxlor/autoresponder';"); + Database::query("DELETE FROM `" . TABLE_PANEL_CRONRUNS . "` WHERE `module` = 'froxlor/autoresponder';"); lastStepStatus(0); showUpdateStep("Adding new settings for cron"); @@ -2752,20 +2855,20 @@ if (isFroxlorVersion('0.9.32-rc1')) { $croncmdline = isset($_POST['croncmdline']) ? $_POST['croncmdline'] : "/usr/bin/nice -n 5 /usr/bin/php5 -q"; Settings::AddNew("system.croncmdline", $croncmdline); // add task to generate cron.d-file - inserttask('99'); + \Froxlor\System\Cronjob::inserttask('99'); // silenty 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); showUpdateStep("Removing backup-module ftp-users (deprecated)"); - Database::query("DELETE FROM `".TABLE_FTP_USERS."` WHERE `username` LIKE '%_backup';"); + Database::query("DELETE FROM `" . TABLE_FTP_USERS . "` WHERE `username` LIKE '%_backup';"); lastStepStatus(0); - updateToVersion('0.9.32-rc2'); + \Froxlor\Froxlor::updateToVersion('0.9.32-rc2'); } -if (isFroxlorVersion('0.9.32-rc2')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.32-rc2')) { showUpdateStep("Updating from 0.9.32-rc2 to 0.9.32-rc3", false); showUpdateStep("Removing outdated languages"); @@ -2774,36 +2877,36 @@ if (isFroxlorVersion('0.9.32-rc2')) { Database::query("UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET `def_language` = 'English' WHERE `def_language` NOT REGEXP '(Dutch|English|Français|Deutsch|Italian|Português|Swedish)';"); lastStepStatus(0); - updateToVersion('0.9.32-rc3'); + \Froxlor\Froxlor::updateToVersion('0.9.32-rc3'); } -if (isFroxlorVersion('0.9.32-rc3')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.32-rc3')) { showUpdateStep("Updating from 0.9.32-rc3 to 0.9.32 final", false); - updateToVersion('0.9.32'); + \Froxlor\Froxlor::updateToVersion('0.9.32'); } -if (isFroxlorVersion('0.9.32')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.32')) { showUpdateStep("Updating from 0.9.32 to 0.9.33-dev1", false); showUpdateStep("Adding settings for custom newsfeed on customer-dashboard"); - Settings::AddNew("customer.show_news_feed", isset($_POST['customer_show_news_feed']) ? (int)$_POST['customer_show_news_feed'] : '0'); + Settings::AddNew("customer.show_news_feed", isset($_POST['customer_show_news_feed']) ? (int) $_POST['customer_show_news_feed'] : '0'); Settings::AddNew("customer.news_feed_url", isset($_POST['customer_news_feed_url']) ? $_POST['customer_news_feed_url'] : ''); lastStepStatus(0); - updateToVersion('0.9.33-dev1'); + \Froxlor\Froxlor::updateToVersion('0.9.33-dev1'); } -if (isFroxlorVersion('0.9.33-dev1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.33-dev1')) { showUpdateStep("Updating from 0.9.33-dev1 to 0.9.33-dev2", false); showUpdateStep("Adding settings for hostname-dns-entry"); - Settings::AddNew("system.dns_createhostnameentry", isset($_POST['dns_createhostnameentry']) ? (int)$_POST['dns_createhostnameentry'] : '0'); + Settings::AddNew("system.dns_createhostnameentry", isset($_POST['dns_createhostnameentry']) ? (int) $_POST['dns_createhostnameentry'] : '0'); lastStepStatus(0); - updateToVersion('0.9.33-dev2'); + \Froxlor\Froxlor::updateToVersion('0.9.33-dev2'); } -if (isFroxlorVersion('0.9.33-dev2')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.33-dev2')) { showUpdateStep("Updating from 0.9.33-dev2 to 0.9.33-dev3", false); showUpdateStep("Adding settings for password-generation options"); @@ -2818,291 +2921,300 @@ if (isFroxlorVersion('0.9.33-dev2')) { Settings::AddNew("phpfpm.use_mod_proxy", '0'); lastStepStatus(0); - updateToVersion('0.9.33-dev3'); + \Froxlor\Froxlor::updateToVersion('0.9.33-dev3'); } -if (isFroxlorVersion('0.9.33-dev3')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.33-dev3')) { showUpdateStep("Updating from 0.9.33-dev3 to 0.9.33-rc1", false); showUpdateStep("Updating database-scheme"); - Database::query("ALTER TABLE `".TABLE_PANEL_DOMAINS."` MODIFY `dkim_privkey` text"); - Database::query("ALTER TABLE `".TABLE_PANEL_DOMAINS."` MODIFY `dkim_pubkey` text"); - Database::query("ALTER TABLE `".TABLE_PANEL_DOMAINS."` MODIFY `specialsettings` text"); - Database::query("ALTER TABLE `".TABLE_PANEL_IPSANDPORTS."` MODIFY `specialsettings` text"); - Database::query("ALTER TABLE `".TABLE_PANEL_IPSANDPORTS."` MODIFY `default_vhostconf_domain` text"); - Database::query("ALTER TABLE `".TABLE_PANEL_DOMAIN_SSL_SETTINGS."` MODIFY `ssl_ca_file` text"); - Database::query("ALTER TABLE `".TABLE_PANEL_DOMAIN_SSL_SETTINGS."` MODIFY `ssl_cert_chainfile` text"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` MODIFY `dkim_privkey` text"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` MODIFY `dkim_pubkey` text"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` MODIFY `specialsettings` text"); + Database::query("ALTER TABLE `" . TABLE_PANEL_IPSANDPORTS . "` MODIFY `specialsettings` text"); + Database::query("ALTER TABLE `" . TABLE_PANEL_IPSANDPORTS . "` MODIFY `default_vhostconf_domain` text"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` MODIFY `ssl_ca_file` text"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` MODIFY `ssl_cert_chainfile` text"); lastStepStatus(0); showUpdateStep("Removing old settings"); - Database::query("DELETE FROM `".TABLE_PANEL_SETTINGS."` WHERE `settinggroup`='panel' AND `varname` = 'use_webfonts';"); - Database::query("DELETE FROM `".TABLE_PANEL_SETTINGS."` WHERE `settinggroup`='panel' AND `varname` = 'webfont';"); + Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `settinggroup`='panel' AND `varname` = 'use_webfonts';"); + Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `settinggroup`='panel' AND `varname` = 'webfont';"); lastStepStatus(0); showUpdateStep("Adding local froxlor group to customer groups"); - if ((int)Settings::Get('system.mod_fcgid_ownvhost') == 1 || (int)Settings::Get('phpfpm.enabled_ownvhost') == 1) { - if ((int)Settings::Get('system.mod_fcgid') == 1) { + if ((int) Settings::Get('system.mod_fcgid_ownvhost') == 1 || (int) Settings::Get('phpfpm.enabled_ownvhost') == 1) { + if ((int) Settings::Get('system.mod_fcgid') == 1) { $local_user = Settings::Get('system.mod_fcgid_httpuser'); } else { $local_user = Settings::Get('phpfpm.vhost_httpuser'); } - Database::query("UPDATE `".TABLE_FTP_GROUPS."` SET `members` = CONCAT(`members`, ',".$local_user."');"); + Database::query("UPDATE `" . TABLE_FTP_GROUPS . "` SET `members` = CONCAT(`members`, '," . $local_user . "');"); lastStepStatus(0); } else { lastStepStatus(1, "not needed"); } - updateToVersion('0.9.33-rc1'); + \Froxlor\Froxlor::updateToVersion('0.9.33-rc1'); } -if (isFroxlorVersion('0.9.33-rc1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.33-rc1')) { showUpdateStep("Updating from 0.9.33-rc1 to 0.9.33-rc2", false); showUpdateStep("Add new setting for sending cron-errors via mail"); - $sendcronerrors = isset($_POST['system_send_cron_errors']) ? (int)$_POST['system_send_cron_errors'] : "0"; + $sendcronerrors = isset($_POST['system_send_cron_errors']) ? (int) $_POST['system_send_cron_errors'] : "0"; Settings::addNew('system.send_cron_errors', $sendcronerrors); lastStepStatus(0); showUpdateStep("Add new custom-notes field for admins and customer"); - Database::query("ALTER TABLE `".TABLE_PANEL_ADMINS."` ADD `custom_notes` text AFTER `theme`"); - Database::query("ALTER TABLE `".TABLE_PANEL_ADMINS."` ADD `custom_notes_show` tinyint(1) NOT NULL default '0' AFTER `custom_notes`"); - Database::query("ALTER TABLE `".TABLE_PANEL_CUSTOMERS."` ADD `custom_notes` text AFTER `theme`"); - Database::query("ALTER TABLE `".TABLE_PANEL_CUSTOMERS."` ADD `custom_notes_show` tinyint(1) NOT NULL default '0' AFTER `custom_notes`"); + Database::query("ALTER TABLE `" . TABLE_PANEL_ADMINS . "` ADD `custom_notes` text AFTER `theme`"); + Database::query("ALTER TABLE `" . TABLE_PANEL_ADMINS . "` ADD `custom_notes_show` tinyint(1) NOT NULL default '0' AFTER `custom_notes`"); + Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` ADD `custom_notes` text AFTER `theme`"); + Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` ADD `custom_notes_show` tinyint(1) NOT NULL default '0' AFTER `custom_notes`"); lastStepStatus(0); // go from varchar(50) to varchar(255) because of some hashes that are longer than that showUpdateStep("Updating table structure of admins and customers"); - Database::query("ALTER TABLE `".TABLE_PANEL_ADMINS."` MODIFY `password` varchar(255) NOT NULL default ''"); - Database::query("ALTER TABLE `".TABLE_PANEL_CUSTOMERS."` MODIFY `password` varchar(255) NOT NULL default ''"); + Database::query("ALTER TABLE `" . TABLE_PANEL_ADMINS . "` MODIFY `password` varchar(255) NOT NULL default ''"); + Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` MODIFY `password` varchar(255) NOT NULL default ''"); lastStepStatus(0); - updateToVersion('0.9.33-rc2'); + \Froxlor\Froxlor::updateToVersion('0.9.33-rc2'); } -if (isFroxlorVersion('0.9.33-rc2')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.33-rc2')) { showUpdateStep("Updating from 0.9.33-rc2 to 0.9.33-rc3"); lastStepStatus(0); - updateToVersion('0.9.33-rc3'); - + \Froxlor\Froxlor::updateToVersion('0.9.33-rc3'); } -if (isFroxlorVersion('0.9.33-rc3')) { - - showUpdateStep("Updating from 0.9.33-rc3 to 0.9.33 final"); - lastStepStatus(0); - updateToVersion('0.9.33'); +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.33-rc3')) { + showUpdateStep("Updating from 0.9.33-rc3 to 0.9.33 final"); + lastStepStatus(0); + \Froxlor\Froxlor::updateToVersion('0.9.33'); } -if (isFroxlorVersion('0.9.33')) { - - showUpdateStep("Updating from 0.9.33 to 0.9.33.1"); - lastStepStatus(0); - updateToVersion('0.9.33.1'); +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.33')) { + showUpdateStep("Updating from 0.9.33 to 0.9.33.1"); + lastStepStatus(0); + \Froxlor\Froxlor::updateToVersion('0.9.33.1'); } -if (isFroxlorVersion('0.9.33.1')) { - - showUpdateStep("Updating from 0.9.33.1 to 0.9.33.2"); - lastStepStatus(0); - updateToVersion('0.9.33.2'); +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.33.1')) { + showUpdateStep("Updating from 0.9.33.1 to 0.9.33.2"); + lastStepStatus(0); + \Froxlor\Froxlor::updateToVersion('0.9.33.2'); } -if (isFroxlorVersion('0.9.33.2')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.33.2')) { - showUpdateStep("Updating from 0.9.33.2 to 0.9.34-dev1", false); + showUpdateStep("Updating from 0.9.33.2 to 0.9.34-dev1", false); - showUpdateStep("Updating table structure of domains"); - Database::query("ALTER TABLE `".TABLE_PANEL_DOMAINS."` MODIFY `parentdomainid` int(11) NOT NULL default '0'"); - lastStepStatus(0); + showUpdateStep("Updating table structure of domains"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` MODIFY `parentdomainid` int(11) NOT NULL default '0'"); + lastStepStatus(0); - showUpdateStep("Updating stored email-templates"); - $chk_stmt = Database::prepare("SELECT * FROM `".TABLE_PANEL_TEMPLATES."` WHERE `templategroup` = 'mails'"); - Database::pexecute($chk_stmt); - // do we have any? - if ($chk_stmt->rowCount() > 0) { - // prepare update-statement - $upd_stmt = Database::prepare("UPDATE `".TABLE_PANEL_TEMPLATES."` SET `language` = :lang WHERE `id` = :id"); - // get each row - while ($row = $chk_stmt->fetch()) { - // let htmlentities run over the language name and update the entry - Database::pexecute($upd_stmt, array('lang' => htmlentities($row['language'])), false); - } - lastStepStatus(0); - } else { - lastStepStatus(1, "not needed"); - } + showUpdateStep("Updating stored email-templates"); + $chk_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_TEMPLATES . "` WHERE `templategroup` = 'mails'"); + Database::pexecute($chk_stmt); + // do we have any? + if ($chk_stmt->rowCount() > 0) { + // prepare update-statement + $upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_TEMPLATES . "` SET `language` = :lang WHERE `id` = :id"); + // get each row + while ($row = $chk_stmt->fetch()) { + // let htmlentities run over the language name and update the entry + Database::pexecute($upd_stmt, array( + 'lang' => htmlentities($row['language']) + ), false); + } + lastStepStatus(0); + } else { + lastStepStatus(1, "not needed"); + } - showUpdateStep("Updating language descriptions to be in the native language"); - $upd_stmt = Database::prepare("UPDATE `".TABLE_PANEL_LANGUAGE."` SET `language` = :lang WHERE `iso` = :iso"); - Database::pexecute($upd_stmt, array('lang' => 'Français', 'iso' => 'fr'), false); - Database::pexecute($upd_stmt, array('lang' => 'Português', 'iso' => 'pt'), false); - Database::pexecute($upd_stmt, array('lang' => 'Italiano', 'iso' => 'it'), false); - Database::pexecute($upd_stmt, array('lang' => 'Nederlands', 'iso' => 'nl'), false); - Database::pexecute($upd_stmt, array('lang' => 'Svenska', 'iso' => 'sv'), false); - lastStepStatus(0); + showUpdateStep("Updating language descriptions to be in the native language"); + $upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_LANGUAGE . "` SET `language` = :lang WHERE `iso` = :iso"); + Database::pexecute($upd_stmt, array( + 'lang' => 'Français', + 'iso' => 'fr' + ), false); + Database::pexecute($upd_stmt, array( + 'lang' => 'Português', + 'iso' => 'pt' + ), false); + Database::pexecute($upd_stmt, array( + 'lang' => 'Italiano', + 'iso' => 'it' + ), false); + Database::pexecute($upd_stmt, array( + 'lang' => 'Nederlands', + 'iso' => 'nl' + ), false); + Database::pexecute($upd_stmt, array( + 'lang' => 'Svenska', + 'iso' => 'sv' + ), false); + lastStepStatus(0); - updateToVersion('0.9.34-dev1'); + \Froxlor\Froxlor::updateToVersion('0.9.34-dev1'); } -if (isFroxlorVersion('0.9.34-dev1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.34-dev1')) { - showUpdateStep("Updating from 0.9.34-dev1 to 0.9.34-dev2", false); + showUpdateStep("Updating from 0.9.34-dev1 to 0.9.34-dev2", false); - showUpdateStep("Adding new settings for apache-itk-mpm"); - Settings::AddNew("system.apacheitksupport", '0'); - lastStepStatus(0); + showUpdateStep("Adding new settings for apache-itk-mpm"); + Settings::AddNew("system.apacheitksupport", '0'); + lastStepStatus(0); - showUpdateStep("Increase text-field size of domain-ssl table"); - Database::query("ALTER TABLE `".TABLE_PANEL_DOMAIN_SSL_SETTINGS."` MODIFY `ssl_cert_file` mediumtext NOT NULL"); - Database::query("ALTER TABLE `".TABLE_PANEL_DOMAIN_SSL_SETTINGS."` MODIFY `ssl_key_file` mediumtext NOT NULL"); - Database::query("ALTER TABLE `".TABLE_PANEL_DOMAIN_SSL_SETTINGS."` MODIFY `ssl_ca_file` mediumtext NOT NULL"); - Database::query("ALTER TABLE `".TABLE_PANEL_DOMAIN_SSL_SETTINGS."` MODIFY `ssl_cert_chainfile` mediumtext NOT NULL"); - lastStepStatus(0); - - updateToVersion('0.9.34-dev2'); + showUpdateStep("Increase text-field size of domain-ssl table"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` MODIFY `ssl_cert_file` mediumtext NOT NULL"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` MODIFY `ssl_key_file` mediumtext NOT NULL"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` MODIFY `ssl_ca_file` mediumtext NOT NULL"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` MODIFY `ssl_cert_chainfile` mediumtext NOT NULL"); + lastStepStatus(0); + \Froxlor\Froxlor::updateToVersion('0.9.34-dev2'); } -if (isFroxlorVersion('0.9.34-dev2')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.34-dev2')) { - showUpdateStep("Updating from 0.9.34-dev2 to 0.9.34-dev3", false); + showUpdateStep("Updating from 0.9.34-dev2 to 0.9.34-dev3", false); - $do_update = true; - showUpdateStep("Checking for required PHP mbstring-extension"); - if (!extension_loaded('mbstring')) { - $do_update = false; - lastStepStatus(2, 'not installed'); - } else { - lastStepStatus(0); - } + $do_update = true; + showUpdateStep("Checking for required PHP mbstring-extension"); + if (! extension_loaded('mbstring')) { + $do_update = false; + lastStepStatus(2, 'not installed'); + } else { + lastStepStatus(0); + } - if ($do_update) { - updateToVersion('0.9.34-dev3'); - } + if ($do_update) { + \Froxlor\Froxlor::updateToVersion('0.9.34-dev3'); + } } +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.34-dev3')) { -if (isFroxlorVersion('0.9.34-dev3')) { + showUpdateStep("Updating from 0.9.34-dev3 to 0.9.34-dev4", false); - showUpdateStep("Updating from 0.9.34-dev3 to 0.9.34-dev4", false); + showUpdateStep("Adding field umask to phpconfig table"); + Database::query("ALTER TABLE `" . TABLE_PANEL_PHPCONFIGS . "` ADD `mod_fcgid_umask` varchar(15) NOT NULL DEFAULT '022' AFTER `mod_fcgid_maxrequests`"); + lastStepStatus(0); - showUpdateStep("Adding field umask to phpconfig table"); - Database::query("ALTER TABLE `".TABLE_PANEL_PHPCONFIGS."` ADD `mod_fcgid_umask` varchar(15) NOT NULL DEFAULT '022' AFTER `mod_fcgid_maxrequests`"); - lastStepStatus(0); - - updateToVersion('0.9.34-dev4'); + \Froxlor\Froxlor::updateToVersion('0.9.34-dev4'); } -if (isFroxlorVersion('0.9.34-dev4')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.34-dev4')) { - showUpdateStep("Updating from 0.9.34-dev4 to 0.9.34 final"); - lastStepStatus(0); + showUpdateStep("Updating from 0.9.34-dev4 to 0.9.34 final"); + lastStepStatus(0); - updateToVersion('0.9.34'); + \Froxlor\Froxlor::updateToVersion('0.9.34'); } -if (isFroxlorVersion('0.9.34')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.34')) { - showUpdateStep("Updating from 0.9.34 to 0.9.34.1"); - lastStepStatus(0); + showUpdateStep("Updating from 0.9.34 to 0.9.34.1"); + lastStepStatus(0); - updateToVersion('0.9.34.1'); + \Froxlor\Froxlor::updateToVersion('0.9.34.1'); } -if (isFroxlorVersion('0.9.34.1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.34.1')) { - showUpdateStep("Updating from 0.9.34.1 to 0.9.34.2"); - lastStepStatus(0); + showUpdateStep("Updating from 0.9.34.1 to 0.9.34.2"); + lastStepStatus(0); - updateToVersion('0.9.34.2'); + \Froxlor\Froxlor::updateToVersion('0.9.34.2'); } -if (isFroxlorVersion('0.9.34.2')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.34.2')) { - showUpdateStep("Updating from 0.9.34.2 to 0.9.35-dev1", false); + showUpdateStep("Updating from 0.9.34.2 to 0.9.35-dev1", false); - showUpdateStep("Adding Let's Encrypt - certificate fields"); - Database::query("ALTER TABLE `".TABLE_PANEL_DOMAIN_SSL_SETTINGS."` ADD `expirationdate` DATETIME NULL AFTER `ssl_cert_chainfile`;"); - Database::query("ALTER TABLE `".TABLE_PANEL_CUSTOMERS."` ADD `lepublickey` MEDIUMTEXT DEFAULT NULL AFTER `custom_notes_show`"); - Database::query("ALTER TABLE `".TABLE_PANEL_CUSTOMERS."` ADD `leprivatekey` MEDIUMTEXT DEFAULT NULL AFTER `lepublickey`;"); - Database::query("ALTER TABLE `".TABLE_PANEL_DOMAINS."` ADD `letsencrypt` TINYINT(1) NOT NULL DEFAULT '0' AFTER `ismainbutsubto`;"); - Settings::AddNew("system.leprivatekey", 'unset'); - Settings::AddNew("system.lepublickey", 'unset'); - showUpdateStep("Adding new cron-module for Let's encrypt"); - $stmt = Database::prepare(" + showUpdateStep("Adding Let's Encrypt - certificate fields"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` ADD `expirationdate` DATETIME NULL AFTER `ssl_cert_chainfile`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` ADD `lepublickey` MEDIUMTEXT DEFAULT NULL AFTER `custom_notes_show`"); + Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` ADD `leprivatekey` MEDIUMTEXT DEFAULT NULL AFTER `lepublickey`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `letsencrypt` TINYINT(1) NOT NULL DEFAULT '0' AFTER `ismainbutsubto`;"); + Settings::AddNew("system.leprivatekey", 'unset'); + Settings::AddNew("system.lepublickey", 'unset'); + showUpdateStep("Adding new cron-module for Let's encrypt"); + $stmt = Database::prepare(" INSERT INTO `" . TABLE_PANEL_CRONRUNS . "` SET `module` = 'froxlor/letsencrypt', `cronfile` = 'letsencrypt', `interval` = '5 MINUTE', `desc_lng_key` = 'cron_letsencrypt', `lastrun` = UNIX_TIMESTAMP(), - `isactive` = 0" - ); - Database::pexecute($stmt); - lastStepStatus(0); + `isactive` = 0"); + Database::pexecute($stmt); + lastStepStatus(0); - updateToVersion('0.9.35-dev1'); + \Froxlor\Froxlor::updateToVersion('0.9.35-dev1'); } -if (isFroxlorVersion('0.9.35-dev1')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.35-dev1')) { - showUpdateStep("Updating from 0.9.35-dev1 to 0.9.35-dev2", false); + showUpdateStep("Updating from 0.9.35-dev1 to 0.9.35-dev2", false); - showUpdateStep("Adding Let's Encrypt - settings"); - Settings::AddNew("system.letsencryptca", 'production'); - Settings::AddNew("system.letsencryptcountrycode", 'DE'); - Settings::AddNew("system.letsencryptstate", 'Germany'); - lastStepStatus(0); + showUpdateStep("Adding Let's Encrypt - settings"); + Settings::AddNew("system.letsencryptca", 'production'); + Settings::AddNew("system.letsencryptcountrycode", 'DE'); + Settings::AddNew("system.letsencryptstate", 'Germany'); + lastStepStatus(0); - updateToVersion('0.9.35-dev2'); + \Froxlor\Froxlor::updateToVersion('0.9.35-dev2'); } -if (isFroxlorVersion('0.9.35-dev2')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.35-dev2')) { - showUpdateStep("Updating from 0.9.35-dev2 to 0.9.35-dev3", false); + showUpdateStep("Updating from 0.9.35-dev2 to 0.9.35-dev3", false); - showUpdateStep("Adding new domain fields for Let's Encrypt"); - Database::query("ALTER TABLE `".TABLE_PANEL_DOMAINS."` ADD `termination_date` date NOT NULL AFTER `registration_date`"); - lastStepStatus(0); + showUpdateStep("Adding new domain fields for Let's Encrypt"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `termination_date` date NOT NULL AFTER `registration_date`"); + lastStepStatus(0); - updateToVersion('0.9.35-dev3'); + \Froxlor\Froxlor::updateToVersion('0.9.35-dev3'); } -if (isFroxlorVersion('0.9.35-dev3')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.35-dev3')) { - showUpdateStep("Updating from 0.9.35-dev3 to 0.9.35-dev4", false); + showUpdateStep("Updating from 0.9.35-dev3 to 0.9.35-dev4", false); // remove unused setting showUpdateStep("Removing unused setting "Send cron-errors to froxlor-admin via e-mail""); Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `settinggroup` = 'system' AND `varname` = 'send_cron_errors';"); lastStepStatus(0); - updateToVersion('0.9.35-dev4'); + \Froxlor\Froxlor::updateToVersion('0.9.35-dev4'); } +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.35-dev4')) { -if (isFroxlorVersion('0.9.35-dev4')) { - - showUpdateStep("Updating from 0.9.35-dev4 to 0.9.35-dev5", false); + showUpdateStep("Updating from 0.9.35-dev4 to 0.9.35-dev5", false); showUpdateStep("Adding more Let's Encrypt settings"); - Settings::AddNew("system.letsencryptchallengepath", FROXLOR_INSTALL_DIR); - Settings::AddNew("system.letsencryptkeysize", '4096'); - Settings::AddNew("system.letsencryptreuseold", 0); - Database::query("ALTER TABLE `".TABLE_PANEL_DOMAIN_SSL_SETTINGS."` ADD `ssl_csr_file` MEDIUMTEXT AFTER `ssl_cert_chainfile`;"); - Database::query("ALTER TABLE `".TABLE_PANEL_DOMAINS."` ADD `hsts` VARCHAR(10) NOT NULL DEFAULT '0' AFTER `letsencrypt`"); - Database::query("ALTER TABLE `".TABLE_PANEL_DOMAINS."` ADD `hsts_sub` TINYINT(1) NOT NULL DEFAULT '0' AFTER `hsts`"); - Database::query("ALTER TABLE `".TABLE_PANEL_DOMAINS."` ADD `hsts_preload` TINYINT(1) NOT NULL DEFAULT '1' AFTER `hsts_sub`"); + Settings::AddNew("system.letsencryptchallengepath", \Froxlor\Froxlor::getInstallDir()); + Settings::AddNew("system.letsencryptkeysize", '4096'); + Settings::AddNew("system.letsencryptreuseold", 0); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` ADD `ssl_csr_file` MEDIUMTEXT AFTER `ssl_cert_chainfile`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `hsts` VARCHAR(10) NOT NULL DEFAULT '0' AFTER `letsencrypt`"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `hsts_sub` TINYINT(1) NOT NULL DEFAULT '0' AFTER `hsts`"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `hsts_preload` TINYINT(1) NOT NULL DEFAULT '1' AFTER `hsts_sub`"); lastStepStatus(0); - updateToVersion('0.9.35-dev5'); + \Froxlor\Froxlor::updateToVersion('0.9.35-dev5'); } -if (isFroxlorVersion('0.9.35-dev5')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.35-dev5')) { showUpdateStep("Updating from 0.9.35-dev5 to 0.9.35-dev6", false); @@ -3118,14 +3230,14 @@ if (isFroxlorVersion('0.9.35-dev5')) { lastStepStatus(0); showUpdateStep("Adding new fields to panel_domains table"); - Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS ."` ADD `vhost_usedefaultlocation` tinyint(1) NOT NULL default '1' AFTER `ssl_redirect`;"); - Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS ."` ADD `vhostsettingid` tinyint(11) NOT NULL default '0' AFTER `vhost_usedefaultlocation`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `vhost_usedefaultlocation` tinyint(1) NOT NULL default '1' AFTER `ssl_redirect`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `vhostsettingid` tinyint(11) NOT NULL default '0' AFTER `vhost_usedefaultlocation`;"); lastStepStatus(0); - updateToVersion('0.9.35-dev6'); + \Froxlor\Froxlor::updateToVersion('0.9.35-dev6'); } -if (isFroxlorVersion('0.9.35-dev6')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.35-dev6')) { showUpdateStep("Updating from 0.9.35-dev6 to 0.9.35-dev7", false); @@ -3134,40 +3246,832 @@ if (isFroxlorVersion('0.9.35-dev6')) { Database::query("ALTER TABLE `panel_vhostconfigs` ADD `webserver` VARCHAR(255) NOT NULL DEFAULT '" . $webserver . "' AFTER `vhostsettings`;"); lastStepStatus(0); - updateToVersion('0.9.35-dev7'); + \Froxlor\Froxlor::updateToVersion('0.9.35-dev7'); } -if (isFroxlorVersion('0.9.35-dev7')) { +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.35-dev7')) { - showUpdateStep("Updating from 0.9.35-dev7 to 0.9.35-rc1"); - lastStepStatus(0); - - updateToVersion('0.9.35-rc1'); -} - -if (isFroxlorVersion('0.9.35-rc1') && isDatabaseVersion(null)) { - - Settings::AddNew("panel.db_version", "201603070"); - - showUpdateStep("Removing unused table and fields from database"); - Database::query("DROP TABLE IF EXISTS `panel_vhostconfigs`;"); - Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS ."` DROP `vhost_usedefaultlocation`;"); - Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS ."` DROP `vhostsettingid`;"); - lastStepStatus(0); - - showUpdateStep("Adding new setting to enable/disable Let's Encrypt"); - $enable_letsencrypt = isset($_POST['enable_letsencrypt']) ? (int)$_POST['enable_letsencrypt'] : "1"; - Settings::AddNew("system.leenabled", $enable_letsencrypt); - Database::query("UPDATE `".TABLE_PANEL_CRONRUNS."` SET `isactive` = '".$enable_letsencrypt."' WHERE `cronfile` = 'letsencrypt'"); - lastStepStatus(0); - -} - -if (isDatabaseVersion('201603070')) { - - showUpdateStep("Adding new php.ini directive to php-configurations: opcache.restrict_api"); - Database::query("UPDATE `" . TABLE_PANEL_PHPCONFIGS ."` SET `phpsettings` = CONCAT(`phpsettings`, '\r\nopcache.restrict_api = \"{DOCUMENT_ROOT}\"\r\n');"); + showUpdateStep("Updating from 0.9.35-dev7 to 0.9.35-rc1"); lastStepStatus(0); - updateToDbVersion('201603150'); + \Froxlor\Froxlor::updateToVersion('0.9.35-rc1'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.35-rc1') && \Froxlor\Froxlor::isDatabaseVersion(null)) { + + Settings::AddNew("panel.db_version", "201603070"); + + showUpdateStep("Removing unused table and fields from database"); + Database::query("DROP TABLE IF EXISTS `panel_vhostconfigs`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` DROP `vhost_usedefaultlocation`;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` DROP `vhostsettingid`;"); + lastStepStatus(0); + + showUpdateStep("Adding new setting to enable/disable Let's Encrypt"); + $enable_letsencrypt = isset($_POST['enable_letsencrypt']) ? (int) $_POST['enable_letsencrypt'] : "1"; + Settings::AddNew("system.leenabled", $enable_letsencrypt); + Database::query("UPDATE `" . TABLE_PANEL_CRONRUNS . "` SET `isactive` = '" . $enable_letsencrypt . "' WHERE `cronfile` = 'letsencrypt'"); + lastStepStatus(0); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201603070')) { + + showUpdateStep("Adding new php.ini directive to php-configurations: opcache.restrict_api"); + Database::query("UPDATE `" . TABLE_PANEL_PHPCONFIGS . "` SET `phpsettings` = CONCAT(`phpsettings`, '\r\nopcache.restrict_api = \"{DOCUMENT_ROOT}\"\r\n');"); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201603150'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.35-rc1')) { + + showUpdateStep("Updating from 0.9.35-rc1 to 0.9.35 final"); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToVersion('0.9.35'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.35')) { + + showUpdateStep("Updating from 0.9.35 to 0.9.35.1"); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToVersion('0.9.35.1'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.35.1') && \Froxlor\Froxlor::isDatabaseVersion('201603150')) { + + showUpdateStep("Adding new backup settings and cron"); + $enable_backup = isset($_POST['enable_backup']) ? (int) $_POST['enable_backup'] : "0"; + Settings::AddNew("system.backupenabled", $enable_backup); + $stmt = Database::prepare(" + INSERT INTO `" . TABLE_PANEL_CRONRUNS . "` SET + `module` = 'froxlor/backup', + `cronfile` = 'backup', + `interval` = '1 DAY', + `desc_lng_key` = 'cron_backup', + `lastrun` = 0, + `isactive` = :isactive"); + Database::pexecute($stmt, array( + 'isactive' => $enable_backup + )); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201604270'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.35.1')) { + + showUpdateStep("Updating from 0.9.35.1 to 0.9.36 final"); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToVersion('0.9.36'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201604270')) { + + showUpdateStep("Adding new dns related tables and settings"); + $enable_dns = isset($_POST['enable_dns']) ? (int) $_POST['enable_dns'] : "0"; + Settings::AddNew("system.dnsenabled", $enable_dns); + + Database::query("DROP TABLE IF EXISTS `domain_dns_entries`;"); + $sql = "CREATE TABLE `domain_dns_entries` ( + `id` int(20) NOT NULL auto_increment, + `domain_id` int(15) NOT NULL, + `record` varchar(255) NOT NULL, + `type` varchar(10) NOT NULL DEFAULT 'A', + `content` text NOT NULL, + `ttl` int(11) NOT NULL DEFAULT '18000', + `prio` int(11) DEFAULT NULL, + PRIMARY KEY (`id`) + ) DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;"; + Database::query($sql); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201605090'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201605090')) { + + showUpdateStep("Adjusting SPF record setting"); + $current_spf = Settings::Get('spf.spf_entry'); + // @ IN TXT "v=spf1 a mx -all" + $new_spf = substr($current_spf, strpos($current_spf, '"')); + Settings::Set('spf.spf_entry', $new_spf, true); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201605120'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201605120')) { + + showUpdateStep("Adding new dns-server setting"); + $new_dns_daemon = isset($_POST['new_dns_daemon']) ? $_POST['new_dns_daemon'] : "bind"; + Settings::AddNew("system.dns_server", $new_dns_daemon); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201605170'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201605170')) { + + showUpdateStep("Adding new dns-editor setting for customers"); + Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` ADD `dnsenabled` tinyint(1) NOT NULL default '0' AFTER `perlenabled`;"); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201605180'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201605180')) { + + showUpdateStep("Changing tables to be more mysql strict-mode compatible"); + Database::query("ALTER TABLE `" . TABLE_FTP_USERS . "` CHANGE `last_login` `last_login` DATETIME NULL DEFAULT NULL;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_IPSANDPORTS . "` CHANGE `specialsettings` `specialsettings` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_TASKS . "` CHANGE `data` `data` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL;"); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201606190'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201606190')) { + + showUpdateStep("Adding new setting for mod_php users to specify content of the global directory options file"); + Settings::AddNew("system.apacheglobaldiropt", ""); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201607140'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.36')) { + + showUpdateStep("Updating from 0.9.36 to 0.9.37-rc1", false); + \Froxlor\Froxlor::updateToVersion('0.9.37-rc1'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201607140')) { + + showUpdateStep("Adding new setting to hide certain options in customer panel"); + Settings::AddNew("panel.customer_hide_options", ""); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201607210'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.37-rc1')) { + + showUpdateStep("Updating from 0.9.37-rc1 to 0.9.37 final", false); + \Froxlor\Froxlor::updateToVersion('0.9.37'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201607210')) { + + showUpdateStep("Adding new settings for customer shell option"); + Settings::AddNew("system.allow_customer_shell", "0"); + Settings::AddNew("system.available_shells", ""); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201608260'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201608260')) { + + showUpdateStep("Adding new settings to use Let's Encrypt for froxlor"); + Settings::AddNew("system.le_froxlor_enabled", "0"); + Settings::AddNew("system.le_froxlor_redirect", "0"); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201609050'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201609050')) { + + showUpdateStep("Adding new settings for acme.conf (Let's Encrypt)"); + // get user-chosen value + $websrv_default = "/etc/apache2/conf-enabled/acme.conf"; + if (Settings::Get('system.webserver') == 'nginx') { + $websrv_default = "/etc/nginx/acme.conf"; + } + $acmeconffile = isset($_POST['acmeconffile']) ? $_POST['acmeconffile'] : $websrv_default; + $acmeconffile = \Froxlor\FileDir::makeCorrectFile($acmeconffile); + Settings::AddNew("system.letsencryptacmeconf", $acmeconffile); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201609120'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201609120')) { + + showUpdateStep("Adding new SMTP settings for emails sent by froxlor"); + // get user-chosen value + $smtp_enable = isset($_POST['smtp_enable']) ? (int) $_POST['smtp_enable'] : 0; + $smtp_host = isset($_POST['smtp_host']) ? $_POST['smtp_host'] : "localhost"; + $smtp_port = isset($_POST['smtp_port']) ? (int) $_POST['smtp_port'] : 25; + $smtp_usetls = isset($_POST['smtp_usetls']) ? (int) $_POST['smtp_usetls'] : 1; + $smtp_useauth = isset($_POST['smtp_auth']) ? (int) $_POST['smtp_auth'] : 1; + $smtp_user = isset($_POST['smtp_user']) ? $_POST['smtp_user'] : ""; + $smtp_passwd = isset($_POST['smtp_passwd']) ? $_POST['smtp_passwd'] : ""; + + Settings::AddNew("system.mail_use_smtp", $smtp_enable); + Settings::AddNew("system.mail_smtp_host", $smtp_host); + Settings::AddNew("system.mail_smtp_port", $smtp_port); + Settings::AddNew("system.mail_smtp_usetls", $smtp_usetls); + Settings::AddNew("system.mail_smtp_auth", $smtp_useauth); + Settings::AddNew("system.mail_smtp_user", $smtp_user); + Settings::AddNew("system.mail_smtp_passwd", $smtp_passwd); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201609200'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201609200')) { + + showUpdateStep("Changing tables to be more mysql strict-mode compatible"); + Database::query("ALTER TABLE `" . TABLE_MAIL_VIRTUAL . "` CHANGE `destination` `destination` TEXT NOT NULL DEFAULT '';"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` CHANGE `registration_date` `registration_date` DATE NULL DEFAULT NULL;"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` CHANGE `termination_date` `termination_date` DATE NULL DEFAULT NULL;"); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201609240'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201609240')) { + + showUpdateStep("Add HSTS settings for froxlor-vhost"); + Settings::AddNew("system.hsts_maxage", 0); + Settings::AddNew("system.hsts_incsub", 0); + Settings::AddNew("system.hsts_preload", 0); + lastStepStatus(0); + + showUpdateStep("Settings HSTS default values for all domains (deactivated)"); + Database::query("UPDATE `" . TABLE_PANEL_DOMAINS . "` SET `hsts_sub` = '0', `hsts_preload` = '0';"); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201610070'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.37')) { + + showUpdateStep("Updating from 0.9.37 to 0.9.38-rc1", false); + \Froxlor\Froxlor::updateToVersion('0.9.38-rc1'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.38-rc1')) { + + showUpdateStep("Updating from 0.9.38-rc1 to 0.9.38-rc2", false); + \Froxlor\Froxlor::updateToVersion('0.9.38-rc2'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.38-rc2')) { + + showUpdateStep("Updating from 0.9.38-rc2 to 0.9.38 final", false); + \Froxlor\Froxlor::updateToVersion('0.9.38'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201610070')) { + + showUpdateStep("Add Nginx http2 setting"); + Settings::AddNew("system.nginx_http2_support", 0); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201611180'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.38')) { + + showUpdateStep("Updating from 0.9.38 to 0.9.38.1", false); + \Froxlor\Froxlor::updateToVersion('0.9.38.1'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.38.1')) { + + showUpdateStep("Updating from 0.9.38.1 to 0.9.38.2", false); + \Froxlor\Froxlor::updateToVersion('0.9.38.2'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.38.2')) { + + showUpdateStep("Updating from 0.9.38.2 to 0.9.38.3", false); + \Froxlor\Froxlor::updateToVersion('0.9.38.3'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.38.3')) { + + showUpdateStep("Updating from 0.9.38.3 to 0.9.38.4", false); + \Froxlor\Froxlor::updateToVersion('0.9.38.4'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201611180')) { + + showUpdateStep("Updating database table definition for panel_domains"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `phpenabled` tinyint(1) NOT NULL default '1' AFTER `parentdomainid`;"); + lastStepStatus(0); + + showUpdateStep("Adding field for let's-encrypt registration status"); + Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` add `leregistered` TINYINT(1) NOT NULL DEFAULT 0;"); + lastStepStatus(0); + + showUpdateStep("Adding system setting for let's-encrypt registration status"); + Settings::AddNew('system.leregistered', '0'); + lastStepStatus(0); + + showUpdateStep("Adding unique key to ipsandports table"); + Database::query("ALTER TABLE `" . TABLE_PANEL_IPSANDPORTS . "` ADD UNIQUE KEY `ip_port` (`ip`,`port`)"); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201612110'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.38.4')) { + + showUpdateStep("Updating from 0.9.38.4 to 0.9.38.5", false); + \Froxlor\Froxlor::updateToVersion('0.9.38.5'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.38.5')) { + + showUpdateStep("Updating from 0.9.38.5 to 0.9.38.6", false); + \Froxlor\Froxlor::updateToVersion('0.9.38.6'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.38.6')) { + + showUpdateStep("Updating from 0.9.38.6 to 0.9.38.7", false); + \Froxlor\Froxlor::updateToVersion('0.9.38.7'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201612110')) { + + showUpdateStep("Adding field for OCSP stapling"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `ocsp_stapling` TINYINT(1) NOT NULL DEFAULT '0';"); + lastStepStatus(0); + + showUpdateStep("Adding default setting for Apache 2.4 OCSP cache path"); + Settings::AddNew('system.apache24_ocsp_cache_path', 'shmcb:/var/run/apache2/ocsp-stapling.cache(131072)'); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201704100'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201704100')) { + + showUpdateStep("Adding new setting for libnss-extrausers"); + $system_nssextrausers = isset($_POST['system_nssextrausers']) ? (int) $_POST['system_nssextrausers'] : 0; + Settings::AddNew('system.nssextrausers', $system_nssextrausers); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201705050'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201705050')) { + + showUpdateStep("Updating HTTP2 setting"); + if (Settings::Get('system.nginx_http2_support') != null) { + Database::query("UPDATE `" . TABLE_PANEL_SETTINGS . "` SET `varname` = 'http2_support' WHERE `varname` = 'nginx_http2_support';"); + } else { + Settings::AddNew('system.http2_support', 0); + } + lastStepStatus(0); + showUpdateStep("Adding domain field for HTTP2 stapling"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `http2` TINYINT(1) NOT NULL DEFAULT '0';"); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201708240'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201708240')) { + + showUpdateStep("Adding new 'disable LE self-check' setting"); + $system_disable_le_selfcheck = isset($_POST['system_disable_le_selfcheck']) ? (int) $_POST['system_disable_le_selfcheck'] : 0; + Settings::AddNew('system.disable_le_selfcheck', $system_disable_le_selfcheck); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201712310'); + + showUpdateStep("Updating from 0.9.38.7 to 0.9.38.8", false); + \Froxlor\Froxlor::updateToVersion('0.9.38.8'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201712310')) { + + showUpdateStep("Adding field for fpm-daemon configs"); + Database::query("ALTER TABLE `" . TABLE_PANEL_PHPCONFIGS . "` ADD `fpmsettingid` int(11) NOT NULL DEFAULT '1';"); + lastStepStatus(0); + + showUpdateStep("Adding new fpm-daemons table"); + Database::query("DROP TABLE IF EXISTS `panel_fpmdaemons`;"); + $sql = "CREATE TABLE `panel_fpmdaemons` ( + `id` int(11) unsigned NOT NULL auto_increment, + `description` varchar(50) NOT NULL, + `reload_cmd` varchar(255) NOT NULL, + `config_dir` varchar(255) NOT NULL, + `pm` varchar(15) NOT NULL DEFAULT 'static', + `max_children` int(4) NOT NULL DEFAULT '1', + `start_servers` int(4) NOT NULL DEFAULT '20', + `min_spare_servers` int(4) NOT NULL DEFAULT '5', + `max_spare_servers` int(4) NOT NULL DEFAULT '35', + `max_requests` int(4) NOT NULL DEFAULT '0', + `idle_timeout` int(4) NOT NULL DEFAULT '30', + PRIMARY KEY (`id`), + UNIQUE KEY `reload` (`reload_cmd`), + UNIQUE KEY `config` (`config_dir`) + ) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci;"; + Database::query($sql); + lastStepStatus(0); + + showUpdateStep("Converting php-fpm settings to new layout"); + $ins_stmt = Database::prepare(" + INSERT INTO `panel_fpmdaemons` SET + `id` = 1, + `description` = 'System default', + `reload_cmd` = :reloadcmd, + `config_dir` = :confdir, + `pm` = :pm, + `max_children` = :maxc, + `start_servers` = :starts, + `min_spare_servers` = :minss, + `max_spare_servers` = :maxss, + `max_requests` = :maxr, + `idle_timeout` = :it + "); + Database::pexecute($ins_stmt, array( + 'reloadcmd' => Settings::Get('phpfpm.reload'), + 'confdir' => Settings::Get('phpfpm.configdir'), + 'pm' => Settings::Get('phpfpm.pm'), + 'maxc' => Settings::Get('phpfpm.max_children'), + 'starts' => Settings::Get('phpfpm.start_servers'), + 'minss' => Settings::Get('phpfpm.min_spare_servers'), + 'maxss' => Settings::Get('phpfpm.max_spare_servers'), + 'maxr' => Settings::Get('phpfpm.max_requests'), + 'it' => Settings::Get('phpfpm.idle_timeout') + )); + lastStepStatus(0); + + showUpdateStep("Deleting unneeded settings"); + Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `settinggroup` = 'phpfpm' AND `varname` = 'reload'"); + Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `settinggroup` = 'phpfpm' AND `varname` = 'configdir'"); + Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `settinggroup` = 'phpfpm' AND `varname` = 'pm'"); + Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `settinggroup` = 'phpfpm' AND `varname` = 'max_children'"); + Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `settinggroup` = 'phpfpm' AND `varname` = 'start_servers'"); + Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `settinggroup` = 'phpfpm' AND `varname` = 'min_spare_servers'"); + Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `settinggroup` = 'phpfpm' AND `varname` = 'max_spare_servers'"); + Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `settinggroup` = 'phpfpm' AND `varname` = 'max_requests'"); + Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `settinggroup` = 'phpfpm' AND `varname` = 'idle_timeout'"); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201801070'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201801070')) { + + showUpdateStep("Adding field allowed_phpconfigs for customers"); + Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` ADD `allowed_phpconfigs` varchar(500) NOT NULL default '';"); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201801080'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201801080')) { + + showUpdateStep("Adding new setting for Let's Encrypt ACME version"); + Settings::AddNew('system.leapiversion', '1'); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201801090'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201801090')) { + + showUpdateStep("Adding field pass_authorizationheader for php-configs"); + Database::query("ALTER TABLE `" . TABLE_PANEL_PHPCONFIGS . "` ADD `pass_authorizationheader` tinyint(1) NOT NULL default '0';"); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201801091'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201801091')) { + + showUpdateStep("Adding new setting for SSL protocols"); + Settings::AddNew('system.ssl_protocols', 'TLSv1,TLSv1.2'); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201801100'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201801100')) { + + showUpdateStep("Adding field for security.limit_extensions fpm-setting"); + Database::query("ALTER TABLE `" . TABLE_PANEL_FPMDAEMONS . "` ADD `limit_extensions` varchar(255) NOT NULL default '.php';"); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201801101'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201801101')) { + + showUpdateStep("Adding dynamic php-fpm php.ini settings"); + Settings::AddNew('phpfpm.ini_flags', 'asp_tags +display_errors +display_startup_errors +html_errors +log_errors +magic_quotes_gpc +magic_quotes_runtime +magic_quotes_sybase +mail.add_x_header +session.cookie_secure +session.use_cookies +short_open_tag +track_errors +xmlrpc_errors +suhosin.simulation +suhosin.session.encrypt +suhosin.session.cryptua +suhosin.session.cryptdocroot +suhosin.cookie.encrypt +suhosin.cookie.cryptua +suhosin.cookie.cryptdocroot +suhosin.executor.disable_eval +mbstring.func_overload'); + Settings::AddNew('phpfpm.ini_values', 'auto_append_file +auto_prepend_file +date.timezone +default_charset +error_reporting +include_path +log_errors_max_len +mail.log +max_execution_time +session.cookie_domain +session.cookie_lifetime +session.cookie_path +session.name +session.serialize_handler +upload_max_filesize +xmlrpc_error_number +session.auto_start +always_populate_raw_post_data +suhosin.session.cryptkey +suhosin.session.cryptraddr +suhosin.session.checkraddr +suhosin.cookie.cryptkey +suhosin.cookie.plainlist +suhosin.cookie.cryptraddr +suhosin.cookie.checkraddr +suhosin.executor.func.blacklist +suhosin.executor.eval.whitelist'); + Settings::AddNew('phpfpm.ini_admin_flags', 'allow_call_time_pass_reference +allow_url_fopen +allow_url_include +auto_detect_line_endings +cgi.fix_pathinfo +cgi.force_redirect +enable_dl +expose_php +file_uploads +ignore_repeated_errors +ignore_repeated_source +log_errors +register_argc_argv +report_memleaks +opcache.enable +opcache.consistency_checks +opcache.dups_fix +opcache.load_comments +opcache.revalidate_path +opcache.save_comments +opcache.use_cwd +opcache.validate_timestamps +opcache.fast_shutdown'); + Settings::AddNew('phpfpm.ini_admin_values', 'cgi.redirect_status_env +date.timezone +disable_classes +disable_functions +error_log +gpc_order +max_input_time +max_input_vars +memory_limit +open_basedir +output_buffering +post_max_size +precision +sendmail_path +session.gc_divisor +session.gc_probability +variables_order +opcache.log_verbosity_level +opcache.restrict_api +opcache.revalidate_freq +opcache.max_accelerated_files +opcache.memory_consumption +opcache.interned_strings_buffer'); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201801110'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201801110')) { + + showUpdateStep("Adding php-fpm php PATH setting for envrironment"); + Settings::AddNew("phpfpm.envpath", '/usr/local/bin:/usr/bin:/bin'); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201801260'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.38.8')) { + + showUpdateStep("Updating from 0.9.38.8 to 0.9.39 final", false); + \Froxlor\Froxlor::updateToVersion('0.9.39'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.39')) { + + showUpdateStep("Updating from 0.9.39 to 0.9.39.1", false); + \Froxlor\Froxlor::updateToVersion('0.9.39.1'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.39.1')) { + + showUpdateStep("Updating from 0.9.39.1 to 0.9.39.2", false); + \Froxlor\Froxlor::updateToVersion('0.9.39.2'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201801260')) { + + showUpdateStep("Adding new plans table"); + Database::query("DROP TABLE IF EXISTS `panel_plans`;"); + $sql = "CREATE TABLE `panel_plans` ( + `id` int(11) NOT NULL auto_increment, + `adminid` int(11) NOT NULL default '0', + `name` varchar(255) NOT NULL default '', + `description` text NOT NULL, + `value` longtext NOT NULL, + `ts` int(15) NOT NULL default '0', + PRIMARY KEY (id), + KEY adminid (adminid) + ) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci;"; + Database::query($sql); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201802120'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201802120')) { + + showUpdateStep("Adding domain field for try_files flag"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `notryfiles` tinyint(1) DEFAULT '0';"); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201802130'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.39.2')) { + + showUpdateStep("Updating from 0.9.39.2 to 0.9.39.3", false); + \Froxlor\Froxlor::updateToVersion('0.9.39.3'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.39.3')) { + + showUpdateStep("Updating from 0.9.39.3 to 0.9.39.4", false); + \Froxlor\Froxlor::updateToVersion('0.9.39.4'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.39.4')) { + + showUpdateStep("Updating from 0.9.39.4 to 0.9.39.5", false); + \Froxlor\Froxlor::updateToVersion('0.9.39.5'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201802130')) { + + showUpdateStep("Adding fullchain field to ssl certificates"); + Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` ADD `ssl_fullchain_file` mediumtext AFTER `ssl_csr_file`;"); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201802250'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201802250')) { + + showUpdateStep("Adding webserver logfile settings"); + Settings::AddNew("system.logfiles_format", ''); + Settings::AddNew("system.logfiles_type", '1'); + Settings::AddNew("system.logfiles_piped", '0'); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201805240'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201805240')) { + + showUpdateStep("Adding webserver logfile-script settings"); + Settings::AddNew("system.logfiles_script", ''); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201805241'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201805241')) { + + $do_update = true; + showUpdateStep("Checking for required PHP json-extension"); + if (! extension_loaded('json')) { + $do_update = false; + lastStepStatus(2, 'not installed'); + } else { + lastStepStatus(0); + + showUpdateStep("Checking for current cronjobs that need converting"); + $result_tasks_stmt = Database::query(" + SELECT * FROM `" . TABLE_PANEL_TASKS . "` ORDER BY `id` ASC + "); + $upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_TASKS . "` SET `data` = :data WHERE `id` = :taskid"); + while ($row = $result_tasks_stmt->fetch(PDO::FETCH_ASSOC)) { + if (! empty($row['data'])) { + $data = unserialize($row['data']); + Database::pexecute($upd_stmt, array( + 'data' => json_encode($data), + 'taskid' => $row['id'] + )); + } + } + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201805290'); + } +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201805290')) { + + showUpdateStep("Adding leaccount field to panel customers"); + Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` ADD COLUMN `leaccount` varchar(255) default '' AFTER `leregistered`;"); + lastStepStatus(0); + + showUpdateStep("Adding system setting for let's-encrypt account"); + Settings::AddNew('system.leaccount', ""); + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201809180'); +} + +if (\Froxlor\Froxlor::isDatabaseVersion('201809180')) { + + showUpdateStep("Adding new fields for php configs"); + Database::query("ALTER TABLE `" . TABLE_PANEL_PHPCONFIGS . "` ADD `override_fpmconfig` tinyint(1) NOT NULL DEFAULT '0';"); + Database::query("ALTER TABLE `" . TABLE_PANEL_PHPCONFIGS . "` ADD `pm` varchar(15) NOT NULL DEFAULT 'static';"); + Database::query("ALTER TABLE `" . TABLE_PANEL_PHPCONFIGS . "` ADD `max_children` int(4) NOT NULL DEFAULT '1';"); + Database::query("ALTER TABLE `" . TABLE_PANEL_PHPCONFIGS . "` ADD `start_servers` int(4) NOT NULL DEFAULT '20';"); + Database::query("ALTER TABLE `" . TABLE_PANEL_PHPCONFIGS . "` ADD `min_spare_servers` int(4) NOT NULL DEFAULT '5';"); + Database::query("ALTER TABLE `" . TABLE_PANEL_PHPCONFIGS . "` ADD `max_spare_servers` int(4) NOT NULL DEFAULT '35';"); + Database::query("ALTER TABLE `" . TABLE_PANEL_PHPCONFIGS . "` ADD `max_requests` int(4) NOT NULL DEFAULT '0';"); + Database::query("ALTER TABLE `" . TABLE_PANEL_PHPCONFIGS . "` ADD `idle_timeout` int(4) NOT NULL DEFAULT '30';"); + Database::query("ALTER TABLE `" . TABLE_PANEL_PHPCONFIGS . "` ADD `limit_extensions` varchar(255) NOT NULL default '.php';"); + lastStepStatus(0); + + showUpdateStep("Synchronize fpm-daemon process manager settings with php-configs"); + // get all fpm-daemons + $sel_stmt = Database::prepare("SELECT * FROM `panel_fpmdaemons`;"); + Database::pexecute($sel_stmt); + $fpm_daemons = $sel_stmt->fetchAll(PDO::FETCH_ASSOC); + $upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_PHPCONFIGS . "` SET + `pm` = :pm, + `max_children` = :maxc, + `start_servers` = :starts, + `min_spare_servers` = :minss, + `max_spare_servers` = :maxss, + `max_requests` = :maxr, + `idle_timeout` = :it, + `limit_extensions` = :le + WHERE `fpmsettingid` = :fpmid + "); + // update all php-configs with the pm data from the fpm-daemon + foreach ($fpm_daemons as $fpm_daemon) { + Database::pexecute($upd_stmt, array( + 'pm' => $fpm_daemon['pm'], + 'maxc' => $fpm_daemon['max_children'], + 'starts' => $fpm_daemon['start_servers'], + 'minss' => $fpm_daemon['min_spare_servers'], + 'maxss' => $fpm_daemon['max_spare_servers'], + 'maxr' => $fpm_daemon['max_requests'], + 'it' => $fpm_daemon['idle_timeout'], + 'le' => $fpm_daemon['limit_extensions'], + 'fpmid' => $fpm_daemon['id'] + )); + } + lastStepStatus(0); + + \Froxlor\Froxlor::updateToDbVersion('201809280'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.39.5')) { + showUpdateStep("Updating from 0.9.39.5 to 0.9.40", false); + \Froxlor\Froxlor::updateToVersion('0.9.40'); +} + +if (\Froxlor\Froxlor::isFroxlorVersion('0.9.40')) { + + showUpdateStep("Updating from 0.9.40 to 0.9.40.1", false); + \Froxlor\Froxlor::updateToVersion('0.9.40.1'); } diff --git a/install/updates/froxlor/upgrade_syscp.inc.php b/install/updates/froxlor/upgrade_syscp.inc.php deleted file mode 100644 index 8dd28a94..00000000 --- a/install/updates/froxlor/upgrade_syscp.inc.php +++ /dev/null @@ -1,39 +0,0 @@ - (2010-) - * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt - * @package Install - * - */ - -if (!defined('AREA') - || (defined('AREA') && AREA != 'admin') - || !isset($userinfo['loginname']) - || (isset($userinfo['loginname']) && $userinfo['loginname'] == '') -) { - header('Location: ../../../index.php'); - exit; -} - -$updateto = '0.9-r0'; -$frontend = 'froxlor'; - -showUpdateStep("Upgrading SysCP ".Settings::Get('panel.version')." to Froxlor ". $updateto, false); -updateToVersion($updateto); - -// add field frontend -Database::query("INSERT INTO `" . TABLE_PANEL_SETTINGS . "` SET - `settinggroup` = 'panel', - `varname` = 'frontend', - `value` = 'froxlor'" -); -Settings::Set('panel.frontend', $frontend); diff --git a/install/updates/preconfig.php b/install/updates/preconfig.php index 89c28f3c..e0f601c5 100644 --- a/install/updates/preconfig.php +++ b/install/updates/preconfig.php @@ -31,14 +31,17 @@ function getPreConfig($current_version, $current_db_version) $has_preconfig = false; $return = '

PLEASE NOTE - Important update notifications

'; - include_once makeCorrectFile(dirname(__FILE__).'/preconfig/0.9/preconfig_0.9.inc.php'); + include_once \Froxlor\FileDir::makeCorrectFile(dirname(__FILE__) . '/preconfig/0.9/preconfig_0.9.inc.php'); parseAndOutputPreconfig($has_preconfig, $return, $current_version, $current_db_version); - $return .= '

'.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); + 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 .= ''; - if($has_preconfig) { + if ($has_preconfig) { return $return; } else { return ''; @@ -47,9 +50,9 @@ function getPreConfig($current_version, $current_db_version) function versionInUpdate($current_version, $version_to_check) { - if (!isFroxlor()) { + if (! \Froxlor\Froxlor::isFroxlor()) { return true; } - return (version_compare2($current_version, $version_to_check) == -1 ? true : false); + return (\Froxlor\Froxlor::versionCompare2($current_version, $version_to_check) == - 1 ? true : false); } 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 28613aba..122114c1 100644 --- a/install/updates/preconfig/0.9/preconfig_0.9.inc.php +++ b/install/updates/preconfig/0.9/preconfig_0.9.inc.php @@ -14,166 +14,154 @@ * @package Language * */ +use Froxlor\Database\Database; +use Froxlor\Settings; +use PHPMailer\PHPMailer; /** * 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 - * + * @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 parseAndOutputPreconfig(&$has_preconfig, &$return, $current_version, $current_db_version) { - +function parseAndOutputPreconfig(&$has_preconfig, &$return, $current_version, $current_db_version) +{ global $lng; - if(versionInUpdate($current_version, '0.9.4-svn2')) - { + if (versionInUpdate($current_version, '0.9.4-svn2')) { $has_preconfig = true; $description = 'Froxlor now enables the usage of a domain-wildcard entry and subdomains for this domain at the same time (subdomains are parsed before the main-domain vhost container).'; - $description.= 'This makes it possible to catch all non-existing subdomains with the main vhost but also have the ability to use subdomains for that domain.
'; - $description.= 'If you would like Froxlor to do so with your domains, the update script can set the correct values for existing domains for you. Note: future domains will have wildcard-entries enabled by default no matter how you decide here.'; + $description .= 'This makes it possible to catch all non-existing subdomains with the main vhost but also have the ability to use subdomains for that domain.
'; + $description .= 'If you would like Froxlor to do so with your domains, the update script can set the correct values for existing domains for you. Note: future domains will have wildcard-entries enabled by default no matter how you decide here.'; $question = 'Do you want to use wildcard-entries for existing domains?: '; - $question.= makeyesno('update_domainwildcardentry', '1', '0', '1'); + $question .= \Froxlor\UI\HTML::makeyesno('update_domainwildcardentry', '1', '0', '1'); - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } - if(versionInUpdate($current_version, '0.9.6-svn2')) - { - if(!PHPMailer::ValidateAddress(Settings::Get('panel.adminmail'))) - { + if (versionInUpdate($current_version, '0.9.6-svn2')) { + if (! PHPMailer::ValidateAddress(Settings::Get('panel.adminmail'))) { $has_preconfig = true; $description = 'Froxlor uses a newer version of the phpMailerClass and determined that your current admin-mail address is invalid.'; - $question = 'Please specify a new admin-email address: '; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + $question = 'Please specify a new admin-email address: '; + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } } - if(versionInUpdate($current_version, '0.9.6-svn3')) - { + if (versionInUpdate($current_version, '0.9.6-svn3')) { $has_preconfig = true; $description = 'You now have the possibility to define default error-documents for your webserver which replace the default webserver error-messages.'; $question = 'Do you want to enable default error-documents?: '; - $question .= makeyesno('update_deferr_enable', '1', '0', '0').'

'; - if(Settings::Get('system.webserver') == 'apache2') - { + $question .= \Froxlor\UI\HTML::makeyesno('update_deferr_enable', '1', '0', '0') . '

'; + if (Settings::Get('system.webserver') == 'apache2') { $question .= 'Path/URL for error 500: 

'; $question .= 'Path/URL for error 401: 

'; $question .= 'Path/URL for error 403: 

'; } $question .= 'Path/URL for error 404: '; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } - if(versionInUpdate($current_version, '0.9.6-svn4')) - { + if (versionInUpdate($current_version, '0.9.6-svn4')) { $has_preconfig = true; $description = 'You can define a default support-ticket priority level which is pre-selected for new support-tickets.'; $question = 'Which should be the default ticket-priority?: '; $question .= ''; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + $priorities = \Froxlor\UI\HTML::makeoption($lng['ticket']['high'], '1', '2'); + $priorities .= \Froxlor\UI\HTML::makeoption($lng['ticket']['normal'], '2', '2'); + $priorities .= \Froxlor\UI\HTML::makeoption($lng['ticket']['low'], '3', '2'); + $question .= $priorities . ''; + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } - if(versionInUpdate($current_version, '0.9.6-svn5')) - { + if (versionInUpdate($current_version, '0.9.6-svn5')) { $has_preconfig = true; $description = 'If you have more than one PHP configurations defined in Froxlor you can now set a default one which will be used for every domain.'; $question = 'Select default PHP configuration: '; $question .= ''; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + $question .= $configs . ''; + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } - if(versionInUpdate($current_version, '0.9.6-svn6')) - { + if (versionInUpdate($current_version, '0.9.6-svn6')) { $has_preconfig = true; $description = 'For the new FTP-quota feature, you can now chose the currently used ftpd-software.'; $question = 'Used FTPd-software: '; $question .= ''; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } - if(versionInUpdate($current_version, '0.9.7-svn1')) - { + if (versionInUpdate($current_version, '0.9.7-svn1')) { $has_preconfig = true; $description = 'You can now choose whether customers can select the http-redirect code and which of them acts as default.'; $question = 'Allow customer chosen redirects?: '; - $question.= makeyesno('update_customredirect_enable', '1', '0', '1').'

'; - $question.= 'Select default redirect code (default: empty): '; - $question.= ''; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + $question .= \Froxlor\UI\HTML::makeyesno('update_customredirect_enable', '1', '0', '1') . '

'; + $question .= 'Select default redirect code (default: empty): '; + $question .= ''; + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } - if(versionInUpdate($current_version, '0.9.7-svn2')) - { + if (versionInUpdate($current_version, '0.9.7-svn2')) { $result = Database::query("SELECT `domain` FROM " . TABLE_PANEL_DOMAINS . " WHERE `documentroot` LIKE '%:%' AND `documentroot` NOT LIKE 'http://%' AND `openbasedir_path` = '0' AND `openbasedir` = '1'"); $wrongOpenBasedirDomain = array(); - while($row = $result->fetch(PDO::FETCH_ASSOC)) { + while ($row = $result->fetch(PDO::FETCH_ASSOC)) { $wrongOpenBasedirDomain[] = $row['domain']; } - if(count($wrongOpenBasedirDomain) > 0) - { + if (count($wrongOpenBasedirDomain) > 0) { $has_preconfig = true; $description = 'Resetting the open_basedir to customer - root'; $question = 'Due to a security - issue regarding open_basedir, Froxlor will set the open_basedir for the following domains to the customers root instead of the chosen documentroot:
 '; - $question.= '
    '; - $idna_convert = new idna_convert_wrapper(); - foreach($wrongOpenBasedirDomain as $domain) - { - $question.= '
  • ' . $idna_convert->decode($domain) . '
  • '; + $question .= '
      '; + $idna_convert = new \Froxlor\Idna\IdnaWrapper(); + foreach ($wrongOpenBasedirDomain as $domain) { + $question .= '
    • ' . $idna_convert->decode($domain) . '
    • '; } - $question.= '
    '; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + $question .= '
'; + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } } - if(versionInUpdate($current_version, '0.9.9-svn1')) - { + if (versionInUpdate($current_version, '0.9.9-svn1')) { $has_preconfig = true; $description = 'When entering MX servers to Froxlor there was no mail-, imap-, pop3- and smtp-"A record" created. You can now chose whether this should be done or not.'; $question = 'Do you want these A-records to be created even with MX servers given?: '; - $question.= makeyesno('update_defdns_mailentry', '1', '0', '0'); - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + $question .= \Froxlor\UI\HTML::makeyesno('update_defdns_mailentry', '1', '0', '0'); + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } - if(versionInUpdate($current_version, '0.9.10-svn1')) - { + if (versionInUpdate($current_version, '0.9.10-svn1')) { $has_nouser = false; $has_nogroup = false; $result_stmt = Database::query("SELECT * FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `settinggroup` = 'system' AND `varname` = 'httpuser'"); $result = $result_stmt->fetch(PDO::FETCH_ASSOC); - if(!isset($result) || !isset($result['value'])) - { + if (! isset($result) || ! isset($result['value'])) { $has_preconfig = true; $has_nouser = true; $guessed_user = 'www-data'; - if(function_exists('posix_getuid') - && function_exists('posix_getpwuid') - ) { + if (function_exists('posix_getuid') && function_exists('posix_getpwuid')) { $_httpuser = posix_getpwuid(posix_getuid()); $guessed_user = $_httpuser['name']; } @@ -182,260 +170,228 @@ function parseAndOutputPreconfig(&$has_preconfig, &$return, $current_version, $c $result_stmt = Database::query("SELECT * FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `settinggroup` = 'system' AND `varname` = 'httpgroup'"); $result = $result_stmt->fetch(PDO::FETCH_ASSOC); - if(!isset($result) || !isset($result['value'])) - { + if (! isset($result) || ! isset($result['value'])) { $has_preconfig = true; $has_nogroup = true; $guessed_group = 'www-data'; - if(function_exists('posix_getgid') - && function_exists('posix_getgrgid') - ) { + if (function_exists('posix_getgid') && function_exists('posix_getgrgid')) { $_httpgroup = posix_getgrgid(posix_getgid()); $guessed_group = $_httpgroup['name']; } } - if($has_nouser || $has_nogroup) - { + if ($has_nouser || $has_nogroup) { $description = 'Please enter the correct username/groupname of the webserver on your system We\'re guessing the user but it might not be correct, so please check.'; - if($has_nouser) - { - $question = 'Please enter the webservers username: '; - } - elseif($has_nogroup) - { - $question2 = 'Please enter the webservers groupname: '; - if($has_nouser) { - $question .= '

'.$question2; + if ($has_nouser) { + $question = 'Please enter the webservers username: '; + } elseif ($has_nogroup) { + $question2 = 'Please enter the webservers groupname: '; + if ($has_nouser) { + $question .= '

' . $question2; } else { $question = $question2; } } - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } } - if(versionInUpdate($current_version, '0.9.10')) - { + if (versionInUpdate($current_version, '0.9.10')) { $has_preconfig = true; $description = 'you can now decide whether Froxlor should be reached via hostname/froxlor or directly via the hostname.'; $question = 'Do you want Froxlor to be reached directly via the hostname?: '; - $question.= makeyesno('update_directlyviahostname', '1', '0', '0'); - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + $question .= \Froxlor\UI\HTML::makeyesno('update_directlyviahostname', '1', '0', '0'); + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } - if(versionInUpdate($current_version, '0.9.11-svn1')) - { + if (versionInUpdate($current_version, '0.9.11-svn1')) { $has_preconfig = true; $description = 'It is possible to enhance security with setting a regular expression to force your customers to enter more complex passwords.'; $question = 'Enter a regular expression to force a higher password complexity (leave empty for none): '; - $question.= ''; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + $question .= ''; + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } - if(versionInUpdate($current_version, '0.9.11-svn3')) - { + if (versionInUpdate($current_version, '0.9.11-svn3')) { $has_preconfig = true; $description = 'As Froxlor can now handle perl, you have to specify where the perl executable is (only if you\'re running lighttpd, else just leave empty).'; $question = 'Path to perl (default \'/usr/bin/perl\'): '; - $question.= ''; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + $question .= ''; + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } - if(versionInUpdate($current_version, '0.9.12-svn1')) - { - if(Settings::Get('system.mod_fcgid') == 1) - { + if (versionInUpdate($current_version, '0.9.12-svn1')) { + if (Settings::Get('system.mod_fcgid') == 1) { $has_preconfig = true; $description = 'You can chose whether you want Froxlor to use FCGID itself too now.'; $question = 'Use FCGID for the Froxlor Panel?: '; - $question.= makeyesno('update_fcgid_ownvhost', '1', '0', '0').'

'; - $question.= 'If \'yes\', please specify local user/group (have to exist, Froxlor does not add them automatically):

'; - $question.= 'Local user: '; - $question.= '

'; - $question.= 'Local group: '; - $question.= '
'; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + $question .= \Froxlor\UI\HTML::makeyesno('update_fcgid_ownvhost', '1', '0', '0') . '

'; + $question .= 'If \'yes\', please specify local user/group (have to exist, Froxlor does not add them automatically):

'; + $question .= 'Local user: '; + $question .= '

'; + $question .= 'Local group: '; + $question .= '
'; + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } } - if(versionInUpdate($current_version, '0.9.12-svn2')) - { + if (versionInUpdate($current_version, '0.9.12-svn2')) { $has_preconfig = true; $description = 'Many apache user will have problems using perl/CGI as the customer docroots are not within the suexec path. Froxlor provides a simple workaround for that.'; $question = 'Enable Apache/SuExec/Perl workaround?: '; - $question.= makeyesno('update_perl_suexecworkaround', '1', '0', '0').'

'; - $question.= 'If \'yes\', please specify a path within the suexec path where Froxlor will create symlinks to customer perl-enabled paths:

'; - $question.= 'Path for symlinks (must be within suexec path): '; - $question.= '
'; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + $question .= \Froxlor\UI\HTML::makeyesno('update_perl_suexecworkaround', '1', '0', '0') . '

'; + $question .= 'If \'yes\', please specify a path within the suexec path where Froxlor will create symlinks to customer perl-enabled paths:

'; + $question .= 'Path for symlinks (must be within suexec path): '; + $question .= '
'; + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } - if(versionInUpdate($current_version, '0.9.12-svn4')) - { - if((int)Settings::Get('system.awstats_enabled') == 1) - { + if (versionInUpdate($current_version, '0.9.12-svn4')) { + if ((int) Settings::Get('system.awstats_enabled') == 1) { $has_preconfig = true; $description = 'Due to different paths of awstats_buildstaticpages.pl and awstats.pl you can set a different path for awstats.pl now.'; $question = 'Path to \'awstats.pl\'?: '; - $question.= '
'; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + $question .= '
'; + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } } - if(versionInUpdate($current_version, '0.9.13-svn1')) - { - if((int)Settings::Get('autoresponder.autoresponder_active') == 1) - { + if (versionInUpdate($current_version, '0.9.13-svn1')) { + if ((int) Settings::Get('autoresponder.autoresponder_active') == 1) { $has_preconfig = true; $description = 'Froxlor can now limit the number of autoresponder-entries for each user. Here you can set the value which will be available for each customer (Of course you can change the value for each customer separately after the update).'; $question = 'How many autoresponders should your customers be able to add?: '; - $question.= ' '.makecheckbox('update_autoresponder_default', $lng['customer']['unlimited'], '-1', false, 0, true, true).'
'; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + $question .= ' ' . \Froxlor\UI\HTML::makecheckbox('update_autoresponder_default', $lng['customer']['unlimited'], '-1', false, 0, true, true) . '
'; + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } } - if(versionInUpdate($current_version, '0.9.13.1')) - { - if((int)Settings::Get('system.mod_fcgid_ownvhost') == 1) - { + if (versionInUpdate($current_version, '0.9.13.1')) { + if ((int) Settings::Get('system.mod_fcgid_ownvhost') == 1) { $has_preconfig = true; $description = 'You have FCGID for Froxlor itself activated. You can now specify a PHP-configuration for this.'; $question = 'Select Froxlor-vhost PHP configuration: '; $question .= ''; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + $question .= $configs . ''; + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } } - if(versionInUpdate($current_version, '0.9.14-svn3')) - { - if((int)Settings::Get('system.awstats_enabled') == 1) - { + if (versionInUpdate($current_version, '0.9.14-svn3')) { + if ((int) Settings::Get('system.awstats_enabled') == 1) { $has_preconfig = true; $description = 'To have icons in AWStats statistic-pages please enter the path to AWStats icons folder.'; $question = 'Path to AWSTats icons folder: '; - $question.= ''; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + $question .= ''; + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } } - if(versionInUpdate($current_version, '0.9.14-svn4')) - { - if((int)Settings::Get('system.use_ssl') == 1) - { + if (versionInUpdate($current_version, '0.9.14-svn4')) { + if ((int) Settings::Get('system.use_ssl') == 1) { $has_preconfig = true; $description = 'Froxlor now has the possibility to set \'SSLCertificateChainFile\' for the apache webserver.'; $question = 'Enter filename (leave empty for none): '; - $question.= ''; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + $question .= ''; + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } } - if(versionInUpdate($current_version, '0.9.14-svn6')) - { + if (versionInUpdate($current_version, '0.9.14-svn6')) { $has_preconfig = true; $description = 'You can now allow customers to use any of their domains as username for the login.'; $question = 'Do you want to enable domain-login for all customers?: '; - $question.= makeyesno('update_allow_domain_login', '1', '0', '0'); - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + $question .= \Froxlor\UI\HTML::makeyesno('update_allow_domain_login', '1', '0', '0'); + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } - if(versionInUpdate($current_version, '0.9.14-svn10')) - { + if (versionInUpdate($current_version, '0.9.14-svn10')) { $has_preconfig = true; $description = 'This update removes the unsupported real-time option. Additionally the deprecated tables for navigation and cronscripts are removed, any modules using these tables need to be updated to the new structure!'; $question = ''; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } - if(versionInUpdate($current_version, '0.9.16-svn1')) - { + if (versionInUpdate($current_version, '0.9.16-svn1')) { $has_preconfig = true; $description = 'Froxlor now features support for php-fpm.'; $question = 'Do you want to enable php-fpm?: '; - $question.= makeyesno('update_phpfpm_enabled', '1', '0', '0').'

'; - $question.= 'If \'yes\', please specify the configuration directory: '; - $question.= '

'; - $question.= 'Please specify the temporary files directory: '; - $question.= '

'; - $question.= 'Please specify the PEAR directory: '; - $question.= '

'; - $question.= 'Please specify the php-fpm restart-command: '; - $question.= '

'; - $question.= 'Please specify the php-fpm rocess manager control: '; - $question.= '

'; - $question.= 'Please specify the number of child processes: '; - $question.= '

'; - $question.= 'Please specify the number of requests per child before respawning: '; - $question.= '

'; - $question.= 'The following settings are only required if you chose process manager = dynamic

'; - $question.= 'Please specify the number of child processes created on startup: '; - $question.= '

'; - $question.= 'Please specify the desired minimum number of idle server processes: '; - $question.= '

'; - $question.= 'Please specify the desired maximum number of idle server processes: '; - $question.= '
'; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + $question .= \Froxlor\UI\HTML::makeyesno('update_phpfpm_enabled', '1', '0', '0') . '

'; + $question .= 'If \'yes\', please specify the configuration directory: '; + $question .= '

'; + $question .= 'Please specify the temporary files directory: '; + $question .= '

'; + $question .= 'Please specify the PEAR directory: '; + $question .= '

'; + $question .= 'Please specify the php-fpm restart-command: '; + $question .= '

'; + $question .= 'Please specify the php-fpm rocess manager control: '; + $question .= '

'; + $question .= 'Please specify the number of child processes: '; + $question .= '

'; + $question .= 'Please specify the number of requests per child before respawning: '; + $question .= '

'; + $question .= 'The following settings are only required if you chose process manager = dynamic

'; + $question .= 'Please specify the number of child processes created on startup: '; + $question .= '

'; + $question .= 'Please specify the desired minimum number of idle server processes: '; + $question .= '

'; + $question .= 'Please specify the desired maximum number of idle server processes: '; + $question .= '
'; + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } - if(versionInUpdate($current_version, '0.9.16-svn2')) - { - if((int)Settings::Get('phpfpm.enabled') == 1) - { + if (versionInUpdate($current_version, '0.9.16-svn2')) { + if ((int) Settings::Get('phpfpm.enabled') == 1) { $has_preconfig = true; $description = 'You can chose whether you want Froxlor to use PHP-FPM itself too now.'; $question = 'Use PHP-FPM for the Froxlor Panel?: '; - $question.= makeyesno('update_phpfpm_enabled_ownvhost', '1', '0', '0').'

'; - $question.= 'If \'yes\', please specify local user/group (have to exist, Froxlor does not add them automatically):

'; - $question.= 'Local user: '; - $question.= '

'; - $question.= 'Local group: '; - $question.= '
'; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + $question .= \Froxlor\UI\HTML::makeyesno('update_phpfpm_enabled_ownvhost', '1', '0', '0') . '

'; + $question .= 'If \'yes\', please specify local user/group (have to exist, Froxlor does not add them automatically):

'; + $question .= 'Local user: '; + $question .= '

'; + $question .= 'Local group: '; + $question .= '
'; + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } } - if(versionInUpdate($current_version, '0.9.17-svn1')) - { + if (versionInUpdate($current_version, '0.9.17-svn1')) { $has_preconfig = true; $description = 'Select if you want to enable the web- and traffic-reports'; $question = 'Enable?: '; - $question.= makeyesno('update_system_report_enable', '1', '0', '1').'

'; - $question.= 'If \'yes\', please specify a percentage value for web- and traffic when reports are to be sent:

'; - $question.= 'Webusage warning level: '; - $question.= '

'; - $question.= 'Traffic warning level: '; - $question.= '
'; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + $question .= \Froxlor\UI\HTML::makeyesno('update_system_report_enable', '1', '0', '1') . '

'; + $question .= 'If \'yes\', please specify a percentage value for web- and traffic when reports are to be sent:

'; + $question .= 'Webusage warning level: '; + $question .= '

'; + $question .= 'Traffic warning level: '; + $question .= '
'; + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } - if(versionInUpdate($current_version, '0.9.18-svn2')) - { + if (versionInUpdate($current_version, '0.9.18-svn2')) { $has_preconfig = true; $description = 'As you can (obviously) see, Froxlor now comes with a new theme. You also have the possibility to switch back to "Classic" if you want to.'; $question = 'Select default panel theme: '; - $question.= ''; + $themes = \Froxlor\UI\Template::getThemes(); + foreach ($themes as $cur_theme) // $theme is already in use { - $question.= makeoption($cur_theme, $cur_theme, 'Froxlor'); + $question .= \Froxlor\UI\HTML::makeoption($cur_theme, $cur_theme, 'Froxlor'); } - $question.= ''; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + $question .= ''; + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } - if(versionInUpdate($current_version, '0.9.28-svn4')) - { + if (versionInUpdate($current_version, '0.9.28-svn4')) { $has_preconfig = true; $description = 'This version introduces a lot of profound changes:'; $description .= '
  • Improving the whole template system
  • Full UTF-8 support
  • Removing support for the former default theme \'Classic\'
'; @@ -444,15 +400,14 @@ function parseAndOutputPreconfig(&$has_preconfig, &$return, $current_version, $c $description .= 'test this update in a testing environment using your existing data.

'; $question = 'Select your preferred Classic Theme replacement: '; - $question.= ''; + $themes = \Froxlor\UI\Template::getThemes(); + foreach ($themes as $cur_theme) { + $question .= \Froxlor\UI\HTML::makeoption($cur_theme, $cur_theme, 'Froxlor'); } - $question.= ''; + $question .= ''; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } if (versionInUpdate($current_version, '0.9.28-svn6')) { @@ -460,17 +415,17 @@ 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.= '
LoadModule authz_core_module modules/mod_authz_core.so
+			$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?: '; - $question.= makeyesno('update_system_apache24', '1', '0', '0'); - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + $question .= \Froxlor\UI\HTML::makeyesno('update_system_apache24', '1', '0', '0'); + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } elseif (Settings::Get('system.webserver') == 'nginx') { $has_preconfig = true; $description = 'The path to nginx\'s fastcgi_params file is now customizable.

'; $question = 'Please enter full path to you nginx/fastcgi_params file (including filename): '; - $question.= ''; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + $question .= ''; + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } } @@ -478,25 +433,23 @@ function parseAndOutputPreconfig(&$has_preconfig, &$return, $current_version, $c $has_preconfig = true; - $description = 'This version adds an option to append the domain-name to the document-root for domains and subdomains.
'; + $description = 'This version adds an option to append the domain-name to the document-root for domains and subdomains.
'; $description .= 'You can enable or disable this feature anytime from settings -> system settings.
'; $question = 'Do you want to automatically append the domain-name to the documentroot of newly created domains?: '; - $question.= makeyesno('update_system_documentroot_use_default_value', '1', '0', '0'); + $question .= \Froxlor\UI\HTML::makeyesno('update_system_documentroot_use_default_value', '1', '0', '0'); - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } if (versionInUpdate($current_version, '0.9.28')) { $has_preconfig = true; // just an information about the new sendmail parameter (#1134) - $description = 'Froxlor changed the default parameter-set of sendmail (php.ini)
'; + $description = 'Froxlor changed the default parameter-set of sendmail (php.ini)
'; $description .= 'sendmail_path = "/usr/sbin/sendmail -t -i -f {CUSTOMER_EMAIL}"

'; $description .= 'If you don\'t have any problems with sending mails, you don\'t need to change this'; - if (Settings::Get('system.mod_fcgid') == '1' - || Settings::Get('phpfpm.enabled') == '1' - ) { + if (Settings::Get('system.mod_fcgid') == '1' || Settings::Get('phpfpm.enabled') == '1') { // information about removal of php's safe_mode $description .= '

The php safe_mode flag has been removed as current versions of PHP
'; $description .= 'do not support it anymore.

'; @@ -504,62 +457,58 @@ function parseAndOutputPreconfig(&$has_preconfig, &$return, $current_version, $c } $question = ''; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } if (versionInUpdate($current_version, '0.9.29-dev1')) { // we only need to ask if fcgid|php-fpm is enabled - if (Settings::Get('system.mod_fcgid') == '1' - || Settings::Get('phpfpm.enabled') == '1' - ) { + if (Settings::Get('system.mod_fcgid') == '1' || Settings::Get('phpfpm.enabled') == '1') { $has_preconfig = true; - $description = 'Standard-subdomains can now be hidden from the php-configuration overview.
'; + $description = 'Standard-subdomains can now be hidden from the php-configuration overview.
'; $question = 'Do you want to hide the standard-subdomains (this can be changed in the settings any time)?: '; - $question.= makeyesno('hide_stdsubdomains', '1', '0', '0'); - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + $question .= \Froxlor\UI\HTML::makeyesno('hide_stdsubdomains', '1', '0', '0'); + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } } if (versionInUpdate($current_version, '0.9.29-dev2')) { $has_preconfig = true; - $description = 'You can now decide whether admins/customers are able to change the theme
'; + $description = 'You can now decide whether admins/customers are able to change the theme
'; $question = 'If you want to disallow theme-changing, select "no" from the dropdowns: '; - $question.= "Admins: ". makeyesno('allow_themechange_a', '1', '0', '1').'  '; - $question.= "Customers: ".makeyesno('allow_themechange_c', '1', '0', '1'); - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + $question .= "Admins: " . \Froxlor\UI\HTML::makeyesno('allow_themechange_a', '1', '0', '1') . '  '; + $question .= "Customers: " . \Froxlor\UI\HTML::makeyesno('allow_themechange_c', '1', '0', '1'); + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } if (versionInUpdate($current_version, '0.9.29-dev3')) { $has_preconfig = true; - $description = 'There is now a possibility to specify AXFR servers for your bind zone-configuration
'; + $description = 'There is now a possibility to specify AXFR servers for your bind zone-configuration
'; $question = 'Enter a comma-separated list of AXFR servers or leave empty (default): '; - $question.= ''; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + $question .= ''; + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } if (versionInUpdate($current_version, '0.9.29-dev4')) { $has_preconfig = true; - $description = 'As customers can now specify ssl-certificate data for their domains, you need to specify where the generated files are stored
'; + $description = 'As customers can now specify ssl-certificate data for their domains, you need to specify where the generated files are stored
'; $question = 'Specify the directory for customer ssl-certificates: '; - $question.= ''; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + $question .= ''; + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } if (versionInUpdate($current_version, '0.9.29.1-dev3')) { $has_preconfig = true; - $description = 'The build in logrotation-feature has been removed. Please follow the configuration-instructions for your system to enable logrotating again.'; + $description = 'The build in logrotation-feature has been removed. Please follow the configuration-instructions for your system to enable logrotating again.'; $question = ''; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } // let the apache+fpm users know that they MUST change their config // for the domains / webserver to work after the update if (versionInUpdate($current_version, '0.9.30-dev1')) { - if (Settings::Get('system.webserver') == 'apache2' - && Settings::Get('phpfpm.enabled') == '1' - ) { + if (Settings::Get('system.webserver') == 'apache2' && Settings::Get('phpfpm.enabled') == '1') { $has_preconfig = true; - $description = 'The PHP-FPM implementation for apache2 has changed. Please look for the "fastcgi.conf" (Debian/Ubuntu) or "70_fastcgi.conf" (Gentoo) within /etc/apache2/ and change it as shown below:

'; + $description = 'The PHP-FPM implementation for apache2 has changed. Please look for the "fastcgi.conf" (Debian/Ubuntu) or "70_fastcgi.conf" (Gentoo) within /etc/apache2/ and change it as shown below:

'; $description .= '
<IfModule mod_fastcgi.c>
     FastCgiIpcDir /var/lib/apache2/fastcgi/
     <Location "/fastcgiphp">
@@ -570,142 +519,215 @@ function parseAndOutputPreconfig(&$has_preconfig, &$return, $current_version, $c
     </Location>
 </IfModule>
'; $question = ''; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } } if (versionInUpdate($current_version, '0.9.31-dev2')) { - if (Settings::Get('system.webserver') == 'apache2' - && Settings::Get('phpfpm.enabled') == '1' - ) { + if (Settings::Get('system.webserver') == 'apache2' && Settings::Get('phpfpm.enabled') == '1') { $has_preconfig = true; - $description = 'The FPM socket directory is now a setting in froxlor. Its default is /var/lib/apache2/fastcgi/.
If you are using /var/run/apache2 in the "fastcgi.conf" (Debian/Ubuntu) or "70_fastcgi.conf" (Gentoo) please correct this path accordingly
'; + $description = 'The FPM socket directory is now a setting in froxlor. Its default is /var/lib/apache2/fastcgi/.
If you are using /var/run/apache2 in the "fastcgi.conf" (Debian/Ubuntu) or "70_fastcgi.conf" (Gentoo) please correct this path accordingly
'; $question = ''; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } } if (versionInUpdate($current_version, '0.9.31-dev4')) { $has_preconfig = true; - $description = 'The template-variable {PASSWORD} has been replaced with {LINK}. Please update your password reset templates!
'; + $description = 'The template-variable {PASSWORD} has been replaced with {LINK}. Please update your password reset templates!
'; $question = ''; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } if (versionInUpdate($current_version, '0.9.31-dev5')) { $has_preconfig = true; - $description = 'You can enable/disable error-reporting for admins and customers!

'; + $description = 'You can enable/disable error-reporting for admins and customers!

'; $question = 'Do you want to enable error-reporting for admins? (default: yes): '; - $question.= makeyesno('update_error_report_admin', '1', '0', '1').'
'; - $question.= 'Do you want to enable error-reporting for customers? (default: no): '; - $question.= makeyesno('update_error_report_customer', '1', '0', '0'); - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + $question .= \Froxlor\UI\HTML::makeyesno('update_error_report_admin', '1', '0', '1') . '
'; + $question .= 'Do you want to enable error-reporting for customers? (default: no): '; + $question .= \Froxlor\UI\HTML::makeyesno('update_error_report_customer', '1', '0', '0'); + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } if (versionInUpdate($current_version, '0.9.31-rc2')) { $has_preconfig = true; - $description = 'You can enable/disable the display/usage of the news-feed for admins

'; + $description = 'You can enable/disable the display/usage of the news-feed for admins

'; $question = 'Do you want to enable the news-feed for admins? (default: yes): '; - $question.= makeyesno('update_admin_news_feed', '1', '0', '1').'
'; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + $question .= \Froxlor\UI\HTML::makeyesno('update_admin_news_feed', '1', '0', '1') . '
'; + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } if (versionInUpdate($current_version, '0.9.32-dev2')) { $has_preconfig = true; - $description = 'To enable logging of the mail-traffic, you need to set the following settings accordingly

'; + $description = 'To enable logging of the mail-traffic, you need to set the following settings accordingly

'; $question = 'Do you want to enable the traffic collection for mail? (default: yes): '; - $question.= makeyesno('mailtraffic_enabled', '1', '0', '1').'
'; - $question.= 'Mail Transfer Agent
'; - $question.= 'Type of your MTA: '; - $question.= '
'; - $question.= 'Logfile for your MTA: '; - $question.= '
'; - $question.= 'Mail Delivery Agent
'; - $question.= 'Type of your MDA: '; - $question.= '

'; - $question.= 'Logfile for your MDA: '; - $question.= '
'; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + $question .= \Froxlor\UI\HTML::makeyesno('mailtraffic_enabled', '1', '0', '1') . '
'; + $question .= 'Mail Transfer Agent
'; + $question .= 'Type of your MTA: '; + $question .= '
'; + $question .= 'Logfile for your MTA: '; + $question .= '
'; + $question .= 'Mail Delivery Agent
'; + $question .= 'Type of your MDA: '; + $question .= '

'; + $question .= 'Logfile for your MDA: '; + $question .= '
'; + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } if (versionInUpdate($current_version, '0.9.32-dev5')) { $has_preconfig = true; $description = 'Froxlor now generates a cron-configuration file for the cron-daemon. Please set a filename which will be included automatically by your crond (e.g. files in /etc/cron.d/)

'; $question = 'Path to the cron-service configuration-file. This file will be updated regularly and automatically by froxlor.
Note: please be sure to use the same filename as for the main froxlor cronjob (default: /etc/cron.d/froxlor)!
'; - $question.= '
'; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + $question .= '
'; + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } if (versionInUpdate($current_version, '0.9.32-dev6')) { $has_preconfig = true; $description = 'In order for the new cron.d file to work properly, we need to know about the cron-service reload command.

'; $question = 'Please specify the reload-command of your cron-daemon (default: /etc/init.d/cron reload)
'; - $question.= '
'; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + $question .= '
'; + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } 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.= '
'; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + $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") . "\";"); } if (versionInUpdate($current_version, '0.9.33-dev1')) { $has_preconfig = true; - $description = 'You can enable/disable the display/usage of the custom newsfeed for customers.

'; + $description = 'You can enable/disable the display/usage of the custom newsfeed for customers.

'; $question = 'Do you want to enable the custom newsfeed for customer? (default: no): '; - $question.= makeyesno('customer_show_news_feed', '1', '0', '0').'
'; - $question.= 'You have to set the URL for your RSS-feed here, if you have chosen to enable the custom newsfeed on the customer-dashboard: '; - $question.= '
'; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + $question .= \Froxlor\UI\HTML::makeyesno('customer_show_news_feed', '1', '0', '0') . '
'; + $question .= 'You have to set the URL for your RSS-feed here, if you have chosen to enable the custom newsfeed on the customer-dashboard: '; + $question .= '
'; + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } if (versionInUpdate($current_version, '0.9.33-dev2')) { // only if bind is used - if not the default will be set, which is '0' (off) if (Settings::get('system.bind_enable') == 1) { $has_preconfig = true; - $description = 'You can enable/disable the generation of the bind-zone / config for the system hostname.

'; + $description = 'You can enable/disable the generation of the bind-zone / config for the system hostname.

'; $question = 'Do you want to generate a bind-zone for the system-hostname? (default: no): '; - $question.= makeyesno('dns_createhostnameentry', '1', '0', '0').'
'; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + $question .= \Froxlor\UI\HTML::makeyesno('dns_createhostnameentry', '1', '0', '0') . '
'; + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } } if (versionInUpdate($current_version, '0.9.33-rc2')) { $has_preconfig = true; - $description = 'You can chose whether you want to receive an e-mail on cronjob errors. Keep in mind that this can lead to an e-mail being sent every 5 minutes.

'; + $description = 'You can chose whether you want to receive an e-mail on cronjob errors. Keep in mind that this can lead to an e-mail being sent every 5 minutes.

'; $question = 'Do you want to receive cron-errors via mail? (default: no): '; - $question.= makeyesno('system_send_cron_errors', '1', '0', '0').'
'; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + $question .= \Froxlor\UI\HTML::makeyesno('system_send_cron_errors', '1', '0', '0') . '
'; + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } if (versionInUpdate($current_version, '0.9.34-dev3')) { - $has_preconfig = true; - $description = 'Froxlor now requires the PHP mbstring-extension as we need to be multibyte-character safe in some cases'; - $question = 'PHP mbstring is currently: '; - if (!extension_loaded('mbstring')) { - $question .= 'not installed/loaded'; - $question .= '
Please install the PHP mbstring extension in order to finish the update'; - } else { - $question .= 'installed/loaded'; - } - $question .= '
'; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + $has_preconfig = true; + $description = 'Froxlor now requires the PHP mbstring-extension as we need to be multibyte-character safe in some cases'; + $question = 'PHP mbstring is currently: '; + if (! extension_loaded('mbstring')) { + $question .= 'not installed/loaded'; + $question .= '
Please install the PHP mbstring extension in order to finish the update'; + } else { + $question .= 'installed/loaded'; + } + $question .= '
'; + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); } if (versionInUpdate($current_db_version, '201603070')) { - $has_preconfig = true; - $description = 'You can chose whether you want to enable or disable our Let\'s Encrypt implementation.
Please remember that you need to go through the webserver-configuration when enabled because this feature needs a special configuration.

'; - $question = 'Do you want to enable Let\'s Encrypt? (default: yes): '; - $question.= makeyesno('enable_letsencrypt', '1', '0', '1').'
'; - eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + $has_preconfig = true; + $description = 'You can chose whether you want to enable or disable our Let\'s Encrypt implementation.
Please remember that you need to go through the webserver-configuration when enabled because this feature needs a special configuration.

'; + $question = 'Do you want to enable Let\'s Encrypt? (default: yes): '; + $question .= \Froxlor\UI\HTML::makeyesno('enable_letsencrypt', '1', '0', '1') . '
'; + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); + } + + if (versionInUpdate($current_db_version, '201604270')) { + $has_preconfig = true; + $description = 'You can chose whether you want to enable or disable our backup function.

'; + $question = 'Do you want to enable Backup? (default: no): '; + $question .= \Froxlor\UI\HTML::makeyesno('enable_backup', '1', '0', '0') . '
'; + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); + } + + if (versionInUpdate($current_db_version, '201605090')) { + $has_preconfig = true; + $description = 'You can chose whether you want to enable or disable our DNS editor

'; + $question = 'Do you want to enable the DNS editor? (default: no): '; + $question .= \Froxlor\UI\HTML::makeyesno('enable_dns', '1', '0', '0') . '
'; + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); + } + + if (versionInUpdate($current_db_version, '201605170')) { + $has_preconfig = true; + $description = 'Froxlor now supports the dns-daemon Power-DNS, you can chose between bind and powerdns now.'; + $question = 'Select dns-daemon you want to use: '; + $question .= ''; + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); + } + + if (versionInUpdate($current_db_version, '201609120')) { + if (Settings::Get('system.leenabled') == 1) { + $has_preconfig = true; + $description = 'You can now customize the path to your acme.conf file (global alias for Let\'s Encrypt). If you already set up Let\'s Encrypt and the acme.conf file, please set this to the complete path to the file!

'; + $question = 'Path to the acme.conf alias-file.
'; + $question .= '
'; + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); + } + } + + if (versionInUpdate($current_db_version, '201609200')) { + $has_preconfig = true; + $description = 'Specify SMTP settings which froxlor should use to send mail (optional)

'; + $question = 'Enable sending mails via SMTP?
'; + $question .= \Froxlor\UI\HTML::makeyesno('smtp_enable', '1', '0', '0') . '
'; + $question .= 'Enable sending mails via SMTP?
'; + $question .= '
'; + $question .= 'TCP port to connect to?
'; + $question .= '
'; + $question .= 'Enable TLS encryption?
'; + $question .= \Froxlor\UI\HTML::makeyesno('smtp_usetls', '1', '0', '1') . '
'; + $question .= 'Enable SMTP authentication?
'; + $question .= \Froxlor\UI\HTML::makeyesno('smtp_auth', '1', '0', '1') . '
'; + $question .= 'SMTP user?
'; + $question .= '
'; + $question .= 'SMTP password?
'; + $question .= '
'; + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); + } + + if (versionInUpdate($current_db_version, '201705050')) { + $has_preconfig = true; + $description = 'DEBIAN/UBUNTU ONLY: Enable usage of libnss-extrausers as alternative to libnss-mysql (NOTE: if enabled, go through the configuration steps right after the update!!!)

'; + $question = 'Enable usage of libnss-extrausers?
'; + $question .= \Froxlor\UI\HTML::makeyesno('system_nssextrausers', '1', '0', '0') . '
'; + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); + } + + if (versionInUpdate($current_db_version, '201712310')) { + if (Settings::Get('system.leenabled') == 1) { + $has_preconfig = true; + $description = 'Chose whether you want to disable the Let\'s Encrypt selfcheck as it causes false positives for some configurations.

'; + $question = 'Disable Let\'s Encrypt self-check?
'; + $question .= \Froxlor\UI\HTML::makeyesno('system_disable_le_selfcheck', '1', '0', '0') . '
'; + eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); + } } } diff --git a/install/updatesql.php b/install/updatesql.php index 86fe204e..23936090 100644 --- a/install/updatesql.php +++ b/install/updatesql.php @@ -16,52 +16,41 @@ * @package Install * */ +use Froxlor\FroxlorLogger; -if (!defined('AREA') - || (defined('AREA') && AREA != 'admin') - || !isset($userinfo['loginname']) - || (isset($userinfo['loginname']) && $userinfo['loginname'] == '') -) { - header('Location: ../index.php'); - exit; +require_once __DIR__ . '/lib/updateFunctions.php'; + +if (! defined('_CRON_UPDATE')) { + if (! defined('AREA') || (defined('AREA') && AREA != 'admin') || ! isset($userinfo['loginname']) || (isset($userinfo['loginname']) && $userinfo['loginname'] == '')) { + header('Location: ../index.php'); + exit(); + } } -$updatelog = FroxlorLogger::getInstanceOf(array('loginname' => 'updater')); - -$updatelogfile = validateUpdateLogFile(makeCorrectFile(dirname(__FILE__).'/update.log')); -$filelog = FileLogger::getInstanceOf(array('loginname' => 'updater')); -$filelog->setLogFile($updatelogfile); +$filelog = FroxlorLogger::getInstanceOf(array( + 'loginname' => 'updater' +)); // if first writing does not work we'll stop, tell the user to fix it // and then let him try again. try { - $filelog->logAction(ADM_ACTION, LOG_WARNING, '-------------- START LOG --------------'); -} catch(Exception $e) { - standard_error('exception', $e->getMessage()); + $filelog->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, '-------------- START LOG --------------'); +} catch (Exception $e) { + \Froxlor\UI\Response::standard_error('exception', $e->getMessage()); } -/* - * since froxlor, we have to check if there's still someone - * out there using syscp and needs to upgrade - */ -if(!isFroxlor()) { - /** - * Upgrading SysCP to Froxlor-0.9 - */ - include_once (makeCorrectFile(dirname(__FILE__).'/updates/froxlor/upgrade_syscp.inc.php')); -} - -if (isFroxlor()) { - include_once (makeCorrectFile(dirname(__FILE__).'/updates/froxlor/0.9/update_0.9.inc.php')); +if (\Froxlor\Froxlor::isFroxlor()) { + include_once (\Froxlor\FileDir::makeCorrectFile(dirname(__FILE__) . '/updates/froxlor/0.9/update_0.9.inc.php')); + include_once (\Froxlor\FileDir::makeCorrectFile(dirname(__FILE__) . '/updates/froxlor/0.10/update_0.10.inc.php')); // Check Froxlor - database integrity (only happens after all updates are done, so we know the db-layout is okay) showUpdateStep("Checking database integrity"); - $integrity = new IntegrityCheck(); - if (!$integrity->checkAll()) { + $integrity = new \Froxlor\Database\IntegrityCheck(); + if (! $integrity->checkAll()) { lastStepStatus(1, 'Monkeys ate the integrity'); showUpdateStep("Trying to remove monkeys, feeding bananas"); - if(!$integrity->fixAll()) { + if (! $integrity->fixAll()) { lastStepStatus(2, 'Some monkeys just would not move, you should contact team@froxlor.org'); } else { lastStepStatus(0, 'Integrity restored'); @@ -70,6 +59,6 @@ if (isFroxlor()) { lastStepStatus(0); } - $filelog->logAction(ADM_ACTION, LOG_WARNING, '--------------- END LOG ---------------'); + $filelog->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, '--------------- END LOG ---------------'); unset($filelog); } 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-ui.min.js b/js/jquery-ui.min.js index 16ae3381..678a0ef3 100644 --- a/js/jquery-ui.min.js +++ b/js/jquery-ui.min.js @@ -1,6 +1,13 @@ -/*! jQuery UI - v1.10.4 - 2014-02-19 +/*! jQuery UI - v1.12.1 - 2018-06-17 * http://jqueryui.com -* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.position.js, jquery.ui.draggable.js, jquery.ui.resizable.js, jquery.ui.sortable.js, jquery.ui.button.js, jquery.ui.dialog.js, jquery.ui.tooltip.js, jquery.ui.effect.js, jquery.ui.effect-scale.js, jquery.ui.effect-slide.js -* Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */ +* Includes: widget.js, position.js, data.js, disable-selection.js, focusable.js, form-reset-mixin.js, jquery-1-7.js, keycode.js, labels.js, scroll-parent.js, tabbable.js, unique-id.js, widgets/draggable.js, widgets/droppable.js, widgets/resizable.js, widgets/selectable.js, widgets/sortable.js, widgets/accordion.js, widgets/autocomplete.js, widgets/button.js, widgets/checkboxradio.js, widgets/controlgroup.js, widgets/datepicker.js, widgets/dialog.js, widgets/menu.js, widgets/mouse.js, widgets/progressbar.js, widgets/selectmenu.js, widgets/slider.js, widgets/spinner.js, widgets/tabs.js, widgets/tooltip.js, effect.js, effects/effect-blind.js, effects/effect-bounce.js, effects/effect-clip.js, effects/effect-drop.js, effects/effect-explode.js, effects/effect-fade.js, effects/effect-fold.js, effects/effect-highlight.js, effects/effect-puff.js, effects/effect-pulsate.js, effects/effect-scale.js, effects/effect-shake.js, effects/effect-size.js, effects/effect-slide.js, effects/effect-transfer.js +* Copyright jQuery Foundation and other contributors; Licensed MIT */ -(function(e,t){function i(t,i){var s,a,o,r=t.nodeName.toLowerCase();return"area"===r?(s=t.parentNode,a=s.name,t.href&&a&&"map"===s.nodeName.toLowerCase()?(o=e("img[usemap=#"+a+"]")[0],!!o&&n(o)):!1):(/input|select|textarea|button|object/.test(r)?!t.disabled:"a"===r?t.href||i:i)&&n(t)}function n(t){return e.expr.filters.visible(t)&&!e(t).parents().addBack().filter(function(){return"hidden"===e.css(this,"visibility")}).length}var s=0,a=/^ui-id-\d+$/;e.ui=e.ui||{},e.extend(e.ui,{version:"1.10.4",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}}),e.fn.extend({focus:function(t){return function(i,n){return"number"==typeof i?this.each(function(){var t=this;setTimeout(function(){e(t).focus(),n&&n.call(t)},i)}):t.apply(this,arguments)}}(e.fn.focus),scrollParent:function(){var t;return t=e.ui.ie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(e.css(this,"position"))&&/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0),/fixed/.test(this.css("position"))||!t.length?e(document):t},zIndex:function(i){if(i!==t)return this.css("zIndex",i);if(this.length)for(var n,s,a=e(this[0]);a.length&&a[0]!==document;){if(n=a.css("position"),("absolute"===n||"relative"===n||"fixed"===n)&&(s=parseInt(a.css("zIndex"),10),!isNaN(s)&&0!==s))return s;a=a.parent()}return 0},uniqueId:function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++s)})},removeUniqueId:function(){return this.each(function(){a.test(this.id)&&e(this).removeAttr("id")})}}),e.extend(e.expr[":"],{data:e.expr.createPseudo?e.expr.createPseudo(function(t){return function(i){return!!e.data(i,t)}}):function(t,i,n){return!!e.data(t,n[3])},focusable:function(t){return i(t,!isNaN(e.attr(t,"tabindex")))},tabbable:function(t){var n=e.attr(t,"tabindex"),s=isNaN(n);return(s||n>=0)&&i(t,!s)}}),e("").outerWidth(1).jquery||e.each(["Width","Height"],function(i,n){function s(t,i,n,s){return e.each(a,function(){i-=parseFloat(e.css(t,"padding"+this))||0,n&&(i-=parseFloat(e.css(t,"border"+this+"Width"))||0),s&&(i-=parseFloat(e.css(t,"margin"+this))||0)}),i}var a="Width"===n?["Left","Right"]:["Top","Bottom"],o=n.toLowerCase(),r={innerWidth:e.fn.innerWidth,innerHeight:e.fn.innerHeight,outerWidth:e.fn.outerWidth,outerHeight:e.fn.outerHeight};e.fn["inner"+n]=function(i){return i===t?r["inner"+n].call(this):this.each(function(){e(this).css(o,s(this,i)+"px")})},e.fn["outer"+n]=function(t,i){return"number"!=typeof t?r["outer"+n].call(this,t):this.each(function(){e(this).css(o,s(this,t,!0,i)+"px")})}}),e.fn.addBack||(e.fn.addBack=function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}),e("").data("a-b","a").removeData("a-b").data("a-b")&&(e.fn.removeData=function(t){return function(i){return arguments.length?t.call(this,e.camelCase(i)):t.call(this)}}(e.fn.removeData)),e.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),e.support.selectstart="onselectstart"in document.createElement("div"),e.fn.extend({disableSelection:function(){return this.bind((e.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(e){e.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}}),e.extend(e.ui,{plugin:{add:function(t,i,n){var s,a=e.ui[t].prototype;for(s in n)a.plugins[s]=a.plugins[s]||[],a.plugins[s].push([i,n[s]])},call:function(e,t,i){var n,s=e.plugins[t];if(s&&e.element[0].parentNode&&11!==e.element[0].parentNode.nodeType)for(n=0;s.length>n;n++)e.options[s[n][0]]&&s[n][1].apply(e.element,i)}},hasScroll:function(t,i){if("hidden"===e(t).css("overflow"))return!1;var n=i&&"left"===i?"scrollLeft":"scrollTop",s=!1;return t[n]>0?!0:(t[n]=1,s=t[n]>0,t[n]=0,s)}})})(jQuery);(function(t,e){var i=0,s=Array.prototype.slice,n=t.cleanData;t.cleanData=function(e){for(var i,s=0;null!=(i=e[s]);s++)try{t(i).triggerHandler("remove")}catch(o){}n(e)},t.widget=function(i,s,n){var o,a,r,h,l={},c=i.split(".")[0];i=i.split(".")[1],o=c+"-"+i,n||(n=s,s=t.Widget),t.expr[":"][o.toLowerCase()]=function(e){return!!t.data(e,o)},t[c]=t[c]||{},a=t[c][i],r=t[c][i]=function(t,i){return this._createWidget?(arguments.length&&this._createWidget(t,i),e):new r(t,i)},t.extend(r,a,{version:n.version,_proto:t.extend({},n),_childConstructors:[]}),h=new s,h.options=t.widget.extend({},h.options),t.each(n,function(i,n){return t.isFunction(n)?(l[i]=function(){var t=function(){return s.prototype[i].apply(this,arguments)},e=function(t){return s.prototype[i].apply(this,t)};return function(){var i,s=this._super,o=this._superApply;return this._super=t,this._superApply=e,i=n.apply(this,arguments),this._super=s,this._superApply=o,i}}(),e):(l[i]=n,e)}),r.prototype=t.widget.extend(h,{widgetEventPrefix:a?h.widgetEventPrefix||i:i},l,{constructor:r,namespace:c,widgetName:i,widgetFullName:o}),a?(t.each(a._childConstructors,function(e,i){var s=i.prototype;t.widget(s.namespace+"."+s.widgetName,r,i._proto)}),delete a._childConstructors):s._childConstructors.push(r),t.widget.bridge(i,r)},t.widget.extend=function(i){for(var n,o,a=s.call(arguments,1),r=0,h=a.length;h>r;r++)for(n in a[r])o=a[r][n],a[r].hasOwnProperty(n)&&o!==e&&(i[n]=t.isPlainObject(o)?t.isPlainObject(i[n])?t.widget.extend({},i[n],o):t.widget.extend({},o):o);return i},t.widget.bridge=function(i,n){var o=n.prototype.widgetFullName||i;t.fn[i]=function(a){var r="string"==typeof a,h=s.call(arguments,1),l=this;return a=!r&&h.length?t.widget.extend.apply(null,[a].concat(h)):a,r?this.each(function(){var s,n=t.data(this,o);return n?t.isFunction(n[a])&&"_"!==a.charAt(0)?(s=n[a].apply(n,h),s!==n&&s!==e?(l=s&&s.jquery?l.pushStack(s.get()):s,!1):e):t.error("no such method '"+a+"' for "+i+" widget instance"):t.error("cannot call methods on "+i+" prior to initialization; "+"attempted to call method '"+a+"'")}):this.each(function(){var e=t.data(this,o);e?e.option(a||{})._init():t.data(this,o,new n(a,this))}),l}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"
",options:{disabled:!1,create:null},_createWidget:function(e,s){s=t(s||this.defaultElement||this)[0],this.element=t(s),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.options=t.widget.extend({},this.options,this._getCreateOptions(),e),this.bindings=t(),this.hoverable=t(),this.focusable=t(),s!==this&&(t.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===s&&this.destroy()}}),this.document=t(s.style?s.ownerDocument:s.document||s),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:t.noop,_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetName).removeData(this.widgetFullName).removeData(t.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:t.noop,widget:function(){return this.element},option:function(i,s){var n,o,a,r=i;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof i)if(r={},n=i.split("."),i=n.shift(),n.length){for(o=r[i]=t.widget.extend({},this.options[i]),a=0;n.length-1>a;a++)o[n[a]]=o[n[a]]||{},o=o[n[a]];if(i=n.pop(),1===arguments.length)return o[i]===e?null:o[i];o[i]=s}else{if(1===arguments.length)return this.options[i]===e?null:this.options[i];r[i]=s}return this._setOptions(r),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return this.options[t]=e,"disabled"===t&&(this.widget().toggleClass(this.widgetFullName+"-disabled ui-state-disabled",!!e).attr("aria-disabled",e),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")),this},enable:function(){return this._setOption("disabled",!1)},disable:function(){return this._setOption("disabled",!0)},_on:function(i,s,n){var o,a=this;"boolean"!=typeof i&&(n=s,s=i,i=!1),n?(s=o=t(s),this.bindings=this.bindings.add(s)):(n=s,s=this.element,o=this.widget()),t.each(n,function(n,r){function h(){return i||a.options.disabled!==!0&&!t(this).hasClass("ui-state-disabled")?("string"==typeof r?a[r]:r).apply(a,arguments):e}"string"!=typeof r&&(h.guid=r.guid=r.guid||h.guid||t.guid++);var l=n.match(/^(\w+)\s*(.*)$/),c=l[1]+a.eventNamespace,u=l[2];u?o.delegate(u,c,h):s.bind(c,h)})},_off:function(t,e){e=(e||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,t.unbind(e).undelegate(e)},_delay:function(t,e){function i(){return("string"==typeof t?s[t]:t).apply(s,arguments)}var s=this;return setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){t(e.currentTarget).addClass("ui-state-hover")},mouseleave:function(e){t(e.currentTarget).removeClass("ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){t(e.currentTarget).addClass("ui-state-focus")},focusout:function(e){t(e.currentTarget).removeClass("ui-state-focus")}})},_trigger:function(e,i,s){var n,o,a=this.options[e];if(s=s||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(n in o)n in i||(i[n]=o[n]);return this.element.trigger(i,s),!(t.isFunction(a)&&a.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,n,o){"string"==typeof n&&(n={effect:n});var a,r=n?n===!0||"number"==typeof n?i:n.effect||i:e;n=n||{},"number"==typeof n&&(n={duration:n}),a=!t.isEmptyObject(n),n.complete=o,n.delay&&s.delay(n.delay),a&&t.effects&&t.effects.effect[r]?s[e](n):r!==e&&s[r]?s[r](n.duration,n.easing,o):s.queue(function(i){t(this)[e](),o&&o.call(s[0]),i()})}})})(jQuery);(function(t){var e=!1;t(document).mouseup(function(){e=!1}),t.widget("ui.mouse",{version:"1.10.4",options:{cancel:"input,textarea,button,select,option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.bind("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).bind("click."+this.widgetName,function(i){return!0===t.data(i.target,e.widgetName+".preventClickEvent")?(t.removeData(i.target,e.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):undefined}),this.started=!1},_mouseDestroy:function(){this.element.unbind("."+this.widgetName),this._mouseMoveDelegate&&t(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(i){if(!e){this._mouseStarted&&this._mouseUp(i),this._mouseDownEvent=i;var s=this,n=1===i.which,a="string"==typeof this.options.cancel&&i.target.nodeName?t(i.target).closest(this.options.cancel).length:!1;return n&&!a&&this._mouseCapture(i)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){s.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(i)&&this._mouseDelayMet(i)&&(this._mouseStarted=this._mouseStart(i)!==!1,!this._mouseStarted)?(i.preventDefault(),!0):(!0===t.data(i.target,this.widgetName+".preventClickEvent")&&t.removeData(i.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return s._mouseMove(t)},this._mouseUpDelegate=function(t){return s._mouseUp(t)},t(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate),i.preventDefault(),e=!0,!0)):!0}},_mouseMove:function(e){return t.ui.ie&&(!document.documentMode||9>document.documentMode)&&!e.button?this._mouseUp(e):this._mouseStarted?(this._mouseDrag(e),e.preventDefault()):(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,e)!==!1,this._mouseStarted?this._mouseDrag(e):this._mouseUp(e)),!this._mouseStarted)},_mouseUp:function(e){return t(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,e.target===this._mouseDownEvent.target&&t.data(e.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(e)),!1},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}})})(jQuery);(function(t,e){function i(t,e,i){return[parseFloat(t[0])*(p.test(t[0])?e/100:1),parseFloat(t[1])*(p.test(t[1])?i/100:1)]}function s(e,i){return parseInt(t.css(e,i),10)||0}function n(e){var i=e[0];return 9===i.nodeType?{width:e.width(),height:e.height(),offset:{top:0,left:0}}:t.isWindow(i)?{width:e.width(),height:e.height(),offset:{top:e.scrollTop(),left:e.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:e.outerWidth(),height:e.outerHeight(),offset:e.offset()}}t.ui=t.ui||{};var a,o=Math.max,r=Math.abs,l=Math.round,h=/left|center|right/,c=/top|center|bottom/,u=/[\+\-]\d+(\.[\d]+)?%?/,d=/^\w+/,p=/%$/,f=t.fn.position;t.position={scrollbarWidth:function(){if(a!==e)return a;var i,s,n=t("
"),o=n.children()[0];return t("body").append(n),i=o.offsetWidth,n.css("overflow","scroll"),s=o.offsetWidth,i===s&&(s=n[0].clientWidth),n.remove(),a=i-s},getScrollInfo:function(e){var i=e.isWindow||e.isDocument?"":e.element.css("overflow-x"),s=e.isWindow||e.isDocument?"":e.element.css("overflow-y"),n="scroll"===i||"auto"===i&&e.widths?"left":i>0?"right":"center",vertical:0>a?"top":n>0?"bottom":"middle"};u>p&&p>r(i+s)&&(l.horizontal="center"),d>g&&g>r(n+a)&&(l.vertical="middle"),l.important=o(r(i),r(s))>o(r(n),r(a))?"horizontal":"vertical",e.using.call(this,t,l)}),c.offset(t.extend(M,{using:h}))})},t.ui.position={fit:{left:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollLeft:s.offset.left,a=s.width,r=t.left-e.collisionPosition.marginLeft,l=n-r,h=r+e.collisionWidth-a-n;e.collisionWidth>a?l>0&&0>=h?(i=t.left+l+e.collisionWidth-a-n,t.left+=l-i):t.left=h>0&&0>=l?n:l>h?n+a-e.collisionWidth:n:l>0?t.left+=l:h>0?t.left-=h:t.left=o(t.left-r,t.left)},top:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollTop:s.offset.top,a=e.within.height,r=t.top-e.collisionPosition.marginTop,l=n-r,h=r+e.collisionHeight-a-n;e.collisionHeight>a?l>0&&0>=h?(i=t.top+l+e.collisionHeight-a-n,t.top+=l-i):t.top=h>0&&0>=l?n:l>h?n+a-e.collisionHeight:n:l>0?t.top+=l:h>0?t.top-=h:t.top=o(t.top-r,t.top)}},flip:{left:function(t,e){var i,s,n=e.within,a=n.offset.left+n.scrollLeft,o=n.width,l=n.isWindow?n.scrollLeft:n.offset.left,h=t.left-e.collisionPosition.marginLeft,c=h-l,u=h+e.collisionWidth-o-l,d="left"===e.my[0]?-e.elemWidth:"right"===e.my[0]?e.elemWidth:0,p="left"===e.at[0]?e.targetWidth:"right"===e.at[0]?-e.targetWidth:0,f=-2*e.offset[0];0>c?(i=t.left+d+p+f+e.collisionWidth-o-a,(0>i||r(c)>i)&&(t.left+=d+p+f)):u>0&&(s=t.left-e.collisionPosition.marginLeft+d+p+f-l,(s>0||u>r(s))&&(t.left+=d+p+f))},top:function(t,e){var i,s,n=e.within,a=n.offset.top+n.scrollTop,o=n.height,l=n.isWindow?n.scrollTop:n.offset.top,h=t.top-e.collisionPosition.marginTop,c=h-l,u=h+e.collisionHeight-o-l,d="top"===e.my[1],p=d?-e.elemHeight:"bottom"===e.my[1]?e.elemHeight:0,f="top"===e.at[1]?e.targetHeight:"bottom"===e.at[1]?-e.targetHeight:0,g=-2*e.offset[1];0>c?(s=t.top+p+f+g+e.collisionHeight-o-a,t.top+p+f+g>c&&(0>s||r(c)>s)&&(t.top+=p+f+g)):u>0&&(i=t.top-e.collisionPosition.marginTop+p+f+g-l,t.top+p+f+g>u&&(i>0||u>r(i))&&(t.top+=p+f+g))}},flipfit:{left:function(){t.ui.position.flip.left.apply(this,arguments),t.ui.position.fit.left.apply(this,arguments)},top:function(){t.ui.position.flip.top.apply(this,arguments),t.ui.position.fit.top.apply(this,arguments)}}},function(){var e,i,s,n,a,o=document.getElementsByTagName("body")[0],r=document.createElement("div");e=document.createElement(o?"div":"body"),s={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},o&&t.extend(s,{position:"absolute",left:"-1000px",top:"-1000px"});for(a in s)e.style[a]=s[a];e.appendChild(r),i=o||document.documentElement,i.insertBefore(e,i.firstChild),r.style.cssText="position: absolute; left: 10.7432222px;",n=t(r).offset().left,t.support.offsetFractions=n>10&&11>n,e.innerHTML="",i.removeChild(e)}()})(jQuery);(function(t){t.widget("ui.draggable",t.ui.mouse,{version:"1.10.4",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1,drag:null,start:null,stop:null},_create:function(){"original"!==this.options.helper||/^(?:r|a|f)/.test(this.element.css("position"))||(this.element[0].style.position="relative"),this.options.addClasses&&this.element.addClass("ui-draggable"),this.options.disabled&&this.element.addClass("ui-draggable-disabled"),this._mouseInit()},_destroy:function(){this.element.removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled"),this._mouseDestroy()},_mouseCapture:function(e){var i=this.options;return this.helper||i.disabled||t(e.target).closest(".ui-resizable-handle").length>0?!1:(this.handle=this._getHandle(e),this.handle?(t(i.iframeFix===!0?"iframe":i.iframeFix).each(function(){t("
").css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1e3}).css(t(this).offset()).appendTo("body")}),!0):!1)},_mouseStart:function(e){var i=this.options;return this.helper=this._createHelper(e),this.helper.addClass("ui-draggable-dragging"),this._cacheHelperProportions(),t.ui.ddmanager&&(t.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(),this.offsetParent=this.helper.offsetParent(),this.offsetParentCssPosition=this.offsetParent.css("position"),this.offset=this.positionAbs=this.element.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},this.offset.scroll=!1,t.extend(this.offset,{click:{left:e.pageX-this.offset.left,top:e.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.originalPosition=this.position=this._generatePosition(e),this.originalPageX=e.pageX,this.originalPageY=e.pageY,i.cursorAt&&this._adjustOffsetFromHelper(i.cursorAt),this._setContainment(),this._trigger("start",e)===!1?(this._clear(),!1):(this._cacheHelperProportions(),t.ui.ddmanager&&!i.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e),this._mouseDrag(e,!0),t.ui.ddmanager&&t.ui.ddmanager.dragStart(this,e),!0)},_mouseDrag:function(e,i){if("fixed"===this.offsetParentCssPosition&&(this.offset.parent=this._getParentOffset()),this.position=this._generatePosition(e),this.positionAbs=this._convertPositionTo("absolute"),!i){var s=this._uiHash();if(this._trigger("drag",e,s)===!1)return this._mouseUp({}),!1;this.position=s.position}return this.options.axis&&"y"===this.options.axis||(this.helper[0].style.left=this.position.left+"px"),this.options.axis&&"x"===this.options.axis||(this.helper[0].style.top=this.position.top+"px"),t.ui.ddmanager&&t.ui.ddmanager.drag(this,e),!1},_mouseStop:function(e){var i=this,s=!1;return t.ui.ddmanager&&!this.options.dropBehaviour&&(s=t.ui.ddmanager.drop(this,e)),this.dropped&&(s=this.dropped,this.dropped=!1),"original"!==this.options.helper||t.contains(this.element[0].ownerDocument,this.element[0])?("invalid"===this.options.revert&&!s||"valid"===this.options.revert&&s||this.options.revert===!0||t.isFunction(this.options.revert)&&this.options.revert.call(this.element,s)?t(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){i._trigger("stop",e)!==!1&&i._clear()}):this._trigger("stop",e)!==!1&&this._clear(),!1):!1},_mouseUp:function(e){return t("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)}),t.ui.ddmanager&&t.ui.ddmanager.dragStop(this,e),t.ui.mouse.prototype._mouseUp.call(this,e)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear(),this},_getHandle:function(e){return this.options.handle?!!t(e.target).closest(this.element.find(this.options.handle)).length:!0},_createHelper:function(e){var i=this.options,s=t.isFunction(i.helper)?t(i.helper.apply(this.element[0],[e])):"clone"===i.helper?this.element.clone().removeAttr("id"):this.element;return s.parents("body").length||s.appendTo("parent"===i.appendTo?this.element[0].parentNode:i.appendTo),s[0]===this.element[0]||/(fixed|absolute)/.test(s.css("position"))||s.css("position","absolute"),s},_adjustOffsetFromHelper:function(e){"string"==typeof e&&(e=e.split(" ")),t.isArray(e)&&(e={left:+e[0],top:+e[1]||0}),"left"in e&&(this.offset.click.left=e.left+this.margins.left),"right"in e&&(this.offset.click.left=this.helperProportions.width-e.right+this.margins.left),"top"in e&&(this.offset.click.top=e.top+this.margins.top),"bottom"in e&&(this.offset.click.top=this.helperProportions.height-e.bottom+this.margins.top)},_getParentOffset:function(){var e=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])&&(e.left+=this.scrollParent.scrollLeft(),e.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===document.body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&t.ui.ie)&&(e={top:0,left:0}),{top:e.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:e.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"===this.cssPosition){var t=this.element.position();return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:t.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e,i,s,n=this.options;return n.containment?"window"===n.containment?(this.containment=[t(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,t(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,t(window).scrollLeft()+t(window).width()-this.helperProportions.width-this.margins.left,t(window).scrollTop()+(t(window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],undefined):"document"===n.containment?(this.containment=[0,0,t(document).width()-this.helperProportions.width-this.margins.left,(t(document).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],undefined):n.containment.constructor===Array?(this.containment=n.containment,undefined):("parent"===n.containment&&(n.containment=this.helper[0].parentNode),i=t(n.containment),s=i[0],s&&(e="hidden"!==i.css("overflow"),this.containment=[(parseInt(i.css("borderLeftWidth"),10)||0)+(parseInt(i.css("paddingLeft"),10)||0),(parseInt(i.css("borderTopWidth"),10)||0)+(parseInt(i.css("paddingTop"),10)||0),(e?Math.max(s.scrollWidth,s.offsetWidth):s.offsetWidth)-(parseInt(i.css("borderRightWidth"),10)||0)-(parseInt(i.css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(e?Math.max(s.scrollHeight,s.offsetHeight):s.offsetHeight)-(parseInt(i.css("borderBottomWidth"),10)||0)-(parseInt(i.css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relative_container=i),undefined):(this.containment=null,undefined)},_convertPositionTo:function(e,i){i||(i=this.position);var s="absolute"===e?1:-1,n="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent;return this.offset.scroll||(this.offset.scroll={top:n.scrollTop(),left:n.scrollLeft()}),{top:i.top+this.offset.relative.top*s+this.offset.parent.top*s-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():this.offset.scroll.top)*s,left:i.left+this.offset.relative.left*s+this.offset.parent.left*s-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():this.offset.scroll.left)*s}},_generatePosition:function(e){var i,s,n,a,o=this.options,r="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,l=e.pageX,h=e.pageY;return this.offset.scroll||(this.offset.scroll={top:r.scrollTop(),left:r.scrollLeft()}),this.originalPosition&&(this.containment&&(this.relative_container?(s=this.relative_container.offset(),i=[this.containment[0]+s.left,this.containment[1]+s.top,this.containment[2]+s.left,this.containment[3]+s.top]):i=this.containment,e.pageX-this.offset.click.lefti[2]&&(l=i[2]+this.offset.click.left),e.pageY-this.offset.click.top>i[3]&&(h=i[3]+this.offset.click.top)),o.grid&&(n=o.grid[1]?this.originalPageY+Math.round((h-this.originalPageY)/o.grid[1])*o.grid[1]:this.originalPageY,h=i?n-this.offset.click.top>=i[1]||n-this.offset.click.top>i[3]?n:n-this.offset.click.top>=i[1]?n-o.grid[1]:n+o.grid[1]:n,a=o.grid[0]?this.originalPageX+Math.round((l-this.originalPageX)/o.grid[0])*o.grid[0]:this.originalPageX,l=i?a-this.offset.click.left>=i[0]||a-this.offset.click.left>i[2]?a:a-this.offset.click.left>=i[0]?a-o.grid[0]:a+o.grid[0]:a)),{top:h-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():this.offset.scroll.top),left:l-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():this.offset.scroll.left)}},_clear:function(){this.helper.removeClass("ui-draggable-dragging"),this.helper[0]===this.element[0]||this.cancelHelperRemoval||this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1},_trigger:function(e,i,s){return s=s||this._uiHash(),t.ui.plugin.call(this,e,[i,s]),"drag"===e&&(this.positionAbs=this._convertPositionTo("absolute")),t.Widget.prototype._trigger.call(this,e,i,s)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),t.ui.plugin.add("draggable","connectToSortable",{start:function(e,i){var s=t(this).data("ui-draggable"),n=s.options,a=t.extend({},i,{item:s.element});s.sortables=[],t(n.connectToSortable).each(function(){var i=t.data(this,"ui-sortable");i&&!i.options.disabled&&(s.sortables.push({instance:i,shouldRevert:i.options.revert}),i.refreshPositions(),i._trigger("activate",e,a))})},stop:function(e,i){var s=t(this).data("ui-draggable"),n=t.extend({},i,{item:s.element});t.each(s.sortables,function(){this.instance.isOver?(this.instance.isOver=0,s.cancelHelperRemoval=!0,this.instance.cancelHelperRemoval=!1,this.shouldRevert&&(this.instance.options.revert=this.shouldRevert),this.instance._mouseStop(e),this.instance.options.helper=this.instance.options._helper,"original"===s.options.helper&&this.instance.currentItem.css({top:"auto",left:"auto"})):(this.instance.cancelHelperRemoval=!1,this.instance._trigger("deactivate",e,n))})},drag:function(e,i){var s=t(this).data("ui-draggable"),n=this;t.each(s.sortables,function(){var a=!1,o=this;this.instance.positionAbs=s.positionAbs,this.instance.helperProportions=s.helperProportions,this.instance.offset.click=s.offset.click,this.instance._intersectsWith(this.instance.containerCache)&&(a=!0,t.each(s.sortables,function(){return this.instance.positionAbs=s.positionAbs,this.instance.helperProportions=s.helperProportions,this.instance.offset.click=s.offset.click,this!==o&&this.instance._intersectsWith(this.instance.containerCache)&&t.contains(o.instance.element[0],this.instance.element[0])&&(a=!1),a})),a?(this.instance.isOver||(this.instance.isOver=1,this.instance.currentItem=t(n).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item",!0),this.instance.options._helper=this.instance.options.helper,this.instance.options.helper=function(){return i.helper[0]},e.target=this.instance.currentItem[0],this.instance._mouseCapture(e,!0),this.instance._mouseStart(e,!0,!0),this.instance.offset.click.top=s.offset.click.top,this.instance.offset.click.left=s.offset.click.left,this.instance.offset.parent.left-=s.offset.parent.left-this.instance.offset.parent.left,this.instance.offset.parent.top-=s.offset.parent.top-this.instance.offset.parent.top,s._trigger("toSortable",e),s.dropped=this.instance.element,s.currentItem=s.element,this.instance.fromOutside=s),this.instance.currentItem&&this.instance._mouseDrag(e)):this.instance.isOver&&(this.instance.isOver=0,this.instance.cancelHelperRemoval=!0,this.instance.options.revert=!1,this.instance._trigger("out",e,this.instance._uiHash(this.instance)),this.instance._mouseStop(e,!0),this.instance.options.helper=this.instance.options._helper,this.instance.currentItem.remove(),this.instance.placeholder&&this.instance.placeholder.remove(),s._trigger("fromSortable",e),s.dropped=!1)})}}),t.ui.plugin.add("draggable","cursor",{start:function(){var e=t("body"),i=t(this).data("ui-draggable").options;e.css("cursor")&&(i._cursor=e.css("cursor")),e.css("cursor",i.cursor)},stop:function(){var e=t(this).data("ui-draggable").options;e._cursor&&t("body").css("cursor",e._cursor)}}),t.ui.plugin.add("draggable","opacity",{start:function(e,i){var s=t(i.helper),n=t(this).data("ui-draggable").options;s.css("opacity")&&(n._opacity=s.css("opacity")),s.css("opacity",n.opacity)},stop:function(e,i){var s=t(this).data("ui-draggable").options;s._opacity&&t(i.helper).css("opacity",s._opacity)}}),t.ui.plugin.add("draggable","scroll",{start:function(){var e=t(this).data("ui-draggable");e.scrollParent[0]!==document&&"HTML"!==e.scrollParent[0].tagName&&(e.overflowOffset=e.scrollParent.offset())},drag:function(e){var i=t(this).data("ui-draggable"),s=i.options,n=!1;i.scrollParent[0]!==document&&"HTML"!==i.scrollParent[0].tagName?(s.axis&&"x"===s.axis||(i.overflowOffset.top+i.scrollParent[0].offsetHeight-e.pageY=0;u--)r=p.snapElements[u].left,l=r+p.snapElements[u].width,h=p.snapElements[u].top,c=h+p.snapElements[u].height,r-f>_||m>l+f||h-f>b||v>c+f||!t.contains(p.snapElements[u].item.ownerDocument,p.snapElements[u].item)?(p.snapElements[u].snapping&&p.options.snap.release&&p.options.snap.release.call(p.element,e,t.extend(p._uiHash(),{snapItem:p.snapElements[u].item})),p.snapElements[u].snapping=!1):("inner"!==g.snapMode&&(s=f>=Math.abs(h-b),n=f>=Math.abs(c-v),a=f>=Math.abs(r-_),o=f>=Math.abs(l-m),s&&(i.position.top=p._convertPositionTo("relative",{top:h-p.helperProportions.height,left:0}).top-p.margins.top),n&&(i.position.top=p._convertPositionTo("relative",{top:c,left:0}).top-p.margins.top),a&&(i.position.left=p._convertPositionTo("relative",{top:0,left:r-p.helperProportions.width}).left-p.margins.left),o&&(i.position.left=p._convertPositionTo("relative",{top:0,left:l}).left-p.margins.left)),d=s||n||a||o,"outer"!==g.snapMode&&(s=f>=Math.abs(h-v),n=f>=Math.abs(c-b),a=f>=Math.abs(r-m),o=f>=Math.abs(l-_),s&&(i.position.top=p._convertPositionTo("relative",{top:h,left:0}).top-p.margins.top),n&&(i.position.top=p._convertPositionTo("relative",{top:c-p.helperProportions.height,left:0}).top-p.margins.top),a&&(i.position.left=p._convertPositionTo("relative",{top:0,left:r}).left-p.margins.left),o&&(i.position.left=p._convertPositionTo("relative",{top:0,left:l-p.helperProportions.width}).left-p.margins.left)),!p.snapElements[u].snapping&&(s||n||a||o||d)&&p.options.snap.snap&&p.options.snap.snap.call(p.element,e,t.extend(p._uiHash(),{snapItem:p.snapElements[u].item})),p.snapElements[u].snapping=s||n||a||o||d)}}),t.ui.plugin.add("draggable","stack",{start:function(){var e,i=this.data("ui-draggable").options,s=t.makeArray(t(i.stack)).sort(function(e,i){return(parseInt(t(e).css("zIndex"),10)||0)-(parseInt(t(i).css("zIndex"),10)||0)});s.length&&(e=parseInt(t(s[0]).css("zIndex"),10)||0,t(s).each(function(i){t(this).css("zIndex",e+i)}),this.css("zIndex",e+s.length))}}),t.ui.plugin.add("draggable","zIndex",{start:function(e,i){var s=t(i.helper),n=t(this).data("ui-draggable").options;s.css("zIndex")&&(n._zIndex=s.css("zIndex")),s.css("zIndex",n.zIndex)},stop:function(e,i){var s=t(this).data("ui-draggable").options;s._zIndex&&t(i.helper).css("zIndex",s._zIndex)}})})(jQuery);(function(t){function e(t){return parseInt(t,10)||0}function i(t){return!isNaN(parseInt(t,10))}t.widget("ui.resizable",t.ui.mouse,{version:"1.10.4",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_create:function(){var e,i,s,n,a,o=this,r=this.options;if(this.element.addClass("ui-resizable"),t.extend(this,{_aspectRatio:!!r.aspectRatio,aspectRatio:r.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:r.helper||r.ghost||r.animate?r.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)&&(this.element.wrap(t("
").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.data("ui-resizable")),this.elementIsWrapper=!0,this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")}),this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0}),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css({margin:this.originalElement.css("margin")}),this._proportionallyResize()),this.handles=r.handles||(t(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),e=this.handles.split(","),this.handles={},i=0;e.length>i;i++)s=t.trim(e[i]),a="ui-resizable-"+s,n=t("
"),n.css({zIndex:r.zIndex}),"se"===s&&n.addClass("ui-icon ui-icon-gripsmall-diagonal-se"),this.handles[s]=".ui-resizable-"+s,this.element.append(n);this._renderAxis=function(e){var i,s,n,a;e=e||this.element;for(i in this.handles)this.handles[i].constructor===String&&(this.handles[i]=t(this.handles[i],this.element).show()),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)&&(s=t(this.handles[i],this.element),a=/sw|ne|nw|se|n|s/.test(i)?s.outerHeight():s.outerWidth(),n=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join(""),e.css(n,a),this._proportionallyResize()),t(this.handles[i]).length},this._renderAxis(this.element),this._handles=t(".ui-resizable-handle",this.element).disableSelection(),this._handles.mouseover(function(){o.resizing||(this.className&&(n=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),o.axis=n&&n[1]?n[1]:"se")}),r.autoHide&&(this._handles.hide(),t(this.element).addClass("ui-resizable-autohide").mouseenter(function(){r.disabled||(t(this).removeClass("ui-resizable-autohide"),o._handles.show())}).mouseleave(function(){r.disabled||o.resizing||(t(this).addClass("ui-resizable-autohide"),o._handles.hide())})),this._mouseInit()},_destroy:function(){this._mouseDestroy();var e,i=function(e){t(e).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(i(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),i(this.originalElement),this},_mouseCapture:function(e){var i,s,n=!1;for(i in this.handles)s=t(this.handles[i])[0],(s===e.target||t.contains(s,e.target))&&(n=!0);return!this.options.disabled&&n},_mouseStart:function(i){var s,n,a,o=this.options,r=this.element.position(),h=this.element;return this.resizing=!0,/absolute/.test(h.css("position"))?h.css({position:"absolute",top:h.css("top"),left:h.css("left")}):h.is(".ui-draggable")&&h.css({position:"absolute",top:r.top,left:r.left}),this._renderProxy(),s=e(this.helper.css("left")),n=e(this.helper.css("top")),o.containment&&(s+=t(o.containment).scrollLeft()||0,n+=t(o.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:s,top:n},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:h.width(),height:h.height()},this.originalSize=this._helper?{width:h.outerWidth(),height:h.outerHeight()}:{width:h.width(),height:h.height()},this.originalPosition={left:s,top:n},this.sizeDiff={width:h.outerWidth()-h.width(),height:h.outerHeight()-h.height()},this.originalMousePosition={left:i.pageX,top:i.pageY},this.aspectRatio="number"==typeof o.aspectRatio?o.aspectRatio:this.originalSize.width/this.originalSize.height||1,a=t(".ui-resizable-"+this.axis).css("cursor"),t("body").css("cursor","auto"===a?this.axis+"-resize":a),h.addClass("ui-resizable-resizing"),this._propagate("start",i),!0},_mouseDrag:function(e){var i,s=this.helper,n={},a=this.originalMousePosition,o=this.axis,r=this.position.top,h=this.position.left,l=this.size.width,c=this.size.height,u=e.pageX-a.left||0,d=e.pageY-a.top||0,p=this._change[o];return p?(i=p.apply(this,[e,u,d]),this._updateVirtualBoundaries(e.shiftKey),(this._aspectRatio||e.shiftKey)&&(i=this._updateRatio(i,e)),i=this._respectSize(i,e),this._updateCache(i),this._propagate("resize",e),this.position.top!==r&&(n.top=this.position.top+"px"),this.position.left!==h&&(n.left=this.position.left+"px"),this.size.width!==l&&(n.width=this.size.width+"px"),this.size.height!==c&&(n.height=this.size.height+"px"),s.css(n),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),t.isEmptyObject(n)||this._trigger("resize",e,this.ui()),!1):!1},_mouseStop:function(e){this.resizing=!1;var i,s,n,a,o,r,h,l=this.options,c=this;return this._helper&&(i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),n=s&&t.ui.hasScroll(i[0],"left")?0:c.sizeDiff.height,a=s?0:c.sizeDiff.width,o={width:c.helper.width()-a,height:c.helper.height()-n},r=parseInt(c.element.css("left"),10)+(c.position.left-c.originalPosition.left)||null,h=parseInt(c.element.css("top"),10)+(c.position.top-c.originalPosition.top)||null,l.animate||this.element.css(t.extend(o,{top:h,left:r})),c.helper.height(c.size.height),c.helper.width(c.size.width),this._helper&&!l.animate&&this._proportionallyResize()),t("body").css("cursor","auto"),this.element.removeClass("ui-resizable-resizing"),this._propagate("stop",e),this._helper&&this.helper.remove(),!1},_updateVirtualBoundaries:function(t){var e,s,n,a,o,r=this.options;o={minWidth:i(r.minWidth)?r.minWidth:0,maxWidth:i(r.maxWidth)?r.maxWidth:1/0,minHeight:i(r.minHeight)?r.minHeight:0,maxHeight:i(r.maxHeight)?r.maxHeight:1/0},(this._aspectRatio||t)&&(e=o.minHeight*this.aspectRatio,n=o.minWidth/this.aspectRatio,s=o.maxHeight*this.aspectRatio,a=o.maxWidth/this.aspectRatio,e>o.minWidth&&(o.minWidth=e),n>o.minHeight&&(o.minHeight=n),o.maxWidth>s&&(o.maxWidth=s),o.maxHeight>a&&(o.maxHeight=a)),this._vBoundaries=o},_updateCache:function(t){this.offset=this.helper.offset(),i(t.left)&&(this.position.left=t.left),i(t.top)&&(this.position.top=t.top),i(t.height)&&(this.size.height=t.height),i(t.width)&&(this.size.width=t.width)},_updateRatio:function(t){var e=this.position,s=this.size,n=this.axis;return i(t.height)?t.width=t.height*this.aspectRatio:i(t.width)&&(t.height=t.width/this.aspectRatio),"sw"===n&&(t.left=e.left+(s.width-t.width),t.top=null),"nw"===n&&(t.top=e.top+(s.height-t.height),t.left=e.left+(s.width-t.width)),t},_respectSize:function(t){var e=this._vBoundaries,s=this.axis,n=i(t.width)&&e.maxWidth&&e.maxWidtht.width,r=i(t.height)&&e.minHeight&&e.minHeight>t.height,h=this.originalPosition.left+this.originalSize.width,l=this.position.top+this.size.height,c=/sw|nw|w/.test(s),u=/nw|ne|n/.test(s);return o&&(t.width=e.minWidth),r&&(t.height=e.minHeight),n&&(t.width=e.maxWidth),a&&(t.height=e.maxHeight),o&&c&&(t.left=h-e.minWidth),n&&c&&(t.left=h-e.maxWidth),r&&u&&(t.top=l-e.minHeight),a&&u&&(t.top=l-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_proportionallyResize:function(){if(this._proportionallyResizeElements.length){var t,e,i,s,n,a=this.helper||this.element;for(t=0;this._proportionallyResizeElements.length>t;t++){if(n=this._proportionallyResizeElements[t],!this.borderDif)for(this.borderDif=[],i=[n.css("borderTopWidth"),n.css("borderRightWidth"),n.css("borderBottomWidth"),n.css("borderLeftWidth")],s=[n.css("paddingTop"),n.css("paddingRight"),n.css("paddingBottom"),n.css("paddingLeft")],e=0;i.length>e;e++)this.borderDif[e]=(parseInt(i[e],10)||0)+(parseInt(s[e],10)||0);n.css({height:a.height()-this.borderDif[0]-this.borderDif[2]||0,width:a.width()-this.borderDif[1]-this.borderDif[3]||0})}}},_renderProxy:function(){var e=this.element,i=this.options;this.elementOffset=e.offset(),this._helper?(this.helper=this.helper||t("
"),this.helper.addClass(this._helper).css({width:this.element.outerWidth()-1,height:this.element.outerHeight()-1,position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++i.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize,s=this.originalPosition;return{left:s.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize,n=this.originalPosition;return{top:n.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},sw:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[e,i,s]))},ne:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},nw:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[e,i,s]))}},_propagate:function(e,i){t.ui.plugin.call(this,e,[i,this.ui()]),"resize"!==e&&this._trigger(e,i,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),t.ui.plugin.add("resizable","animate",{stop:function(e){var i=t(this).data("ui-resizable"),s=i.options,n=i._proportionallyResizeElements,a=n.length&&/textarea/i.test(n[0].nodeName),o=a&&t.ui.hasScroll(n[0],"left")?0:i.sizeDiff.height,r=a?0:i.sizeDiff.width,h={width:i.size.width-r,height:i.size.height-o},l=parseInt(i.element.css("left"),10)+(i.position.left-i.originalPosition.left)||null,c=parseInt(i.element.css("top"),10)+(i.position.top-i.originalPosition.top)||null;i.element.animate(t.extend(h,c&&l?{top:c,left:l}:{}),{duration:s.animateDuration,easing:s.animateEasing,step:function(){var s={width:parseInt(i.element.css("width"),10),height:parseInt(i.element.css("height"),10),top:parseInt(i.element.css("top"),10),left:parseInt(i.element.css("left"),10)};n&&n.length&&t(n[0]).css({width:s.width,height:s.height}),i._updateCache(s),i._propagate("resize",e)}})}}),t.ui.plugin.add("resizable","containment",{start:function(){var i,s,n,a,o,r,h,l=t(this).data("ui-resizable"),c=l.options,u=l.element,d=c.containment,p=d instanceof t?d.get(0):/parent/.test(d)?u.parent().get(0):d;p&&(l.containerElement=t(p),/document/.test(d)||d===document?(l.containerOffset={left:0,top:0},l.containerPosition={left:0,top:0},l.parentData={element:t(document),left:0,top:0,width:t(document).width(),height:t(document).height()||document.body.parentNode.scrollHeight}):(i=t(p),s=[],t(["Top","Right","Left","Bottom"]).each(function(t,n){s[t]=e(i.css("padding"+n))}),l.containerOffset=i.offset(),l.containerPosition=i.position(),l.containerSize={height:i.innerHeight()-s[3],width:i.innerWidth()-s[1]},n=l.containerOffset,a=l.containerSize.height,o=l.containerSize.width,r=t.ui.hasScroll(p,"left")?p.scrollWidth:o,h=t.ui.hasScroll(p)?p.scrollHeight:a,l.parentData={element:p,left:n.left,top:n.top,width:r,height:h}))},resize:function(e){var i,s,n,a,o=t(this).data("ui-resizable"),r=o.options,h=o.containerOffset,l=o.position,c=o._aspectRatio||e.shiftKey,u={top:0,left:0},d=o.containerElement;d[0]!==document&&/static/.test(d.css("position"))&&(u=h),l.left<(o._helper?h.left:0)&&(o.size.width=o.size.width+(o._helper?o.position.left-h.left:o.position.left-u.left),c&&(o.size.height=o.size.width/o.aspectRatio),o.position.left=r.helper?h.left:0),l.top<(o._helper?h.top:0)&&(o.size.height=o.size.height+(o._helper?o.position.top-h.top:o.position.top),c&&(o.size.width=o.size.height*o.aspectRatio),o.position.top=o._helper?h.top:0),o.offset.left=o.parentData.left+o.position.left,o.offset.top=o.parentData.top+o.position.top,i=Math.abs((o._helper?o.offset.left-u.left:o.offset.left-u.left)+o.sizeDiff.width),s=Math.abs((o._helper?o.offset.top-u.top:o.offset.top-h.top)+o.sizeDiff.height),n=o.containerElement.get(0)===o.element.parent().get(0),a=/relative|absolute/.test(o.containerElement.css("position")),n&&a&&(i-=Math.abs(o.parentData.left)),i+o.size.width>=o.parentData.width&&(o.size.width=o.parentData.width-i,c&&(o.size.height=o.size.width/o.aspectRatio)),s+o.size.height>=o.parentData.height&&(o.size.height=o.parentData.height-s,c&&(o.size.width=o.size.height*o.aspectRatio))},stop:function(){var e=t(this).data("ui-resizable"),i=e.options,s=e.containerOffset,n=e.containerPosition,a=e.containerElement,o=t(e.helper),r=o.offset(),h=o.outerWidth()-e.sizeDiff.width,l=o.outerHeight()-e.sizeDiff.height;e._helper&&!i.animate&&/relative/.test(a.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l}),e._helper&&!i.animate&&/static/.test(a.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l})}}),t.ui.plugin.add("resizable","alsoResize",{start:function(){var e=t(this).data("ui-resizable"),i=e.options,s=function(e){t(e).each(function(){var e=t(this);e.data("ui-resizable-alsoresize",{width:parseInt(e.width(),10),height:parseInt(e.height(),10),left:parseInt(e.css("left"),10),top:parseInt(e.css("top"),10)})})};"object"!=typeof i.alsoResize||i.alsoResize.parentNode?s(i.alsoResize):i.alsoResize.length?(i.alsoResize=i.alsoResize[0],s(i.alsoResize)):t.each(i.alsoResize,function(t){s(t)})},resize:function(e,i){var s=t(this).data("ui-resizable"),n=s.options,a=s.originalSize,o=s.originalPosition,r={height:s.size.height-a.height||0,width:s.size.width-a.width||0,top:s.position.top-o.top||0,left:s.position.left-o.left||0},h=function(e,s){t(e).each(function(){var e=t(this),n=t(this).data("ui-resizable-alsoresize"),a={},o=s&&s.length?s:e.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];t.each(o,function(t,e){var i=(n[e]||0)+(r[e]||0);i&&i>=0&&(a[e]=i||null)}),e.css(a)})};"object"!=typeof n.alsoResize||n.alsoResize.nodeType?h(n.alsoResize):t.each(n.alsoResize,function(t,e){h(t,e)})},stop:function(){t(this).removeData("resizable-alsoresize")}}),t.ui.plugin.add("resizable","ghost",{start:function(){var e=t(this).data("ui-resizable"),i=e.options,s=e.size;e.ghost=e.originalElement.clone(),e.ghost.css({opacity:.25,display:"block",position:"relative",height:s.height,width:s.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass("string"==typeof i.ghost?i.ghost:""),e.ghost.appendTo(e.helper)},resize:function(){var e=t(this).data("ui-resizable");e.ghost&&e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})},stop:function(){var e=t(this).data("ui-resizable");e.ghost&&e.helper&&e.helper.get(0).removeChild(e.ghost.get(0))}}),t.ui.plugin.add("resizable","grid",{resize:function(){var e=t(this).data("ui-resizable"),i=e.options,s=e.size,n=e.originalSize,a=e.originalPosition,o=e.axis,r="number"==typeof i.grid?[i.grid,i.grid]:i.grid,h=r[0]||1,l=r[1]||1,c=Math.round((s.width-n.width)/h)*h,u=Math.round((s.height-n.height)/l)*l,d=n.width+c,p=n.height+u,f=i.maxWidth&&d>i.maxWidth,g=i.maxHeight&&p>i.maxHeight,m=i.minWidth&&i.minWidth>d,v=i.minHeight&&i.minHeight>p;i.grid=r,m&&(d+=h),v&&(p+=l),f&&(d-=h),g&&(p-=l),/^(se|s|e)$/.test(o)?(e.size.width=d,e.size.height=p):/^(ne)$/.test(o)?(e.size.width=d,e.size.height=p,e.position.top=a.top-u):/^(sw)$/.test(o)?(e.size.width=d,e.size.height=p,e.position.left=a.left-c):(p-l>0?(e.size.height=p,e.position.top=a.top-u):(e.size.height=l,e.position.top=a.top+n.height-l),d-h>0?(e.size.width=d,e.position.left=a.left-c):(e.size.width=h,e.position.left=a.left+n.width-h))}})})(jQuery);(function(t){function e(t,e,i){return t>e&&e+i>t}function i(t){return/left|right/.test(t.css("float"))||/inline|table-cell/.test(t.css("display"))}t.widget("ui.sortable",t.ui.mouse,{version:"1.10.4",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3,activate:null,beforeStop:null,change:null,deactivate:null,out:null,over:null,receive:null,remove:null,sort:null,start:null,stop:null,update:null},_create:function(){var t=this.options;this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.floating=this.items.length?"x"===t.axis||i(this.items[0].item):!1,this.offset=this.element.offset(),this._mouseInit(),this.ready=!0},_destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled"),this._mouseDestroy();for(var t=this.items.length-1;t>=0;t--)this.items[t].item.removeData(this.widgetName+"-item");return this},_setOption:function(e,i){"disabled"===e?(this.options[e]=i,this.widget().toggleClass("ui-sortable-disabled",!!i)):t.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(e,i){var s=null,n=!1,o=this;return this.reverting?!1:this.options.disabled||"static"===this.options.type?!1:(this._refreshItems(e),t(e.target).parents().each(function(){return t.data(this,o.widgetName+"-item")===o?(s=t(this),!1):undefined}),t.data(e.target,o.widgetName+"-item")===o&&(s=t(e.target)),s?!this.options.handle||i||(t(this.options.handle,s).find("*").addBack().each(function(){this===e.target&&(n=!0)}),n)?(this.currentItem=s,this._removeCurrentsFromItems(),!0):!1:!1)},_mouseStart:function(e,i,s){var n,o,a=this.options;if(this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(e),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},t.extend(this.offset,{click:{left:e.pageX-this.offset.left,top:e.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(e),this.originalPageX=e.pageX,this.originalPageY=e.pageY,a.cursorAt&&this._adjustOffsetFromHelper(a.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!==this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),a.containment&&this._setContainment(),a.cursor&&"auto"!==a.cursor&&(o=this.document.find("body"),this.storedCursor=o.css("cursor"),o.css("cursor",a.cursor),this.storedStylesheet=t("").appendTo(o)),a.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",a.opacity)),a.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",a.zIndex)),this.scrollParent[0]!==document&&"HTML"!==this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",e,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions(),!s)for(n=this.containers.length-1;n>=0;n--)this.containers[n]._trigger("activate",e,this._uiHash(this));return t.ui.ddmanager&&(t.ui.ddmanager.current=this),t.ui.ddmanager&&!a.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(e),!0},_mouseDrag:function(e){var i,s,n,o,a=this.options,r=!1;for(this.position=this._generatePosition(e),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs),this.options.scroll&&(this.scrollParent[0]!==document&&"HTML"!==this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-e.pageY=0;i--)if(s=this.items[i],n=s.item[0],o=this._intersectsWithPointer(s),o&&s.instance===this.currentContainer&&n!==this.currentItem[0]&&this.placeholder[1===o?"next":"prev"]()[0]!==n&&!t.contains(this.placeholder[0],n)&&("semi-dynamic"===this.options.type?!t.contains(this.element[0],n):!0)){if(this.direction=1===o?"down":"up","pointer"!==this.options.tolerance&&!this._intersectsWithSides(s))break;this._rearrange(e,s),this._trigger("change",e,this._uiHash());break}return this._contactContainers(e),t.ui.ddmanager&&t.ui.ddmanager.drag(this,e),this._trigger("sort",e,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(e,i){if(e){if(t.ui.ddmanager&&!this.options.dropBehaviour&&t.ui.ddmanager.drop(this,e),this.options.revert){var s=this,n=this.placeholder.offset(),o=this.options.axis,a={};o&&"x"!==o||(a.left=n.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]===document.body?0:this.offsetParent[0].scrollLeft)),o&&"y"!==o||(a.top=n.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]===document.body?0:this.offsetParent[0].scrollTop)),this.reverting=!0,t(this.helper).animate(a,parseInt(this.options.revert,10)||500,function(){s._clear(e)})}else this._clear(e,i);return!1}},cancel:function(){if(this.dragging){this._mouseUp({target:null}),"original"===this.options.helper?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var e=this.containers.length-1;e>=0;e--)this.containers[e]._trigger("deactivate",null,this._uiHash(this)),this.containers[e].containerCache.over&&(this.containers[e]._trigger("out",null,this._uiHash(this)),this.containers[e].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),"original"!==this.options.helper&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),t.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?t(this.domPosition.prev).after(this.currentItem):t(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},t(i).each(function(){var i=(t(e.item||this).attr(e.attribute||"id")||"").match(e.expression||/(.+)[\-=_](.+)/);i&&s.push((e.key||i[1]+"[]")+"="+(e.key&&e.expression?i[1]:i[2]))}),!s.length&&e.key&&s.push(e.key+"="),s.join("&")},toArray:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},i.each(function(){s.push(t(e.item||this).attr(e.attribute||"id")||"")}),s},_intersectsWith:function(t){var e=this.positionAbs.left,i=e+this.helperProportions.width,s=this.positionAbs.top,n=s+this.helperProportions.height,o=t.left,a=o+t.width,r=t.top,h=r+t.height,l=this.offset.click.top,c=this.offset.click.left,u="x"===this.options.axis||s+l>r&&h>s+l,d="y"===this.options.axis||e+c>o&&a>e+c,p=u&&d;return"pointer"===this.options.tolerance||this.options.forcePointerForContainers||"pointer"!==this.options.tolerance&&this.helperProportions[this.floating?"width":"height"]>t[this.floating?"width":"height"]?p:e+this.helperProportions.width/2>o&&a>i-this.helperProportions.width/2&&s+this.helperProportions.height/2>r&&h>n-this.helperProportions.height/2},_intersectsWithPointer:function(t){var i="x"===this.options.axis||e(this.positionAbs.top+this.offset.click.top,t.top,t.height),s="y"===this.options.axis||e(this.positionAbs.left+this.offset.click.left,t.left,t.width),n=i&&s,o=this._getDragVerticalDirection(),a=this._getDragHorizontalDirection();return n?this.floating?a&&"right"===a||"down"===o?2:1:o&&("down"===o?2:1):!1},_intersectsWithSides:function(t){var i=e(this.positionAbs.top+this.offset.click.top,t.top+t.height/2,t.height),s=e(this.positionAbs.left+this.offset.click.left,t.left+t.width/2,t.width),n=this._getDragVerticalDirection(),o=this._getDragHorizontalDirection();return this.floating&&o?"right"===o&&s||"left"===o&&!s:n&&("down"===n&&i||"up"===n&&!i)},_getDragVerticalDirection:function(){var t=this.positionAbs.top-this.lastPositionAbs.top;return 0!==t&&(t>0?"down":"up")},_getDragHorizontalDirection:function(){var t=this.positionAbs.left-this.lastPositionAbs.left;return 0!==t&&(t>0?"right":"left")},refresh:function(t){return this._refreshItems(t),this.refreshPositions(),this},_connectWith:function(){var t=this.options;return t.connectWith.constructor===String?[t.connectWith]:t.connectWith},_getItemsAsjQuery:function(e){function i(){r.push(this)}var s,n,o,a,r=[],h=[],l=this._connectWith();if(l&&e)for(s=l.length-1;s>=0;s--)for(o=t(l[s]),n=o.length-1;n>=0;n--)a=t.data(o[n],this.widgetFullName),a&&a!==this&&!a.options.disabled&&h.push([t.isFunction(a.options.items)?a.options.items.call(a.element):t(a.options.items,a.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),a]);for(h.push([t.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):t(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]),s=h.length-1;s>=0;s--)h[s][0].each(i);return t(r)},_removeCurrentsFromItems:function(){var e=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=t.grep(this.items,function(t){for(var i=0;e.length>i;i++)if(e[i]===t.item[0])return!1;return!0})},_refreshItems:function(e){this.items=[],this.containers=[this];var i,s,n,o,a,r,h,l,c=this.items,u=[[t.isFunction(this.options.items)?this.options.items.call(this.element[0],e,{item:this.currentItem}):t(this.options.items,this.element),this]],d=this._connectWith();if(d&&this.ready)for(i=d.length-1;i>=0;i--)for(n=t(d[i]),s=n.length-1;s>=0;s--)o=t.data(n[s],this.widgetFullName),o&&o!==this&&!o.options.disabled&&(u.push([t.isFunction(o.options.items)?o.options.items.call(o.element[0],e,{item:this.currentItem}):t(o.options.items,o.element),o]),this.containers.push(o));for(i=u.length-1;i>=0;i--)for(a=u[i][1],r=u[i][0],s=0,l=r.length;l>s;s++)h=t(r[s]),h.data(this.widgetName+"-item",a),c.push({item:h,instance:a,width:0,height:0,left:0,top:0})},refreshPositions:function(e){this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());var i,s,n,o;for(i=this.items.length-1;i>=0;i--)s=this.items[i],s.instance!==this.currentContainer&&this.currentContainer&&s.item[0]!==this.currentItem[0]||(n=this.options.toleranceElement?t(this.options.toleranceElement,s.item):s.item,e||(s.width=n.outerWidth(),s.height=n.outerHeight()),o=n.offset(),s.left=o.left,s.top=o.top);if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(i=this.containers.length-1;i>=0;i--)o=this.containers[i].element.offset(),this.containers[i].containerCache.left=o.left,this.containers[i].containerCache.top=o.top,this.containers[i].containerCache.width=this.containers[i].element.outerWidth(),this.containers[i].containerCache.height=this.containers[i].element.outerHeight();return this},_createPlaceholder:function(e){e=e||this;var i,s=e.options;s.placeholder&&s.placeholder.constructor!==String||(i=s.placeholder,s.placeholder={element:function(){var s=e.currentItem[0].nodeName.toLowerCase(),n=t("<"+s+">",e.document[0]).addClass(i||e.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper");return"tr"===s?e.currentItem.children().each(function(){t(" ",e.document[0]).attr("colspan",t(this).attr("colspan")||1).appendTo(n)}):"img"===s&&n.attr("src",e.currentItem.attr("src")),i||n.css("visibility","hidden"),n},update:function(t,n){(!i||s.forcePlaceholderSize)&&(n.height()||n.height(e.currentItem.innerHeight()-parseInt(e.currentItem.css("paddingTop")||0,10)-parseInt(e.currentItem.css("paddingBottom")||0,10)),n.width()||n.width(e.currentItem.innerWidth()-parseInt(e.currentItem.css("paddingLeft")||0,10)-parseInt(e.currentItem.css("paddingRight")||0,10)))}}),e.placeholder=t(s.placeholder.element.call(e.element,e.currentItem)),e.currentItem.after(e.placeholder),s.placeholder.update(e,e.placeholder)},_contactContainers:function(s){var n,o,a,r,h,l,c,u,d,p,f=null,g=null;for(n=this.containers.length-1;n>=0;n--)if(!t.contains(this.currentItem[0],this.containers[n].element[0]))if(this._intersectsWith(this.containers[n].containerCache)){if(f&&t.contains(this.containers[n].element[0],f.element[0]))continue;f=this.containers[n],g=n}else this.containers[n].containerCache.over&&(this.containers[n]._trigger("out",s,this._uiHash(this)),this.containers[n].containerCache.over=0);if(f)if(1===this.containers.length)this.containers[g].containerCache.over||(this.containers[g]._trigger("over",s,this._uiHash(this)),this.containers[g].containerCache.over=1);else{for(a=1e4,r=null,p=f.floating||i(this.currentItem),h=p?"left":"top",l=p?"width":"height",c=this.positionAbs[h]+this.offset.click[h],o=this.items.length-1;o>=0;o--)t.contains(this.containers[g].element[0],this.items[o].item[0])&&this.items[o].item[0]!==this.currentItem[0]&&(!p||e(this.positionAbs.top+this.offset.click.top,this.items[o].top,this.items[o].height))&&(u=this.items[o].item.offset()[h],d=!1,Math.abs(u-c)>Math.abs(u+this.items[o][l]-c)&&(d=!0,u+=this.items[o][l]),a>Math.abs(u-c)&&(a=Math.abs(u-c),r=this.items[o],this.direction=d?"up":"down"));if(!r&&!this.options.dropOnEmpty)return;if(this.currentContainer===this.containers[g])return;r?this._rearrange(s,r,null,!0):this._rearrange(s,null,this.containers[g].element,!0),this._trigger("change",s,this._uiHash()),this.containers[g]._trigger("change",s,this._uiHash(this)),this.currentContainer=this.containers[g],this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[g]._trigger("over",s,this._uiHash(this)),this.containers[g].containerCache.over=1}},_createHelper:function(e){var i=this.options,s=t.isFunction(i.helper)?t(i.helper.apply(this.element[0],[e,this.currentItem])):"clone"===i.helper?this.currentItem.clone():this.currentItem;return s.parents("body").length||t("parent"!==i.appendTo?i.appendTo:this.currentItem[0].parentNode)[0].appendChild(s[0]),s[0]===this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),(!s[0].style.width||i.forceHelperSize)&&s.width(this.currentItem.width()),(!s[0].style.height||i.forceHelperSize)&&s.height(this.currentItem.height()),s},_adjustOffsetFromHelper:function(e){"string"==typeof e&&(e=e.split(" ")),t.isArray(e)&&(e={left:+e[0],top:+e[1]||0}),"left"in e&&(this.offset.click.left=e.left+this.margins.left),"right"in e&&(this.offset.click.left=this.helperProportions.width-e.right+this.margins.left),"top"in e&&(this.offset.click.top=e.top+this.margins.top),"bottom"in e&&(this.offset.click.top=this.helperProportions.height-e.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var e=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])&&(e.left+=this.scrollParent.scrollLeft(),e.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===document.body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&t.ui.ie)&&(e={top:0,left:0}),{top:e.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:e.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"===this.cssPosition){var t=this.currentItem.position();return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:t.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e,i,s,n=this.options;"parent"===n.containment&&(n.containment=this.helper[0].parentNode),("document"===n.containment||"window"===n.containment)&&(this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,t("document"===n.containment?document:window).width()-this.helperProportions.width-this.margins.left,(t("document"===n.containment?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]),/^(document|window|parent)$/.test(n.containment)||(e=t(n.containment)[0],i=t(n.containment).offset(),s="hidden"!==t(e).css("overflow"),this.containment=[i.left+(parseInt(t(e).css("borderLeftWidth"),10)||0)+(parseInt(t(e).css("paddingLeft"),10)||0)-this.margins.left,i.top+(parseInt(t(e).css("borderTopWidth"),10)||0)+(parseInt(t(e).css("paddingTop"),10)||0)-this.margins.top,i.left+(s?Math.max(e.scrollWidth,e.offsetWidth):e.offsetWidth)-(parseInt(t(e).css("borderLeftWidth"),10)||0)-(parseInt(t(e).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,i.top+(s?Math.max(e.scrollHeight,e.offsetHeight):e.offsetHeight)-(parseInt(t(e).css("borderTopWidth"),10)||0)-(parseInt(t(e).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top])},_convertPositionTo:function(e,i){i||(i=this.position);var s="absolute"===e?1:-1,n="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,o=/(html|body)/i.test(n[0].tagName);return{top:i.top+this.offset.relative.top*s+this.offset.parent.top*s-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():o?0:n.scrollTop())*s,left:i.left+this.offset.relative.left*s+this.offset.parent.left*s-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():o?0:n.scrollLeft())*s}},_generatePosition:function(e){var i,s,n=this.options,o=e.pageX,a=e.pageY,r="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,h=/(html|body)/i.test(r[0].tagName);return"relative"!==this.cssPosition||this.scrollParent[0]!==document&&this.scrollParent[0]!==this.offsetParent[0]||(this.offset.relative=this._getRelativeOffset()),this.originalPosition&&(this.containment&&(e.pageX-this.offset.click.leftthis.containment[2]&&(o=this.containment[2]+this.offset.click.left),e.pageY-this.offset.click.top>this.containment[3]&&(a=this.containment[3]+this.offset.click.top)),n.grid&&(i=this.originalPageY+Math.round((a-this.originalPageY)/n.grid[1])*n.grid[1],a=this.containment?i-this.offset.click.top>=this.containment[1]&&i-this.offset.click.top<=this.containment[3]?i:i-this.offset.click.top>=this.containment[1]?i-n.grid[1]:i+n.grid[1]:i,s=this.originalPageX+Math.round((o-this.originalPageX)/n.grid[0])*n.grid[0],o=this.containment?s-this.offset.click.left>=this.containment[0]&&s-this.offset.click.left<=this.containment[2]?s:s-this.offset.click.left>=this.containment[0]?s-n.grid[0]:s+n.grid[0]:s)),{top:a-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():h?0:r.scrollTop()),left:o-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():h?0:r.scrollLeft())}},_rearrange:function(t,e,i,s){i?i[0].appendChild(this.placeholder[0]):e.item[0].parentNode.insertBefore(this.placeholder[0],"down"===this.direction?e.item[0]:e.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var n=this.counter;this._delay(function(){n===this.counter&&this.refreshPositions(!s)})},_clear:function(t,e){function i(t,e,i){return function(s){i._trigger(t,s,e._uiHash(e))}}this.reverting=!1;var s,n=[];if(!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null,this.helper[0]===this.currentItem[0]){for(s in this._storedCSS)("auto"===this._storedCSS[s]||"static"===this._storedCSS[s])&&(this._storedCSS[s]="");this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();for(this.fromOutside&&!e&&n.push(function(t){this._trigger("receive",t,this._uiHash(this.fromOutside))}),!this.fromOutside&&this.domPosition.prev===this.currentItem.prev().not(".ui-sortable-helper")[0]&&this.domPosition.parent===this.currentItem.parent()[0]||e||n.push(function(t){this._trigger("update",t,this._uiHash())}),this!==this.currentContainer&&(e||(n.push(function(t){this._trigger("remove",t,this._uiHash())}),n.push(function(t){return function(e){t._trigger("receive",e,this._uiHash(this))}}.call(this,this.currentContainer)),n.push(function(t){return function(e){t._trigger("update",e,this._uiHash(this))}}.call(this,this.currentContainer)))),s=this.containers.length-1;s>=0;s--)e||n.push(i("deactivate",this,this.containers[s])),this.containers[s].containerCache.over&&(n.push(i("out",this,this.containers[s])),this.containers[s].containerCache.over=0);if(this.storedCursor&&(this.document.find("body").css("cursor",this.storedCursor),this.storedStylesheet.remove()),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex","auto"===this._storedZIndex?"":this._storedZIndex),this.dragging=!1,this.cancelHelperRemoval){if(!e){for(this._trigger("beforeStop",t,this._uiHash()),s=0;n.length>s;s++)n[s].call(this,t);this._trigger("stop",t,this._uiHash())}return this.fromOutside=!1,!1}if(e||this._trigger("beforeStop",t,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.helper[0]!==this.currentItem[0]&&this.helper.remove(),this.helper=null,!e){for(s=0;n.length>s;s++)n[s].call(this,t);this._trigger("stop",t,this._uiHash())}return this.fromOutside=!1,!0},_trigger:function(){t.Widget.prototype._trigger.apply(this,arguments)===!1&&this.cancel()},_uiHash:function(e){var i=e||this;return{helper:i.helper,placeholder:i.placeholder||t([]),position:i.position,originalPosition:i.originalPosition,offset:i.positionAbs,item:i.currentItem,sender:e?e.element:null}}})})(jQuery);(function(e){var t,i="ui-button ui-widget ui-state-default ui-corner-all",n="ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",s=function(){var t=e(this);setTimeout(function(){t.find(":ui-button").button("refresh")},1)},a=function(t){var i=t.name,n=t.form,s=e([]);return i&&(i=i.replace(/'/g,"\\'"),s=n?e(n).find("[name='"+i+"']"):e("[name='"+i+"']",t.ownerDocument).filter(function(){return!this.form})),s};e.widget("ui.button",{version:"1.10.4",defaultElement:"").button({label:this.options.closeText,icons:{primary:"ui-icon-closethick"},text:!1}).addClass("ui-dialog-titlebar-close").appendTo(this.uiDialogTitlebar),this._on(this.uiDialogTitlebarClose,{click:function(e){e.preventDefault(),this.close(e)}}),t=e("").uniqueId().addClass("ui-dialog-title").prependTo(this.uiDialogTitlebar),this._title(t),this.uiDialog.attr({"aria-labelledby":t.attr("id")})},_title:function(e){this.options.title||e.html(" "),e.text(this.options.title)},_createButtonPane:function(){this.uiDialogButtonPane=e("
").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),this.uiButtonSet=e("
").addClass("ui-dialog-buttonset").appendTo(this.uiDialogButtonPane),this._createButtons()},_createButtons:function(){var t=this,i=this.options.buttons;return this.uiDialogButtonPane.remove(),this.uiButtonSet.empty(),e.isEmptyObject(i)||e.isArray(i)&&!i.length?(this.uiDialog.removeClass("ui-dialog-buttons"),undefined):(e.each(i,function(i,a){var s,n;a=e.isFunction(a)?{click:a,text:i}:a,a=e.extend({type:"button"},a),s=a.click,a.click=function(){s.apply(t.element[0],arguments)},n={icons:a.icons,text:a.showText},delete a.icons,delete a.showText,e("",a).button(n).appendTo(t.uiButtonSet)}),this.uiDialog.addClass("ui-dialog-buttons"),this.uiDialogButtonPane.appendTo(this.uiDialog),undefined)},_makeDraggable:function(){function t(e){return{position:e.position,offset:e.offset}}var i=this,a=this.options;this.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(a,s){e(this).addClass("ui-dialog-dragging"),i._blockFrames(),i._trigger("dragStart",a,t(s))},drag:function(e,a){i._trigger("drag",e,t(a))},stop:function(s,n){a.position=[n.position.left-i.document.scrollLeft(),n.position.top-i.document.scrollTop()],e(this).removeClass("ui-dialog-dragging"),i._unblockFrames(),i._trigger("dragStop",s,t(n))}})},_makeResizable:function(){function t(e){return{originalPosition:e.originalPosition,originalSize:e.originalSize,position:e.position,size:e.size}}var i=this,a=this.options,s=a.resizable,n=this.uiDialog.css("position"),r="string"==typeof s?s:"n,e,s,w,se,sw,ne,nw";this.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:this.element,maxWidth:a.maxWidth,maxHeight:a.maxHeight,minWidth:a.minWidth,minHeight:this._minHeight(),handles:r,start:function(a,s){e(this).addClass("ui-dialog-resizing"),i._blockFrames(),i._trigger("resizeStart",a,t(s))},resize:function(e,a){i._trigger("resize",e,t(a))},stop:function(s,n){a.height=e(this).height(),a.width=e(this).width(),e(this).removeClass("ui-dialog-resizing"),i._unblockFrames(),i._trigger("resizeStop",s,t(n))}}).css("position",n)},_minHeight:function(){var e=this.options;return"auto"===e.height?e.minHeight:Math.min(e.minHeight,e.height)},_position:function(){var e=this.uiDialog.is(":visible");e||this.uiDialog.show(),this.uiDialog.position(this.options.position),e||this.uiDialog.hide()},_setOptions:function(a){var s=this,n=!1,r={};e.each(a,function(e,a){s._setOption(e,a),e in t&&(n=!0),e in i&&(r[e]=a)}),n&&(this._size(),this._position()),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option",r)},_setOption:function(e,t){var i,a,s=this.uiDialog;"dialogClass"===e&&s.removeClass(this.options.dialogClass).addClass(t),"disabled"!==e&&(this._super(e,t),"appendTo"===e&&this.uiDialog.appendTo(this._appendTo()),"buttons"===e&&this._createButtons(),"closeText"===e&&this.uiDialogTitlebarClose.button({label:""+t}),"draggable"===e&&(i=s.is(":data(ui-draggable)"),i&&!t&&s.draggable("destroy"),!i&&t&&this._makeDraggable()),"position"===e&&this._position(),"resizable"===e&&(a=s.is(":data(ui-resizable)"),a&&!t&&s.resizable("destroy"),a&&"string"==typeof t&&s.resizable("option","handles",t),a||t===!1||this._makeResizable()),"title"===e&&this._title(this.uiDialogTitlebar.find(".ui-dialog-title")))},_size:function(){var e,t,i,a=this.options;this.element.show().css({width:"auto",minHeight:0,maxHeight:"none",height:0}),a.minWidth>a.width&&(a.width=a.minWidth),e=this.uiDialog.css({height:"auto",width:a.width}).outerHeight(),t=Math.max(0,a.minHeight-e),i="number"==typeof a.maxHeight?Math.max(0,a.maxHeight-e):"none","auto"===a.height?this.element.css({minHeight:t,maxHeight:i,height:"auto"}):this.element.height(Math.max(0,a.height-e)),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())},_blockFrames:function(){this.iframeBlocks=this.document.find("iframe").map(function(){var t=e(this);return e("
").css({position:"absolute",width:t.outerWidth(),height:t.outerHeight()}).appendTo(t.parent()).offset(t.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_allowInteraction:function(t){return e(t.target).closest(".ui-dialog").length?!0:!!e(t.target).closest(".ui-datepicker").length},_createOverlay:function(){if(this.options.modal){var t=this,i=this.widgetFullName;e.ui.dialog.overlayInstances||this._delay(function(){e.ui.dialog.overlayInstances&&this.document.bind("focusin.dialog",function(a){t._allowInteraction(a)||(a.preventDefault(),e(".ui-dialog:visible:last .ui-dialog-content").data(i)._focusTabbable())})}),this.overlay=e("
").addClass("ui-widget-overlay ui-front").appendTo(this._appendTo()),this._on(this.overlay,{mousedown:"_keepFocus"}),e.ui.dialog.overlayInstances++}},_destroyOverlay:function(){this.options.modal&&this.overlay&&(e.ui.dialog.overlayInstances--,e.ui.dialog.overlayInstances||this.document.unbind("focusin.dialog"),this.overlay.remove(),this.overlay=null)}}),e.ui.dialog.overlayInstances=0,e.uiBackCompat!==!1&&e.widget("ui.dialog",e.ui.dialog,{_position:function(){var t,i=this.options.position,a=[],s=[0,0];i?(("string"==typeof i||"object"==typeof i&&"0"in i)&&(a=i.split?i.split(" "):[i[0],i[1]],1===a.length&&(a[1]=a[0]),e.each(["left","top"],function(e,t){+a[e]===a[e]&&(s[e]=a[e],a[e]=t)}),i={my:a[0]+(0>s[0]?s[0]:"+"+s[0])+" "+a[1]+(0>s[1]?s[1]:"+"+s[1]),at:a.join(" ")}),i=e.extend({},e.ui.dialog.prototype.options.position,i)):i=e.ui.dialog.prototype.options.position,t=this.uiDialog.is(":visible"),t||this.uiDialog.show(),this.uiDialog.position(i),t||this.uiDialog.hide()}})})(jQuery);(function(t){function e(e,i){var s=(e.attr("aria-describedby")||"").split(/\s+/);s.push(i),e.data("ui-tooltip-id",i).attr("aria-describedby",t.trim(s.join(" ")))}function i(e){var i=e.data("ui-tooltip-id"),s=(e.attr("aria-describedby")||"").split(/\s+/),n=t.inArray(i,s);-1!==n&&s.splice(n,1),e.removeData("ui-tooltip-id"),s=t.trim(s.join(" ")),s?e.attr("aria-describedby",s):e.removeAttr("aria-describedby")}var s=0;t.widget("ui.tooltip",{version:"1.10.4",options:{content:function(){var e=t(this).attr("title")||"";return t("").text(e).html()},hide:!0,items:"[title]:not([disabled])",position:{my:"left top+15",at:"left bottom",collision:"flipfit flip"},show:!0,tooltipClass:null,track:!1,close:null,open:null},_create:function(){this._on({mouseover:"open",focusin:"open"}),this.tooltips={},this.parents={},this.options.disabled&&this._disable()},_setOption:function(e,i){var s=this;return"disabled"===e?(this[i?"_disable":"_enable"](),this.options[e]=i,void 0):(this._super(e,i),"content"===e&&t.each(this.tooltips,function(t,e){s._updateContent(e)}),void 0)},_disable:function(){var e=this;t.each(this.tooltips,function(i,s){var n=t.Event("blur");n.target=n.currentTarget=s[0],e.close(n,!0)}),this.element.find(this.options.items).addBack().each(function(){var e=t(this);e.is("[title]")&&e.data("ui-tooltip-title",e.attr("title")).attr("title","")})},_enable:function(){this.element.find(this.options.items).addBack().each(function(){var e=t(this);e.data("ui-tooltip-title")&&e.attr("title",e.data("ui-tooltip-title"))})},open:function(e){var i=this,s=t(e?e.target:this.element).closest(this.options.items);s.length&&!s.data("ui-tooltip-id")&&(s.attr("title")&&s.data("ui-tooltip-title",s.attr("title")),s.data("ui-tooltip-open",!0),e&&"mouseover"===e.type&&s.parents().each(function(){var e,s=t(this);s.data("ui-tooltip-open")&&(e=t.Event("blur"),e.target=e.currentTarget=this,i.close(e,!0)),s.attr("title")&&(s.uniqueId(),i.parents[this.id]={element:this,title:s.attr("title")},s.attr("title",""))}),this._updateContent(s,e))},_updateContent:function(t,e){var i,s=this.options.content,n=this,o=e?e.type:null;return"string"==typeof s?this._open(e,t,s):(i=s.call(t[0],function(i){t.data("ui-tooltip-open")&&n._delay(function(){e&&(e.type=o),this._open(e,t,i)})}),i&&this._open(e,t,i),void 0)},_open:function(i,s,n){function o(t){l.of=t,a.is(":hidden")||a.position(l)}var a,r,h,l=t.extend({},this.options.position);if(n){if(a=this._find(s),a.length)return a.find(".ui-tooltip-content").html(n),void 0;s.is("[title]")&&(i&&"mouseover"===i.type?s.attr("title",""):s.removeAttr("title")),a=this._tooltip(s),e(s,a.attr("id")),a.find(".ui-tooltip-content").html(n),this.options.track&&i&&/^mouse/.test(i.type)?(this._on(this.document,{mousemove:o}),o(i)):a.position(t.extend({of:s},this.options.position)),a.hide(),this._show(a,this.options.show),this.options.show&&this.options.show.delay&&(h=this.delayedShow=setInterval(function(){a.is(":visible")&&(o(l.of),clearInterval(h))},t.fx.interval)),this._trigger("open",i,{tooltip:a}),r={keyup:function(e){if(e.keyCode===t.ui.keyCode.ESCAPE){var i=t.Event(e);i.currentTarget=s[0],this.close(i,!0)}},remove:function(){this._removeTooltip(a)}},i&&"mouseover"!==i.type||(r.mouseleave="close"),i&&"focusin"!==i.type||(r.focusout="close"),this._on(!0,s,r)}},close:function(e){var s=this,n=t(e?e.currentTarget:this.element),o=this._find(n);this.closing||(clearInterval(this.delayedShow),n.data("ui-tooltip-title")&&n.attr("title",n.data("ui-tooltip-title")),i(n),o.stop(!0),this._hide(o,this.options.hide,function(){s._removeTooltip(t(this))}),n.removeData("ui-tooltip-open"),this._off(n,"mouseleave focusout keyup"),n[0]!==this.element[0]&&this._off(n,"remove"),this._off(this.document,"mousemove"),e&&"mouseleave"===e.type&&t.each(this.parents,function(e,i){t(i.element).attr("title",i.title),delete s.parents[e]}),this.closing=!0,this._trigger("close",e,{tooltip:o}),this.closing=!1)},_tooltip:function(e){var i="ui-tooltip-"+s++,n=t("
").attr({id:i,role:"tooltip"}).addClass("ui-tooltip ui-widget ui-corner-all ui-widget-content "+(this.options.tooltipClass||""));return t("
").addClass("ui-tooltip-content").appendTo(n),n.appendTo(this.document[0].body),this.tooltips[i]=e,n},_find:function(e){var i=e.data("ui-tooltip-id");return i?t("#"+i):t()},_removeTooltip:function(t){t.remove(),delete this.tooltips[t.attr("id")]},_destroy:function(){var e=this;t.each(this.tooltips,function(i,s){var n=t.Event("blur");n.target=n.currentTarget=s[0],e.close(n,!0),t("#"+i).remove(),s.data("ui-tooltip-title")&&(s.attr("title",s.data("ui-tooltip-title")),s.removeData("ui-tooltip-title"))})}})})(jQuery);(function(t,e){var i="ui-effects-";t.effects={effect:{}},function(t,e){function i(t,e,i){var s=u[e.type]||{};return null==t?i||!e.def?null:e.def:(t=s.floor?~~t:parseFloat(t),isNaN(t)?e.def:s.mod?(t+s.mod)%s.mod:0>t?0:t>s.max?s.max:t)}function s(i){var s=h(),n=s._rgba=[];return i=i.toLowerCase(),f(l,function(t,a){var o,r=a.re.exec(i),l=r&&a.parse(r),h=a.space||"rgba";return l?(o=s[h](l),s[c[h].cache]=o[c[h].cache],n=s._rgba=o._rgba,!1):e}),n.length?("0,0,0,0"===n.join()&&t.extend(n,a.transparent),s):a[i]}function n(t,e,i){return i=(i+1)%1,1>6*i?t+6*(e-t)*i:1>2*i?e:2>3*i?t+6*(e-t)*(2/3-i):t}var a,o="backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",r=/^([\-+])=\s*(\d+\.?\d*)/,l=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[t[1],t[2],t[3],t[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[2.55*t[1],2.55*t[2],2.55*t[3],t[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,parse:function(t){return[parseInt(t[1],16),parseInt(t[2],16),parseInt(t[3],16)]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])/,parse:function(t){return[parseInt(t[1]+t[1],16),parseInt(t[2]+t[2],16),parseInt(t[3]+t[3],16)]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(t){return[t[1],t[2]/100,t[3]/100,t[4]]}}],h=t.Color=function(e,i,s,n){return new t.Color.fn.parse(e,i,s,n)},c={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},u={"byte":{floor:!0,max:255},percent:{max:1},degrees:{mod:360,floor:!0}},d=h.support={},p=t("

")[0],f=t.each;p.style.cssText="background-color:rgba(1,1,1,.5)",d.rgba=p.style.backgroundColor.indexOf("rgba")>-1,f(c,function(t,e){e.cache="_"+t,e.props.alpha={idx:3,type:"percent",def:1}}),h.fn=t.extend(h.prototype,{parse:function(n,o,r,l){if(n===e)return this._rgba=[null,null,null,null],this;(n.jquery||n.nodeType)&&(n=t(n).css(o),o=e);var u=this,d=t.type(n),p=this._rgba=[];return o!==e&&(n=[n,o,r,l],d="array"),"string"===d?this.parse(s(n)||a._default):"array"===d?(f(c.rgba.props,function(t,e){p[e.idx]=i(n[e.idx],e)}),this):"object"===d?(n instanceof h?f(c,function(t,e){n[e.cache]&&(u[e.cache]=n[e.cache].slice())}):f(c,function(e,s){var a=s.cache;f(s.props,function(t,e){if(!u[a]&&s.to){if("alpha"===t||null==n[t])return;u[a]=s.to(u._rgba)}u[a][e.idx]=i(n[t],e,!0)}),u[a]&&0>t.inArray(null,u[a].slice(0,3))&&(u[a][3]=1,s.from&&(u._rgba=s.from(u[a])))}),this):e},is:function(t){var i=h(t),s=!0,n=this;return f(c,function(t,a){var o,r=i[a.cache];return r&&(o=n[a.cache]||a.to&&a.to(n._rgba)||[],f(a.props,function(t,i){return null!=r[i.idx]?s=r[i.idx]===o[i.idx]:e})),s}),s},_space:function(){var t=[],e=this;return f(c,function(i,s){e[s.cache]&&t.push(i)}),t.pop()},transition:function(t,e){var s=h(t),n=s._space(),a=c[n],o=0===this.alpha()?h("transparent"):this,r=o[a.cache]||a.to(o._rgba),l=r.slice();return s=s[a.cache],f(a.props,function(t,n){var a=n.idx,o=r[a],h=s[a],c=u[n.type]||{};null!==h&&(null===o?l[a]=h:(c.mod&&(h-o>c.mod/2?o+=c.mod:o-h>c.mod/2&&(o-=c.mod)),l[a]=i((h-o)*e+o,n)))}),this[n](l)},blend:function(e){if(1===this._rgba[3])return this;var i=this._rgba.slice(),s=i.pop(),n=h(e)._rgba;return h(t.map(i,function(t,e){return(1-s)*n[e]+s*t}))},toRgbaString:function(){var e="rgba(",i=t.map(this._rgba,function(t,e){return null==t?e>2?1:0:t});return 1===i[3]&&(i.pop(),e="rgb("),e+i.join()+")"},toHslaString:function(){var e="hsla(",i=t.map(this.hsla(),function(t,e){return null==t&&(t=e>2?1:0),e&&3>e&&(t=Math.round(100*t)+"%"),t});return 1===i[3]&&(i.pop(),e="hsl("),e+i.join()+")"},toHexString:function(e){var i=this._rgba.slice(),s=i.pop();return e&&i.push(~~(255*s)),"#"+t.map(i,function(t){return t=(t||0).toString(16),1===t.length?"0"+t:t}).join("")},toString:function(){return 0===this._rgba[3]?"transparent":this.toRgbaString()}}),h.fn.parse.prototype=h.fn,c.hsla.to=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e,i,s=t[0]/255,n=t[1]/255,a=t[2]/255,o=t[3],r=Math.max(s,n,a),l=Math.min(s,n,a),h=r-l,c=r+l,u=.5*c;return e=l===r?0:s===r?60*(n-a)/h+360:n===r?60*(a-s)/h+120:60*(s-n)/h+240,i=0===h?0:.5>=u?h/c:h/(2-c),[Math.round(e)%360,i,u,null==o?1:o]},c.hsla.from=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e=t[0]/360,i=t[1],s=t[2],a=t[3],o=.5>=s?s*(1+i):s+i-s*i,r=2*s-o;return[Math.round(255*n(r,o,e+1/3)),Math.round(255*n(r,o,e)),Math.round(255*n(r,o,e-1/3)),a]},f(c,function(s,n){var a=n.props,o=n.cache,l=n.to,c=n.from;h.fn[s]=function(s){if(l&&!this[o]&&(this[o]=l(this._rgba)),s===e)return this[o].slice();var n,r=t.type(s),u="array"===r||"object"===r?s:arguments,d=this[o].slice();return f(a,function(t,e){var s=u["object"===r?t:e.idx];null==s&&(s=d[e.idx]),d[e.idx]=i(s,e)}),c?(n=h(c(d)),n[o]=d,n):h(d)},f(a,function(e,i){h.fn[e]||(h.fn[e]=function(n){var a,o=t.type(n),l="alpha"===e?this._hsla?"hsla":"rgba":s,h=this[l](),c=h[i.idx];return"undefined"===o?c:("function"===o&&(n=n.call(this,c),o=t.type(n)),null==n&&i.empty?this:("string"===o&&(a=r.exec(n),a&&(n=c+parseFloat(a[2])*("+"===a[1]?1:-1))),h[i.idx]=n,this[l](h)))})})}),h.hook=function(e){var i=e.split(" ");f(i,function(e,i){t.cssHooks[i]={set:function(e,n){var a,o,r="";if("transparent"!==n&&("string"!==t.type(n)||(a=s(n)))){if(n=h(a||n),!d.rgba&&1!==n._rgba[3]){for(o="backgroundColor"===i?e.parentNode:e;(""===r||"transparent"===r)&&o&&o.style;)try{r=t.css(o,"backgroundColor"),o=o.parentNode}catch(l){}n=n.blend(r&&"transparent"!==r?r:"_default")}n=n.toRgbaString()}try{e.style[i]=n}catch(l){}}},t.fx.step[i]=function(e){e.colorInit||(e.start=h(e.elem,i),e.end=h(e.end),e.colorInit=!0),t.cssHooks[i].set(e.elem,e.start.transition(e.end,e.pos))}})},h.hook(o),t.cssHooks.borderColor={expand:function(t){var e={};return f(["Top","Right","Bottom","Left"],function(i,s){e["border"+s+"Color"]=t}),e}},a=t.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}}(jQuery),function(){function i(e){var i,s,n=e.ownerDocument.defaultView?e.ownerDocument.defaultView.getComputedStyle(e,null):e.currentStyle,a={};if(n&&n.length&&n[0]&&n[n[0]])for(s=n.length;s--;)i=n[s],"string"==typeof n[i]&&(a[t.camelCase(i)]=n[i]);else for(i in n)"string"==typeof n[i]&&(a[i]=n[i]);return a}function s(e,i){var s,n,o={};for(s in i)n=i[s],e[s]!==n&&(a[s]||(t.fx.step[s]||!isNaN(parseFloat(n)))&&(o[s]=n));return o}var n=["add","remove","toggle"],a={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};t.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(e,i){t.fx.step[i]=function(t){("none"!==t.end&&!t.setAttr||1===t.pos&&!t.setAttr)&&(jQuery.style(t.elem,i,t.end),t.setAttr=!0)}}),t.fn.addBack||(t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t.effects.animateClass=function(e,a,o,r){var l=t.speed(a,o,r);return this.queue(function(){var a,o=t(this),r=o.attr("class")||"",h=l.children?o.find("*").addBack():o;h=h.map(function(){var e=t(this);return{el:e,start:i(this)}}),a=function(){t.each(n,function(t,i){e[i]&&o[i+"Class"](e[i])})},a(),h=h.map(function(){return this.end=i(this.el[0]),this.diff=s(this.start,this.end),this}),o.attr("class",r),h=h.map(function(){var e=this,i=t.Deferred(),s=t.extend({},l,{queue:!1,complete:function(){i.resolve(e)}});return this.el.animate(this.diff,s),i.promise()}),t.when.apply(t,h.get()).done(function(){a(),t.each(arguments,function(){var e=this.el;t.each(this.diff,function(t){e.css(t,"")})}),l.complete.call(o[0])})})},t.fn.extend({addClass:function(e){return function(i,s,n,a){return s?t.effects.animateClass.call(this,{add:i},s,n,a):e.apply(this,arguments)}}(t.fn.addClass),removeClass:function(e){return function(i,s,n,a){return arguments.length>1?t.effects.animateClass.call(this,{remove:i},s,n,a):e.apply(this,arguments)}}(t.fn.removeClass),toggleClass:function(i){return function(s,n,a,o,r){return"boolean"==typeof n||n===e?a?t.effects.animateClass.call(this,n?{add:s}:{remove:s},a,o,r):i.apply(this,arguments):t.effects.animateClass.call(this,{toggle:s},n,a,o)}}(t.fn.toggleClass),switchClass:function(e,i,s,n,a){return t.effects.animateClass.call(this,{add:i,remove:e},s,n,a)}})}(),function(){function s(e,i,s,n){return t.isPlainObject(e)&&(i=e,e=e.effect),e={effect:e},null==i&&(i={}),t.isFunction(i)&&(n=i,s=null,i={}),("number"==typeof i||t.fx.speeds[i])&&(n=s,s=i,i={}),t.isFunction(s)&&(n=s,s=null),i&&t.extend(e,i),s=s||i.duration,e.duration=t.fx.off?0:"number"==typeof s?s:s in t.fx.speeds?t.fx.speeds[s]:t.fx.speeds._default,e.complete=n||i.complete,e}function n(e){return!e||"number"==typeof e||t.fx.speeds[e]?!0:"string"!=typeof e||t.effects.effect[e]?t.isFunction(e)?!0:"object"!=typeof e||e.effect?!1:!0:!0}t.extend(t.effects,{version:"1.10.4",save:function(t,e){for(var s=0;e.length>s;s++)null!==e[s]&&t.data(i+e[s],t[0].style[e[s]])},restore:function(t,s){var n,a;for(a=0;s.length>a;a++)null!==s[a]&&(n=t.data(i+s[a]),n===e&&(n=""),t.css(s[a],n))},setMode:function(t,e){return"toggle"===e&&(e=t.is(":hidden")?"show":"hide"),e},getBaseline:function(t,e){var i,s;switch(t[0]){case"top":i=0;break;case"middle":i=.5;break;case"bottom":i=1;break;default:i=t[0]/e.height}switch(t[1]){case"left":s=0;break;case"center":s=.5;break;case"right":s=1;break;default:s=t[1]/e.width}return{x:s,y:i}},createWrapper:function(e){if(e.parent().is(".ui-effects-wrapper"))return e.parent();var i={width:e.outerWidth(!0),height:e.outerHeight(!0),"float":e.css("float")},s=t("

").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),n={width:e.width(),height:e.height()},a=document.activeElement;try{a.id}catch(o){a=document.body}return e.wrap(s),(e[0]===a||t.contains(e[0],a))&&t(a).focus(),s=e.parent(),"static"===e.css("position")?(s.css({position:"relative"}),e.css({position:"relative"})):(t.extend(i,{position:e.css("position"),zIndex:e.css("z-index")}),t.each(["top","left","bottom","right"],function(t,s){i[s]=e.css(s),isNaN(parseInt(i[s],10))&&(i[s]="auto")}),e.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),e.css(n),s.css(i).show()},removeWrapper:function(e){var i=document.activeElement;return e.parent().is(".ui-effects-wrapper")&&(e.parent().replaceWith(e),(e[0]===i||t.contains(e[0],i))&&t(i).focus()),e},setTransition:function(e,i,s,n){return n=n||{},t.each(i,function(t,i){var a=e.cssUnit(i);a[0]>0&&(n[i]=a[0]*s+a[1])}),n}}),t.fn.extend({effect:function(){function e(e){function s(){t.isFunction(a)&&a.call(n[0]),t.isFunction(e)&&e()}var n=t(this),a=i.complete,r=i.mode;(n.is(":hidden")?"hide"===r:"show"===r)?(n[r](),s()):o.call(n[0],i,s)}var i=s.apply(this,arguments),n=i.mode,a=i.queue,o=t.effects.effect[i.effect];return t.fx.off||!o?n?this[n](i.duration,i.complete):this.each(function(){i.complete&&i.complete.call(this)}):a===!1?this.each(e):this.queue(a||"fx",e)},show:function(t){return function(e){if(n(e))return t.apply(this,arguments);var i=s.apply(this,arguments);return i.mode="show",this.effect.call(this,i)}}(t.fn.show),hide:function(t){return function(e){if(n(e))return t.apply(this,arguments);var i=s.apply(this,arguments);return i.mode="hide",this.effect.call(this,i)}}(t.fn.hide),toggle:function(t){return function(e){if(n(e)||"boolean"==typeof e)return t.apply(this,arguments);var i=s.apply(this,arguments);return i.mode="toggle",this.effect.call(this,i)}}(t.fn.toggle),cssUnit:function(e){var i=this.css(e),s=[];return t.each(["em","px","%","pt"],function(t,e){i.indexOf(e)>0&&(s=[parseFloat(i),e])}),s}})}(),function(){var e={};t.each(["Quad","Cubic","Quart","Quint","Expo"],function(t,i){e[i]=function(e){return Math.pow(e,t+2)}}),t.extend(e,{Sine:function(t){return 1-Math.cos(t*Math.PI/2)},Circ:function(t){return 1-Math.sqrt(1-t*t)},Elastic:function(t){return 0===t||1===t?t:-Math.pow(2,8*(t-1))*Math.sin((80*(t-1)-7.5)*Math.PI/15)},Back:function(t){return t*t*(3*t-2)},Bounce:function(t){for(var e,i=4;((e=Math.pow(2,--i))-1)/11>t;);return 1/Math.pow(4,3-i)-7.5625*Math.pow((3*e-2)/22-t,2)}}),t.each(e,function(e,i){t.easing["easeIn"+e]=i,t.easing["easeOut"+e]=function(t){return 1-i(1-t)},t.easing["easeInOut"+e]=function(t){return.5>t?i(2*t)/2:1-i(-2*t+2)/2}})}()})(jQuery);(function(t){t.effects.effect.puff=function(e,i){var s=t(this),n=t.effects.setMode(s,e.mode||"hide"),a="hide"===n,o=parseInt(e.percent,10)||150,r=o/100,l={height:s.height(),width:s.width(),outerHeight:s.outerHeight(),outerWidth:s.outerWidth()};t.extend(e,{effect:"scale",queue:!1,fade:!0,mode:n,complete:i,percent:a?o:100,from:a?l:{height:l.height*r,width:l.width*r,outerHeight:l.outerHeight*r,outerWidth:l.outerWidth*r}}),s.effect(e)},t.effects.effect.scale=function(e,i){var s=t(this),n=t.extend(!0,{},e),a=t.effects.setMode(s,e.mode||"effect"),o=parseInt(e.percent,10)||(0===parseInt(e.percent,10)?0:"hide"===a?0:100),r=e.direction||"both",l=e.origin,h={height:s.height(),width:s.width(),outerHeight:s.outerHeight(),outerWidth:s.outerWidth()},c={y:"horizontal"!==r?o/100:1,x:"vertical"!==r?o/100:1};n.effect="size",n.queue=!1,n.complete=i,"effect"!==a&&(n.origin=l||["middle","center"],n.restore=!0),n.from=e.from||("show"===a?{height:0,width:0,outerHeight:0,outerWidth:0}:h),n.to={height:h.height*c.y,width:h.width*c.x,outerHeight:h.outerHeight*c.y,outerWidth:h.outerWidth*c.x},n.fade&&("show"===a&&(n.from.opacity=0,n.to.opacity=1),"hide"===a&&(n.from.opacity=1,n.to.opacity=0)),s.effect(n)},t.effects.effect.size=function(e,i){var s,n,a,o=t(this),r=["position","top","bottom","left","right","width","height","overflow","opacity"],l=["position","top","bottom","left","right","overflow","opacity"],h=["width","height","overflow"],c=["fontSize"],u=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],d=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],p=t.effects.setMode(o,e.mode||"effect"),f=e.restore||"effect"!==p,g=e.scale||"both",m=e.origin||["middle","center"],v=o.css("position"),_=f?r:l,b={height:0,width:0,outerHeight:0,outerWidth:0};"show"===p&&o.show(),s={height:o.height(),width:o.width(),outerHeight:o.outerHeight(),outerWidth:o.outerWidth()},"toggle"===e.mode&&"show"===p?(o.from=e.to||b,o.to=e.from||s):(o.from=e.from||("show"===p?b:s),o.to=e.to||("hide"===p?b:s)),a={from:{y:o.from.height/s.height,x:o.from.width/s.width},to:{y:o.to.height/s.height,x:o.to.width/s.width}},("box"===g||"both"===g)&&(a.from.y!==a.to.y&&(_=_.concat(u),o.from=t.effects.setTransition(o,u,a.from.y,o.from),o.to=t.effects.setTransition(o,u,a.to.y,o.to)),a.from.x!==a.to.x&&(_=_.concat(d),o.from=t.effects.setTransition(o,d,a.from.x,o.from),o.to=t.effects.setTransition(o,d,a.to.x,o.to))),("content"===g||"both"===g)&&a.from.y!==a.to.y&&(_=_.concat(c).concat(h),o.from=t.effects.setTransition(o,c,a.from.y,o.from),o.to=t.effects.setTransition(o,c,a.to.y,o.to)),t.effects.save(o,_),o.show(),t.effects.createWrapper(o),o.css("overflow","hidden").css(o.from),m&&(n=t.effects.getBaseline(m,s),o.from.top=(s.outerHeight-o.outerHeight())*n.y,o.from.left=(s.outerWidth-o.outerWidth())*n.x,o.to.top=(s.outerHeight-o.to.outerHeight)*n.y,o.to.left=(s.outerWidth-o.to.outerWidth)*n.x),o.css(o.from),("content"===g||"both"===g)&&(u=u.concat(["marginTop","marginBottom"]).concat(c),d=d.concat(["marginLeft","marginRight"]),h=r.concat(u).concat(d),o.find("*[width]").each(function(){var i=t(this),s={height:i.height(),width:i.width(),outerHeight:i.outerHeight(),outerWidth:i.outerWidth()};f&&t.effects.save(i,h),i.from={height:s.height*a.from.y,width:s.width*a.from.x,outerHeight:s.outerHeight*a.from.y,outerWidth:s.outerWidth*a.from.x},i.to={height:s.height*a.to.y,width:s.width*a.to.x,outerHeight:s.height*a.to.y,outerWidth:s.width*a.to.x},a.from.y!==a.to.y&&(i.from=t.effects.setTransition(i,u,a.from.y,i.from),i.to=t.effects.setTransition(i,u,a.to.y,i.to)),a.from.x!==a.to.x&&(i.from=t.effects.setTransition(i,d,a.from.x,i.from),i.to=t.effects.setTransition(i,d,a.to.x,i.to)),i.css(i.from),i.animate(i.to,e.duration,e.easing,function(){f&&t.effects.restore(i,h)})})),o.animate(o.to,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){0===o.to.opacity&&o.css("opacity",o.from.opacity),"hide"===p&&o.hide(),t.effects.restore(o,_),f||("static"===v?o.css({position:"relative",top:o.to.top,left:o.to.left}):t.each(["top","left"],function(t,e){o.css(e,function(e,i){var s=parseInt(i,10),n=t?o.to.left:o.to.top;return"auto"===i?n+"px":s+n+"px"})})),t.effects.removeWrapper(o),i()}})}})(jQuery);(function(t){t.effects.effect.slide=function(e,i){var s,n=t(this),a=["position","top","bottom","left","right","width","height"],o=t.effects.setMode(n,e.mode||"show"),r="show"===o,l=e.direction||"left",h="up"===l||"down"===l?"top":"left",c="up"===l||"left"===l,u={};t.effects.save(n,a),n.show(),s=e.distance||n["top"===h?"outerHeight":"outerWidth"](!0),t.effects.createWrapper(n).css({overflow:"hidden"}),r&&n.css(h,c?isNaN(s)?"-"+s:-s:s),u[h]=(r?c?"+=":"-=":c?"-=":"+=")+s,n.animate(u,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){"hide"===o&&n.hide(),t.effects.restore(n,a),t.effects.removeWrapper(n),i()}})}})(jQuery); \ No newline at end of file +(function(t){"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)})(function(t){function e(t){for(var e=t.css("visibility");"inherit"===e;)t=t.parent(),e=t.css("visibility");return"hidden"!==e}function i(t){for(var e,i;t.length&&t[0]!==document;){if(e=t.css("position"),("absolute"===e||"relative"===e||"fixed"===e)&&(i=parseInt(t.css("zIndex"),10),!isNaN(i)&&0!==i))return i;t=t.parent()}return 0}function s(){this._curInst=null,this._keyEvent=!1,this._disabledInputs=[],this._datepickerShowing=!1,this._inDialog=!1,this._mainDivId="ui-datepicker-div",this._inlineClass="ui-datepicker-inline",this._appendClass="ui-datepicker-append",this._triggerClass="ui-datepicker-trigger",this._dialogClass="ui-datepicker-dialog",this._disableClass="ui-datepicker-disabled",this._unselectableClass="ui-datepicker-unselectable",this._currentClass="ui-datepicker-current-day",this._dayOverClass="ui-datepicker-days-cell-over",this.regional=[],this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:!1,hideIfNoPrevNext:!1,navigationAsDateFormat:!1,gotoCurrent:!1,changeMonth:!1,changeYear:!1,yearRange:"c-10:c+10",showOtherMonths:!1,selectOtherMonths:!1,showWeek:!1,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:!0,showButtonPanel:!1,autoSize:!1,disabled:!1},t.extend(this._defaults,this.regional[""]),this.regional.en=t.extend(!0,{},this.regional[""]),this.regional["en-US"]=t.extend(!0,{},this.regional.en),this.dpDiv=n(t("
"))}function n(e){var i="button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";return e.on("mouseout",i,function(){t(this).removeClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&t(this).removeClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&t(this).removeClass("ui-datepicker-next-hover")}).on("mouseover",i,o)}function o(){t.datepicker._isDisabledDatepicker(p.inline?p.dpDiv.parent()[0]:p.input[0])||(t(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"),t(this).addClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&t(this).addClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&t(this).addClass("ui-datepicker-next-hover"))}function a(e,i){t.extend(e,i);for(var s in i)null==i[s]&&(e[s]=i[s]);return e}function r(t){return function(){var e=this.element.val();t.apply(this,arguments),this._refresh(),e!==this.element.val()&&this._trigger("change")}}t.ui=t.ui||{},t.ui.version="1.12.1";var h=0,l=Array.prototype.slice;t.cleanData=function(e){return function(i){var s,n,o;for(o=0;null!=(n=i[o]);o++)try{s=t._data(n,"events"),s&&s.remove&&t(n).triggerHandler("remove")}catch(a){}e(i)}}(t.cleanData),t.widget=function(e,i,s){var n,o,a,r={},h=e.split(".")[0];e=e.split(".")[1];var l=h+"-"+e;return s||(s=i,i=t.Widget),t.isArray(s)&&(s=t.extend.apply(null,[{}].concat(s))),t.expr[":"][l.toLowerCase()]=function(e){return!!t.data(e,l)},t[h]=t[h]||{},n=t[h][e],o=t[h][e]=function(t,e){return this._createWidget?(arguments.length&&this._createWidget(t,e),void 0):new o(t,e)},t.extend(o,n,{version:s.version,_proto:t.extend({},s),_childConstructors:[]}),a=new i,a.options=t.widget.extend({},a.options),t.each(s,function(e,s){return t.isFunction(s)?(r[e]=function(){function t(){return i.prototype[e].apply(this,arguments)}function n(t){return i.prototype[e].apply(this,t)}return function(){var e,i=this._super,o=this._superApply;return this._super=t,this._superApply=n,e=s.apply(this,arguments),this._super=i,this._superApply=o,e}}(),void 0):(r[e]=s,void 0)}),o.prototype=t.widget.extend(a,{widgetEventPrefix:n?a.widgetEventPrefix||e:e},r,{constructor:o,namespace:h,widgetName:e,widgetFullName:l}),n?(t.each(n._childConstructors,function(e,i){var s=i.prototype;t.widget(s.namespace+"."+s.widgetName,o,i._proto)}),delete n._childConstructors):i._childConstructors.push(o),t.widget.bridge(e,o),o},t.widget.extend=function(e){for(var i,s,n=l.call(arguments,1),o=0,a=n.length;a>o;o++)for(i in n[o])s=n[o][i],n[o].hasOwnProperty(i)&&void 0!==s&&(e[i]=t.isPlainObject(s)?t.isPlainObject(e[i])?t.widget.extend({},e[i],s):t.widget.extend({},s):s);return e},t.widget.bridge=function(e,i){var s=i.prototype.widgetFullName||e;t.fn[e]=function(n){var o="string"==typeof n,a=l.call(arguments,1),r=this;return o?this.length||"instance"!==n?this.each(function(){var i,o=t.data(this,s);return"instance"===n?(r=o,!1):o?t.isFunction(o[n])&&"_"!==n.charAt(0)?(i=o[n].apply(o,a),i!==o&&void 0!==i?(r=i&&i.jquery?r.pushStack(i.get()):i,!1):void 0):t.error("no such method '"+n+"' for "+e+" widget instance"):t.error("cannot call methods on "+e+" prior to initialization; "+"attempted to call method '"+n+"'")}):r=void 0:(a.length&&(n=t.widget.extend.apply(null,[n].concat(a))),this.each(function(){var e=t.data(this,s);e?(e.option(n||{}),e._init&&e._init()):t.data(this,s,new i(n,this))})),r}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"
",options:{classes:{},disabled:!1,create:null},_createWidget:function(e,i){i=t(i||this.defaultElement||this)[0],this.element=t(i),this.uuid=h++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=t(),this.hoverable=t(),this.focusable=t(),this.classesElementLookup={},i!==this&&(t.data(i,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===i&&this.destroy()}}),this.document=t(i.style?i.ownerDocument:i.document||i),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this.options=t.widget.extend({},this.options,this._getCreateOptions(),e),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){var e=this;this._destroy(),t.each(this.classesElementLookup,function(t,i){e._removeClass(i,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:t.noop,widget:function(){return this.element},option:function(e,i){var s,n,o,a=e;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof e)if(a={},s=e.split("."),e=s.shift(),s.length){for(n=a[e]=t.widget.extend({},this.options[e]),o=0;s.length-1>o;o++)n[s[o]]=n[s[o]]||{},n=n[s[o]];if(e=s.pop(),1===arguments.length)return void 0===n[e]?null:n[e];n[e]=i}else{if(1===arguments.length)return void 0===this.options[e]?null:this.options[e];a[e]=i}return this._setOptions(a),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return"classes"===t&&this._setOptionClasses(e),this.options[t]=e,"disabled"===t&&this._setOptionDisabled(e),this},_setOptionClasses:function(e){var i,s,n;for(i in e)n=this.classesElementLookup[i],e[i]!==this.options.classes[i]&&n&&n.length&&(s=t(n.get()),this._removeClass(n,i),s.addClass(this._classes({element:s,keys:i,classes:e,add:!0})))},_setOptionDisabled:function(t){this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!!t),t&&(this._removeClass(this.hoverable,null,"ui-state-hover"),this._removeClass(this.focusable,null,"ui-state-focus"))},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_classes:function(e){function i(i,o){var a,r;for(r=0;i.length>r;r++)a=n.classesElementLookup[i[r]]||t(),a=e.add?t(t.unique(a.get().concat(e.element.get()))):t(a.not(e.element).get()),n.classesElementLookup[i[r]]=a,s.push(i[r]),o&&e.classes[i[r]]&&s.push(e.classes[i[r]])}var s=[],n=this;return e=t.extend({element:this.element,classes:this.options.classes||{}},e),this._on(e.element,{remove:"_untrackClassesElement"}),e.keys&&i(e.keys.match(/\S+/g)||[],!0),e.extra&&i(e.extra.match(/\S+/g)||[]),s.join(" ")},_untrackClassesElement:function(e){var i=this;t.each(i.classesElementLookup,function(s,n){-1!==t.inArray(e.target,n)&&(i.classesElementLookup[s]=t(n.not(e.target).get()))})},_removeClass:function(t,e,i){return this._toggleClass(t,e,i,!1)},_addClass:function(t,e,i){return this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,s){s="boolean"==typeof s?s:i;var n="string"==typeof t||null===t,o={extra:n?e:i,keys:n?t:e,element:n?this.element:t,add:s};return o.element.toggleClass(this._classes(o),s),this},_on:function(e,i,s){var n,o=this;"boolean"!=typeof e&&(s=i,i=e,e=!1),s?(i=n=t(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),t.each(s,function(s,a){function r(){return e||o.options.disabled!==!0&&!t(this).hasClass("ui-state-disabled")?("string"==typeof a?o[a]:a).apply(o,arguments):void 0}"string"!=typeof a&&(r.guid=a.guid=a.guid||r.guid||t.guid++);var h=s.match(/^([\w:-]*)\s*(.*)$/),l=h[1]+o.eventNamespace,c=h[2];c?n.on(l,c,r):i.on(l,r)})},_off:function(e,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.off(i).off(i),this.bindings=t(this.bindings.not(e).get()),this.focusable=t(this.focusable.not(e).get()),this.hoverable=t(this.hoverable.not(e).get())},_delay:function(t,e){function i(){return("string"==typeof t?s[t]:t).apply(s,arguments)}var s=this;return setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){this._addClass(t(e.currentTarget),null,"ui-state-hover")},mouseleave:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){this._addClass(t(e.currentTarget),null,"ui-state-focus")},focusout:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-focus")}})},_trigger:function(e,i,s){var n,o,a=this.options[e];if(s=s||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(n in o)n in i||(i[n]=o[n]);return this.element.trigger(i,s),!(t.isFunction(a)&&a.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,n,o){"string"==typeof n&&(n={effect:n});var a,r=n?n===!0||"number"==typeof n?i:n.effect||i:e;n=n||{},"number"==typeof n&&(n={duration:n}),a=!t.isEmptyObject(n),n.complete=o,n.delay&&s.delay(n.delay),a&&t.effects&&t.effects.effect[r]?s[e](n):r!==e&&s[r]?s[r](n.duration,n.easing,o):s.queue(function(i){t(this)[e](),o&&o.call(s[0]),i()})}}),t.widget,function(){function e(t,e,i){return[parseFloat(t[0])*(u.test(t[0])?e/100:1),parseFloat(t[1])*(u.test(t[1])?i/100:1)]}function i(e,i){return parseInt(t.css(e,i),10)||0}function s(e){var i=e[0];return 9===i.nodeType?{width:e.width(),height:e.height(),offset:{top:0,left:0}}:t.isWindow(i)?{width:e.width(),height:e.height(),offset:{top:e.scrollTop(),left:e.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:e.outerWidth(),height:e.outerHeight(),offset:e.offset()}}var n,o=Math.max,a=Math.abs,r=/left|center|right/,h=/top|center|bottom/,l=/[\+\-]\d+(\.[\d]+)?%?/,c=/^\w+/,u=/%$/,d=t.fn.position;t.position={scrollbarWidth:function(){if(void 0!==n)return n;var e,i,s=t("
"),o=s.children()[0];return t("body").append(s),e=o.offsetWidth,s.css("overflow","scroll"),i=o.offsetWidth,e===i&&(i=s[0].clientWidth),s.remove(),n=e-i},getScrollInfo:function(e){var i=e.isWindow||e.isDocument?"":e.element.css("overflow-x"),s=e.isWindow||e.isDocument?"":e.element.css("overflow-y"),n="scroll"===i||"auto"===i&&e.widthi?"left":e>0?"right":"center",vertical:0>r?"top":s>0?"bottom":"middle"};l>p&&p>a(e+i)&&(u.horizontal="center"),c>f&&f>a(s+r)&&(u.vertical="middle"),u.important=o(a(e),a(i))>o(a(s),a(r))?"horizontal":"vertical",n.using.call(this,t,u)}),h.offset(t.extend(D,{using:r}))})},t.ui.position={fit:{left:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollLeft:s.offset.left,a=s.width,r=t.left-e.collisionPosition.marginLeft,h=n-r,l=r+e.collisionWidth-a-n;e.collisionWidth>a?h>0&&0>=l?(i=t.left+h+e.collisionWidth-a-n,t.left+=h-i):t.left=l>0&&0>=h?n:h>l?n+a-e.collisionWidth:n:h>0?t.left+=h:l>0?t.left-=l:t.left=o(t.left-r,t.left)},top:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollTop:s.offset.top,a=e.within.height,r=t.top-e.collisionPosition.marginTop,h=n-r,l=r+e.collisionHeight-a-n;e.collisionHeight>a?h>0&&0>=l?(i=t.top+h+e.collisionHeight-a-n,t.top+=h-i):t.top=l>0&&0>=h?n:h>l?n+a-e.collisionHeight:n:h>0?t.top+=h:l>0?t.top-=l:t.top=o(t.top-r,t.top)}},flip:{left:function(t,e){var i,s,n=e.within,o=n.offset.left+n.scrollLeft,r=n.width,h=n.isWindow?n.scrollLeft:n.offset.left,l=t.left-e.collisionPosition.marginLeft,c=l-h,u=l+e.collisionWidth-r-h,d="left"===e.my[0]?-e.elemWidth:"right"===e.my[0]?e.elemWidth:0,p="left"===e.at[0]?e.targetWidth:"right"===e.at[0]?-e.targetWidth:0,f=-2*e.offset[0];0>c?(i=t.left+d+p+f+e.collisionWidth-r-o,(0>i||a(c)>i)&&(t.left+=d+p+f)):u>0&&(s=t.left-e.collisionPosition.marginLeft+d+p+f-h,(s>0||u>a(s))&&(t.left+=d+p+f))},top:function(t,e){var i,s,n=e.within,o=n.offset.top+n.scrollTop,r=n.height,h=n.isWindow?n.scrollTop:n.offset.top,l=t.top-e.collisionPosition.marginTop,c=l-h,u=l+e.collisionHeight-r-h,d="top"===e.my[1],p=d?-e.elemHeight:"bottom"===e.my[1]?e.elemHeight:0,f="top"===e.at[1]?e.targetHeight:"bottom"===e.at[1]?-e.targetHeight:0,g=-2*e.offset[1];0>c?(s=t.top+p+f+g+e.collisionHeight-r-o,(0>s||a(c)>s)&&(t.top+=p+f+g)):u>0&&(i=t.top-e.collisionPosition.marginTop+p+f+g-h,(i>0||u>a(i))&&(t.top+=p+f+g))}},flipfit:{left:function(){t.ui.position.flip.left.apply(this,arguments),t.ui.position.fit.left.apply(this,arguments)},top:function(){t.ui.position.flip.top.apply(this,arguments),t.ui.position.fit.top.apply(this,arguments)}}}}(),t.ui.position,t.extend(t.expr[":"],{data:t.expr.createPseudo?t.expr.createPseudo(function(e){return function(i){return!!t.data(i,e)}}):function(e,i,s){return!!t.data(e,s[3])}}),t.fn.extend({disableSelection:function(){var t="onselectstart"in document.createElement("div")?"selectstart":"mousedown";return function(){return this.on(t+".ui-disableSelection",function(t){t.preventDefault()})}}(),enableSelection:function(){return this.off(".ui-disableSelection")}}),t.ui.focusable=function(i,s){var n,o,a,r,h,l=i.nodeName.toLowerCase();return"area"===l?(n=i.parentNode,o=n.name,i.href&&o&&"map"===n.nodeName.toLowerCase()?(a=t("img[usemap='#"+o+"']"),a.length>0&&a.is(":visible")):!1):(/^(input|select|textarea|button|object)$/.test(l)?(r=!i.disabled,r&&(h=t(i).closest("fieldset")[0],h&&(r=!h.disabled))):r="a"===l?i.href||s:s,r&&t(i).is(":visible")&&e(t(i)))},t.extend(t.expr[":"],{focusable:function(e){return t.ui.focusable(e,null!=t.attr(e,"tabindex"))}}),t.ui.focusable,t.fn.form=function(){return"string"==typeof this[0].form?this.closest("form"):t(this[0].form)},t.ui.formResetMixin={_formResetHandler:function(){var e=t(this);setTimeout(function(){var i=e.data("ui-form-reset-instances");t.each(i,function(){this.refresh()})})},_bindFormResetHandler:function(){if(this.form=this.element.form(),this.form.length){var t=this.form.data("ui-form-reset-instances")||[];t.length||this.form.on("reset.ui-form-reset",this._formResetHandler),t.push(this),this.form.data("ui-form-reset-instances",t)}},_unbindFormResetHandler:function(){if(this.form.length){var e=this.form.data("ui-form-reset-instances");e.splice(t.inArray(this,e),1),e.length?this.form.data("ui-form-reset-instances",e):this.form.removeData("ui-form-reset-instances").off("reset.ui-form-reset")}}},"1.7"===t.fn.jquery.substring(0,3)&&(t.each(["Width","Height"],function(e,i){function s(e,i,s,o){return t.each(n,function(){i-=parseFloat(t.css(e,"padding"+this))||0,s&&(i-=parseFloat(t.css(e,"border"+this+"Width"))||0),o&&(i-=parseFloat(t.css(e,"margin"+this))||0)}),i}var n="Width"===i?["Left","Right"]:["Top","Bottom"],o=i.toLowerCase(),a={innerWidth:t.fn.innerWidth,innerHeight:t.fn.innerHeight,outerWidth:t.fn.outerWidth,outerHeight:t.fn.outerHeight};t.fn["inner"+i]=function(e){return void 0===e?a["inner"+i].call(this):this.each(function(){t(this).css(o,s(this,e)+"px")})},t.fn["outer"+i]=function(e,n){return"number"!=typeof e?a["outer"+i].call(this,e):this.each(function(){t(this).css(o,s(this,e,!0,n)+"px")})}}),t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t.ui.keyCode={BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38},t.ui.escapeSelector=function(){var t=/([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g;return function(e){return e.replace(t,"\\$1")}}(),t.fn.labels=function(){var e,i,s,n,o;return this[0].labels&&this[0].labels.length?this.pushStack(this[0].labels):(n=this.eq(0).parents("label"),s=this.attr("id"),s&&(e=this.eq(0).parents().last(),o=e.add(e.length?e.siblings():this.siblings()),i="label[for='"+t.ui.escapeSelector(s)+"']",n=n.add(o.find(i).addBack(i))),this.pushStack(n))},t.fn.scrollParent=function(e){var i=this.css("position"),s="absolute"===i,n=e?/(auto|scroll|hidden)/:/(auto|scroll)/,o=this.parents().filter(function(){var e=t(this);return s&&"static"===e.css("position")?!1:n.test(e.css("overflow")+e.css("overflow-y")+e.css("overflow-x"))}).eq(0);return"fixed"!==i&&o.length?o:t(this[0].ownerDocument||document)},t.extend(t.expr[":"],{tabbable:function(e){var i=t.attr(e,"tabindex"),s=null!=i;return(!s||i>=0)&&t.ui.focusable(e,s)}}),t.fn.extend({uniqueId:function(){var t=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++t)})}}(),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&t(this).removeAttr("id")})}}),t.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase());var c=!1;t(document).on("mouseup",function(){c=!1}),t.widget("ui.mouse",{version:"1.12.1",options:{cancel:"input, textarea, button, select, option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.on("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).on("click."+this.widgetName,function(i){return!0===t.data(i.target,e.widgetName+".preventClickEvent")?(t.removeData(i.target,e.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):void 0}),this.started=!1},_mouseDestroy:function(){this.element.off("."+this.widgetName),this._mouseMoveDelegate&&this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(e){if(!c){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(e),this._mouseDownEvent=e;var i=this,s=1===e.which,n="string"==typeof this.options.cancel&&e.target.nodeName?t(e.target).closest(this.options.cancel).length:!1;return s&&!n&&this._mouseCapture(e)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){i.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(e)!==!1,!this._mouseStarted)?(e.preventDefault(),!0):(!0===t.data(e.target,this.widgetName+".preventClickEvent")&&t.removeData(e.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return i._mouseMove(t)},this._mouseUpDelegate=function(t){return i._mouseUp(t)},this.document.on("mousemove."+this.widgetName,this._mouseMoveDelegate).on("mouseup."+this.widgetName,this._mouseUpDelegate),e.preventDefault(),c=!0,!0)):!0}},_mouseMove:function(e){if(this._mouseMoved){if(t.ui.ie&&(!document.documentMode||9>document.documentMode)&&!e.button)return this._mouseUp(e);if(!e.which)if(e.originalEvent.altKey||e.originalEvent.ctrlKey||e.originalEvent.metaKey||e.originalEvent.shiftKey)this.ignoreMissingWhich=!0;else if(!this.ignoreMissingWhich)return this._mouseUp(e)}return(e.which||e.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(e),e.preventDefault()):(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,e)!==!1,this._mouseStarted?this._mouseDrag(e):this._mouseUp(e)),!this._mouseStarted)},_mouseUp:function(e){this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,e.target===this._mouseDownEvent.target&&t.data(e.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(e)),this._mouseDelayTimer&&(clearTimeout(this._mouseDelayTimer),delete this._mouseDelayTimer),this.ignoreMissingWhich=!1,c=!1,e.preventDefault()},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),t.ui.plugin={add:function(e,i,s){var n,o=t.ui[e].prototype;for(n in s)o.plugins[n]=o.plugins[n]||[],o.plugins[n].push([i,s[n]])},call:function(t,e,i,s){var n,o=t.plugins[e];if(o&&(s||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(n=0;o.length>n;n++)t.options[o[n][0]]&&o[n][1].apply(t.element,i)}},t.ui.safeActiveElement=function(t){var e;try{e=t.activeElement}catch(i){e=t.body}return e||(e=t.body),e.nodeName||(e=t.body),e},t.ui.safeBlur=function(e){e&&"body"!==e.nodeName.toLowerCase()&&t(e).trigger("blur")},t.widget("ui.draggable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1,drag:null,start:null,stop:null},_create:function(){"original"===this.options.helper&&this._setPositionRelative(),this.options.addClasses&&this._addClass("ui-draggable"),this._setHandleClassName(),this._mouseInit()},_setOption:function(t,e){this._super(t,e),"handle"===t&&(this._removeHandleClassName(),this._setHandleClassName())},_destroy:function(){return(this.helper||this.element).is(".ui-draggable-dragging")?(this.destroyOnClear=!0,void 0):(this._removeHandleClassName(),this._mouseDestroy(),void 0)},_mouseCapture:function(e){var i=this.options;return this.helper||i.disabled||t(e.target).closest(".ui-resizable-handle").length>0?!1:(this.handle=this._getHandle(e),this.handle?(this._blurActiveElement(e),this._blockFrames(i.iframeFix===!0?"iframe":i.iframeFix),!0):!1)},_blockFrames:function(e){this.iframeBlocks=this.document.find(e).map(function(){var e=t(this);return t("
").css("position","absolute").appendTo(e.parent()).outerWidth(e.outerWidth()).outerHeight(e.outerHeight()).offset(e.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_blurActiveElement:function(e){var i=t.ui.safeActiveElement(this.document[0]),s=t(e.target);s.closest(i).length||t.ui.safeBlur(i)},_mouseStart:function(e){var i=this.options;return this.helper=this._createHelper(e),this._addClass(this.helper,"ui-draggable-dragging"),this._cacheHelperProportions(),t.ui.ddmanager&&(t.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(!0),this.offsetParent=this.helper.offsetParent(),this.hasFixedAncestor=this.helper.parents().filter(function(){return"fixed"===t(this).css("position")}).length>0,this.positionAbs=this.element.offset(),this._refreshOffsets(e),this.originalPosition=this.position=this._generatePosition(e,!1),this.originalPageX=e.pageX,this.originalPageY=e.pageY,i.cursorAt&&this._adjustOffsetFromHelper(i.cursorAt),this._setContainment(),this._trigger("start",e)===!1?(this._clear(),!1):(this._cacheHelperProportions(),t.ui.ddmanager&&!i.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e),this._mouseDrag(e,!0),t.ui.ddmanager&&t.ui.ddmanager.dragStart(this,e),!0)},_refreshOffsets:function(t){this.offset={top:this.positionAbs.top-this.margins.top,left:this.positionAbs.left-this.margins.left,scroll:!1,parent:this._getParentOffset(),relative:this._getRelativeOffset()},this.offset.click={left:t.pageX-this.offset.left,top:t.pageY-this.offset.top}},_mouseDrag:function(e,i){if(this.hasFixedAncestor&&(this.offset.parent=this._getParentOffset()),this.position=this._generatePosition(e,!0),this.positionAbs=this._convertPositionTo("absolute"),!i){var s=this._uiHash();if(this._trigger("drag",e,s)===!1)return this._mouseUp(new t.Event("mouseup",e)),!1;this.position=s.position}return this.helper[0].style.left=this.position.left+"px",this.helper[0].style.top=this.position.top+"px",t.ui.ddmanager&&t.ui.ddmanager.drag(this,e),!1},_mouseStop:function(e){var i=this,s=!1;return t.ui.ddmanager&&!this.options.dropBehaviour&&(s=t.ui.ddmanager.drop(this,e)),this.dropped&&(s=this.dropped,this.dropped=!1),"invalid"===this.options.revert&&!s||"valid"===this.options.revert&&s||this.options.revert===!0||t.isFunction(this.options.revert)&&this.options.revert.call(this.element,s)?t(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){i._trigger("stop",e)!==!1&&i._clear()}):this._trigger("stop",e)!==!1&&this._clear(),!1},_mouseUp:function(e){return this._unblockFrames(),t.ui.ddmanager&&t.ui.ddmanager.dragStop(this,e),this.handleElement.is(e.target)&&this.element.trigger("focus"),t.ui.mouse.prototype._mouseUp.call(this,e)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp(new t.Event("mouseup",{target:this.element[0]})):this._clear(),this},_getHandle:function(e){return this.options.handle?!!t(e.target).closest(this.element.find(this.options.handle)).length:!0},_setHandleClassName:function(){this.handleElement=this.options.handle?this.element.find(this.options.handle):this.element,this._addClass(this.handleElement,"ui-draggable-handle")},_removeHandleClassName:function(){this._removeClass(this.handleElement,"ui-draggable-handle")},_createHelper:function(e){var i=this.options,s=t.isFunction(i.helper),n=s?t(i.helper.apply(this.element[0],[e])):"clone"===i.helper?this.element.clone().removeAttr("id"):this.element;return n.parents("body").length||n.appendTo("parent"===i.appendTo?this.element[0].parentNode:i.appendTo),s&&n[0]===this.element[0]&&this._setPositionRelative(),n[0]===this.element[0]||/(fixed|absolute)/.test(n.css("position"))||n.css("position","absolute"),n},_setPositionRelative:function(){/^(?:r|a|f)/.test(this.element.css("position"))||(this.element[0].style.position="relative")},_adjustOffsetFromHelper:function(e){"string"==typeof e&&(e=e.split(" ")),t.isArray(e)&&(e={left:+e[0],top:+e[1]||0}),"left"in e&&(this.offset.click.left=e.left+this.margins.left),"right"in e&&(this.offset.click.left=this.helperProportions.width-e.right+this.margins.left),"top"in e&&(this.offset.click.top=e.top+this.margins.top),"bottom"in e&&(this.offset.click.top=this.helperProportions.height-e.bottom+this.margins.top)},_isRootNode:function(t){return/(html|body)/i.test(t.tagName)||t===this.document[0]},_getParentOffset:function(){var e=this.offsetParent.offset(),i=this.document[0];return"absolute"===this.cssPosition&&this.scrollParent[0]!==i&&t.contains(this.scrollParent[0],this.offsetParent[0])&&(e.left+=this.scrollParent.scrollLeft(),e.top+=this.scrollParent.scrollTop()),this._isRootNode(this.offsetParent[0])&&(e={top:0,left:0}),{top:e.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:e.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"!==this.cssPosition)return{top:0,left:0};var t=this.element.position(),e=this._isRootNode(this.scrollParent[0]);return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+(e?0:this.scrollParent.scrollTop()),left:t.left-(parseInt(this.helper.css("left"),10)||0)+(e?0:this.scrollParent.scrollLeft())}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e,i,s,n=this.options,o=this.document[0];return this.relativeContainer=null,n.containment?"window"===n.containment?(this.containment=[t(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,t(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,t(window).scrollLeft()+t(window).width()-this.helperProportions.width-this.margins.left,t(window).scrollTop()+(t(window).height()||o.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],void 0):"document"===n.containment?(this.containment=[0,0,t(o).width()-this.helperProportions.width-this.margins.left,(t(o).height()||o.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],void 0):n.containment.constructor===Array?(this.containment=n.containment,void 0):("parent"===n.containment&&(n.containment=this.helper[0].parentNode),i=t(n.containment),s=i[0],s&&(e=/(scroll|auto)/.test(i.css("overflow")),this.containment=[(parseInt(i.css("borderLeftWidth"),10)||0)+(parseInt(i.css("paddingLeft"),10)||0),(parseInt(i.css("borderTopWidth"),10)||0)+(parseInt(i.css("paddingTop"),10)||0),(e?Math.max(s.scrollWidth,s.offsetWidth):s.offsetWidth)-(parseInt(i.css("borderRightWidth"),10)||0)-(parseInt(i.css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(e?Math.max(s.scrollHeight,s.offsetHeight):s.offsetHeight)-(parseInt(i.css("borderBottomWidth"),10)||0)-(parseInt(i.css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relativeContainer=i),void 0):(this.containment=null,void 0) +},_convertPositionTo:function(t,e){e||(e=this.position);var i="absolute"===t?1:-1,s=this._isRootNode(this.scrollParent[0]);return{top:e.top+this.offset.relative.top*i+this.offset.parent.top*i-("fixed"===this.cssPosition?-this.offset.scroll.top:s?0:this.offset.scroll.top)*i,left:e.left+this.offset.relative.left*i+this.offset.parent.left*i-("fixed"===this.cssPosition?-this.offset.scroll.left:s?0:this.offset.scroll.left)*i}},_generatePosition:function(t,e){var i,s,n,o,a=this.options,r=this._isRootNode(this.scrollParent[0]),h=t.pageX,l=t.pageY;return r&&this.offset.scroll||(this.offset.scroll={top:this.scrollParent.scrollTop(),left:this.scrollParent.scrollLeft()}),e&&(this.containment&&(this.relativeContainer?(s=this.relativeContainer.offset(),i=[this.containment[0]+s.left,this.containment[1]+s.top,this.containment[2]+s.left,this.containment[3]+s.top]):i=this.containment,t.pageX-this.offset.click.lefti[2]&&(h=i[2]+this.offset.click.left),t.pageY-this.offset.click.top>i[3]&&(l=i[3]+this.offset.click.top)),a.grid&&(n=a.grid[1]?this.originalPageY+Math.round((l-this.originalPageY)/a.grid[1])*a.grid[1]:this.originalPageY,l=i?n-this.offset.click.top>=i[1]||n-this.offset.click.top>i[3]?n:n-this.offset.click.top>=i[1]?n-a.grid[1]:n+a.grid[1]:n,o=a.grid[0]?this.originalPageX+Math.round((h-this.originalPageX)/a.grid[0])*a.grid[0]:this.originalPageX,h=i?o-this.offset.click.left>=i[0]||o-this.offset.click.left>i[2]?o:o-this.offset.click.left>=i[0]?o-a.grid[0]:o+a.grid[0]:o),"y"===a.axis&&(h=this.originalPageX),"x"===a.axis&&(l=this.originalPageY)),{top:l-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.offset.scroll.top:r?0:this.offset.scroll.top),left:h-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.offset.scroll.left:r?0:this.offset.scroll.left)}},_clear:function(){this._removeClass(this.helper,"ui-draggable-dragging"),this.helper[0]===this.element[0]||this.cancelHelperRemoval||this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1,this.destroyOnClear&&this.destroy()},_trigger:function(e,i,s){return s=s||this._uiHash(),t.ui.plugin.call(this,e,[i,s,this],!0),/^(drag|start|stop)/.test(e)&&(this.positionAbs=this._convertPositionTo("absolute"),s.offset=this.positionAbs),t.Widget.prototype._trigger.call(this,e,i,s)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),t.ui.plugin.add("draggable","connectToSortable",{start:function(e,i,s){var n=t.extend({},i,{item:s.element});s.sortables=[],t(s.options.connectToSortable).each(function(){var i=t(this).sortable("instance");i&&!i.options.disabled&&(s.sortables.push(i),i.refreshPositions(),i._trigger("activate",e,n))})},stop:function(e,i,s){var n=t.extend({},i,{item:s.element});s.cancelHelperRemoval=!1,t.each(s.sortables,function(){var t=this;t.isOver?(t.isOver=0,s.cancelHelperRemoval=!0,t.cancelHelperRemoval=!1,t._storedCSS={position:t.placeholder.css("position"),top:t.placeholder.css("top"),left:t.placeholder.css("left")},t._mouseStop(e),t.options.helper=t.options._helper):(t.cancelHelperRemoval=!0,t._trigger("deactivate",e,n))})},drag:function(e,i,s){t.each(s.sortables,function(){var n=!1,o=this;o.positionAbs=s.positionAbs,o.helperProportions=s.helperProportions,o.offset.click=s.offset.click,o._intersectsWith(o.containerCache)&&(n=!0,t.each(s.sortables,function(){return this.positionAbs=s.positionAbs,this.helperProportions=s.helperProportions,this.offset.click=s.offset.click,this!==o&&this._intersectsWith(this.containerCache)&&t.contains(o.element[0],this.element[0])&&(n=!1),n})),n?(o.isOver||(o.isOver=1,s._parent=i.helper.parent(),o.currentItem=i.helper.appendTo(o.element).data("ui-sortable-item",!0),o.options._helper=o.options.helper,o.options.helper=function(){return i.helper[0]},e.target=o.currentItem[0],o._mouseCapture(e,!0),o._mouseStart(e,!0,!0),o.offset.click.top=s.offset.click.top,o.offset.click.left=s.offset.click.left,o.offset.parent.left-=s.offset.parent.left-o.offset.parent.left,o.offset.parent.top-=s.offset.parent.top-o.offset.parent.top,s._trigger("toSortable",e),s.dropped=o.element,t.each(s.sortables,function(){this.refreshPositions()}),s.currentItem=s.element,o.fromOutside=s),o.currentItem&&(o._mouseDrag(e),i.position=o.position)):o.isOver&&(o.isOver=0,o.cancelHelperRemoval=!0,o.options._revert=o.options.revert,o.options.revert=!1,o._trigger("out",e,o._uiHash(o)),o._mouseStop(e,!0),o.options.revert=o.options._revert,o.options.helper=o.options._helper,o.placeholder&&o.placeholder.remove(),i.helper.appendTo(s._parent),s._refreshOffsets(e),i.position=s._generatePosition(e,!0),s._trigger("fromSortable",e),s.dropped=!1,t.each(s.sortables,function(){this.refreshPositions()}))})}}),t.ui.plugin.add("draggable","cursor",{start:function(e,i,s){var n=t("body"),o=s.options;n.css("cursor")&&(o._cursor=n.css("cursor")),n.css("cursor",o.cursor)},stop:function(e,i,s){var n=s.options;n._cursor&&t("body").css("cursor",n._cursor)}}),t.ui.plugin.add("draggable","opacity",{start:function(e,i,s){var n=t(i.helper),o=s.options;n.css("opacity")&&(o._opacity=n.css("opacity")),n.css("opacity",o.opacity)},stop:function(e,i,s){var n=s.options;n._opacity&&t(i.helper).css("opacity",n._opacity)}}),t.ui.plugin.add("draggable","scroll",{start:function(t,e,i){i.scrollParentNotHidden||(i.scrollParentNotHidden=i.helper.scrollParent(!1)),i.scrollParentNotHidden[0]!==i.document[0]&&"HTML"!==i.scrollParentNotHidden[0].tagName&&(i.overflowOffset=i.scrollParentNotHidden.offset())},drag:function(e,i,s){var n=s.options,o=!1,a=s.scrollParentNotHidden[0],r=s.document[0];a!==r&&"HTML"!==a.tagName?(n.axis&&"x"===n.axis||(s.overflowOffset.top+a.offsetHeight-e.pageY=0;d--)h=s.snapElements[d].left-s.margins.left,l=h+s.snapElements[d].width,c=s.snapElements[d].top-s.margins.top,u=c+s.snapElements[d].height,h-g>_||m>l+g||c-g>b||v>u+g||!t.contains(s.snapElements[d].item.ownerDocument,s.snapElements[d].item)?(s.snapElements[d].snapping&&s.options.snap.release&&s.options.snap.release.call(s.element,e,t.extend(s._uiHash(),{snapItem:s.snapElements[d].item})),s.snapElements[d].snapping=!1):("inner"!==f.snapMode&&(n=g>=Math.abs(c-b),o=g>=Math.abs(u-v),a=g>=Math.abs(h-_),r=g>=Math.abs(l-m),n&&(i.position.top=s._convertPositionTo("relative",{top:c-s.helperProportions.height,left:0}).top),o&&(i.position.top=s._convertPositionTo("relative",{top:u,left:0}).top),a&&(i.position.left=s._convertPositionTo("relative",{top:0,left:h-s.helperProportions.width}).left),r&&(i.position.left=s._convertPositionTo("relative",{top:0,left:l}).left)),p=n||o||a||r,"outer"!==f.snapMode&&(n=g>=Math.abs(c-v),o=g>=Math.abs(u-b),a=g>=Math.abs(h-m),r=g>=Math.abs(l-_),n&&(i.position.top=s._convertPositionTo("relative",{top:c,left:0}).top),o&&(i.position.top=s._convertPositionTo("relative",{top:u-s.helperProportions.height,left:0}).top),a&&(i.position.left=s._convertPositionTo("relative",{top:0,left:h}).left),r&&(i.position.left=s._convertPositionTo("relative",{top:0,left:l-s.helperProportions.width}).left)),!s.snapElements[d].snapping&&(n||o||a||r||p)&&s.options.snap.snap&&s.options.snap.snap.call(s.element,e,t.extend(s._uiHash(),{snapItem:s.snapElements[d].item})),s.snapElements[d].snapping=n||o||a||r||p)}}),t.ui.plugin.add("draggable","stack",{start:function(e,i,s){var n,o=s.options,a=t.makeArray(t(o.stack)).sort(function(e,i){return(parseInt(t(e).css("zIndex"),10)||0)-(parseInt(t(i).css("zIndex"),10)||0)});a.length&&(n=parseInt(t(a[0]).css("zIndex"),10)||0,t(a).each(function(e){t(this).css("zIndex",n+e)}),this.css("zIndex",n+a.length))}}),t.ui.plugin.add("draggable","zIndex",{start:function(e,i,s){var n=t(i.helper),o=s.options;n.css("zIndex")&&(o._zIndex=n.css("zIndex")),n.css("zIndex",o.zIndex)},stop:function(e,i,s){var n=s.options;n._zIndex&&t(i.helper).css("zIndex",n._zIndex)}}),t.ui.draggable,t.widget("ui.droppable",{version:"1.12.1",widgetEventPrefix:"drop",options:{accept:"*",addClasses:!0,greedy:!1,scope:"default",tolerance:"intersect",activate:null,deactivate:null,drop:null,out:null,over:null},_create:function(){var e,i=this.options,s=i.accept;this.isover=!1,this.isout=!0,this.accept=t.isFunction(s)?s:function(t){return t.is(s)},this.proportions=function(){return arguments.length?(e=arguments[0],void 0):e?e:e={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight}},this._addToManager(i.scope),i.addClasses&&this._addClass("ui-droppable")},_addToManager:function(e){t.ui.ddmanager.droppables[e]=t.ui.ddmanager.droppables[e]||[],t.ui.ddmanager.droppables[e].push(this)},_splice:function(t){for(var e=0;t.length>e;e++)t[e]===this&&t.splice(e,1)},_destroy:function(){var e=t.ui.ddmanager.droppables[this.options.scope];this._splice(e)},_setOption:function(e,i){if("accept"===e)this.accept=t.isFunction(i)?i:function(t){return t.is(i)};else if("scope"===e){var s=t.ui.ddmanager.droppables[this.options.scope];this._splice(s),this._addToManager(i)}this._super(e,i)},_activate:function(e){var i=t.ui.ddmanager.current;this._addActiveClass(),i&&this._trigger("activate",e,this.ui(i))},_deactivate:function(e){var i=t.ui.ddmanager.current;this._removeActiveClass(),i&&this._trigger("deactivate",e,this.ui(i))},_over:function(e){var i=t.ui.ddmanager.current;i&&(i.currentItem||i.element)[0]!==this.element[0]&&this.accept.call(this.element[0],i.currentItem||i.element)&&(this._addHoverClass(),this._trigger("over",e,this.ui(i)))},_out:function(e){var i=t.ui.ddmanager.current;i&&(i.currentItem||i.element)[0]!==this.element[0]&&this.accept.call(this.element[0],i.currentItem||i.element)&&(this._removeHoverClass(),this._trigger("out",e,this.ui(i)))},_drop:function(e,i){var s=i||t.ui.ddmanager.current,n=!1;return s&&(s.currentItem||s.element)[0]!==this.element[0]?(this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function(){var i=t(this).droppable("instance");return i.options.greedy&&!i.options.disabled&&i.options.scope===s.options.scope&&i.accept.call(i.element[0],s.currentItem||s.element)&&u(s,t.extend(i,{offset:i.element.offset()}),i.options.tolerance,e)?(n=!0,!1):void 0}),n?!1:this.accept.call(this.element[0],s.currentItem||s.element)?(this._removeActiveClass(),this._removeHoverClass(),this._trigger("drop",e,this.ui(s)),this.element):!1):!1},ui:function(t){return{draggable:t.currentItem||t.element,helper:t.helper,position:t.position,offset:t.positionAbs}},_addHoverClass:function(){this._addClass("ui-droppable-hover")},_removeHoverClass:function(){this._removeClass("ui-droppable-hover")},_addActiveClass:function(){this._addClass("ui-droppable-active")},_removeActiveClass:function(){this._removeClass("ui-droppable-active")}});var u=t.ui.intersect=function(){function t(t,e,i){return t>=e&&e+i>t}return function(e,i,s,n){if(!i.offset)return!1;var o=(e.positionAbs||e.position.absolute).left+e.margins.left,a=(e.positionAbs||e.position.absolute).top+e.margins.top,r=o+e.helperProportions.width,h=a+e.helperProportions.height,l=i.offset.left,c=i.offset.top,u=l+i.proportions().width,d=c+i.proportions().height;switch(s){case"fit":return o>=l&&u>=r&&a>=c&&d>=h;case"intersect":return o+e.helperProportions.width/2>l&&u>r-e.helperProportions.width/2&&a+e.helperProportions.height/2>c&&d>h-e.helperProportions.height/2;case"pointer":return t(n.pageY,c,i.proportions().height)&&t(n.pageX,l,i.proportions().width);case"touch":return(a>=c&&d>=a||h>=c&&d>=h||c>a&&h>d)&&(o>=l&&u>=o||r>=l&&u>=r||l>o&&r>u);default:return!1}}}();t.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(e,i){var s,n,o=t.ui.ddmanager.droppables[e.options.scope]||[],a=i?i.type:null,r=(e.currentItem||e.element).find(":data(ui-droppable)").addBack();t:for(s=0;o.length>s;s++)if(!(o[s].options.disabled||e&&!o[s].accept.call(o[s].element[0],e.currentItem||e.element))){for(n=0;r.length>n;n++)if(r[n]===o[s].element[0]){o[s].proportions().height=0;continue t}o[s].visible="none"!==o[s].element.css("display"),o[s].visible&&("mousedown"===a&&o[s]._activate.call(o[s],i),o[s].offset=o[s].element.offset(),o[s].proportions({width:o[s].element[0].offsetWidth,height:o[s].element[0].offsetHeight}))}},drop:function(e,i){var s=!1;return t.each((t.ui.ddmanager.droppables[e.options.scope]||[]).slice(),function(){this.options&&(!this.options.disabled&&this.visible&&u(e,this,this.options.tolerance,i)&&(s=this._drop.call(this,i)||s),!this.options.disabled&&this.visible&&this.accept.call(this.element[0],e.currentItem||e.element)&&(this.isout=!0,this.isover=!1,this._deactivate.call(this,i)))}),s},dragStart:function(e,i){e.element.parentsUntil("body").on("scroll.droppable",function(){e.options.refreshPositions||t.ui.ddmanager.prepareOffsets(e,i)})},drag:function(e,i){e.options.refreshPositions&&t.ui.ddmanager.prepareOffsets(e,i),t.each(t.ui.ddmanager.droppables[e.options.scope]||[],function(){if(!this.options.disabled&&!this.greedyChild&&this.visible){var s,n,o,a=u(e,this,this.options.tolerance,i),r=!a&&this.isover?"isout":a&&!this.isover?"isover":null;r&&(this.options.greedy&&(n=this.options.scope,o=this.element.parents(":data(ui-droppable)").filter(function(){return t(this).droppable("instance").options.scope===n}),o.length&&(s=t(o[0]).droppable("instance"),s.greedyChild="isover"===r)),s&&"isover"===r&&(s.isover=!1,s.isout=!0,s._out.call(s,i)),this[r]=!0,this["isout"===r?"isover":"isout"]=!1,this["isover"===r?"_over":"_out"].call(this,i),s&&"isout"===r&&(s.isout=!1,s.isover=!0,s._over.call(s,i)))}})},dragStop:function(e,i){e.element.parentsUntil("body").off("scroll.droppable"),e.options.refreshPositions||t.ui.ddmanager.prepareOffsets(e,i)}},t.uiBackCompat!==!1&&t.widget("ui.droppable",t.ui.droppable,{options:{hoverClass:!1,activeClass:!1},_addActiveClass:function(){this._super(),this.options.activeClass&&this.element.addClass(this.options.activeClass)},_removeActiveClass:function(){this._super(),this.options.activeClass&&this.element.removeClass(this.options.activeClass)},_addHoverClass:function(){this._super(),this.options.hoverClass&&this.element.addClass(this.options.hoverClass)},_removeHoverClass:function(){this._super(),this.options.hoverClass&&this.element.removeClass(this.options.hoverClass)}}),t.ui.droppable,t.widget("ui.resizable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,classes:{"ui-resizable-se":"ui-icon ui-icon-gripsmall-diagonal-se"},containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_num:function(t){return parseFloat(t)||0},_isNumber:function(t){return!isNaN(parseFloat(t))},_hasScroll:function(e,i){if("hidden"===t(e).css("overflow"))return!1;var s=i&&"left"===i?"scrollLeft":"scrollTop",n=!1;return e[s]>0?!0:(e[s]=1,n=e[s]>0,e[s]=0,n)},_create:function(){var e,i=this.options,s=this;this._addClass("ui-resizable"),t.extend(this,{_aspectRatio:!!i.aspectRatio,aspectRatio:i.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:i.helper||i.ghost||i.animate?i.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)&&(this.element.wrap(t("
").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,e={marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom"),marginLeft:this.originalElement.css("marginLeft")},this.element.css(e),this.originalElement.css("margin",0),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css(e),this._proportionallyResize()),this._setupHandles(),i.autoHide&&t(this.element).on("mouseenter",function(){i.disabled||(s._removeClass("ui-resizable-autohide"),s._handles.show())}).on("mouseleave",function(){i.disabled||s.resizing||(s._addClass("ui-resizable-autohide"),s._handles.hide())}),this._mouseInit()},_destroy:function(){this._mouseDestroy();var e,i=function(e){t(e).removeData("resizable").removeData("ui-resizable").off(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(i(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),i(this.originalElement),this},_setOption:function(t,e){switch(this._super(t,e),t){case"handles":this._removeHandles(),this._setupHandles();break;default:}},_setupHandles:function(){var e,i,s,n,o,a=this.options,r=this;if(this.handles=a.handles||(t(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=t(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),s=this.handles.split(","),this.handles={},i=0;s.length>i;i++)e=t.trim(s[i]),n="ui-resizable-"+e,o=t("
"),this._addClass(o,"ui-resizable-handle "+n),o.css({zIndex:a.zIndex}),this.handles[e]=".ui-resizable-"+e,this.element.append(o);this._renderAxis=function(e){var i,s,n,o;e=e||this.element;for(i in this.handles)this.handles[i].constructor===String?this.handles[i]=this.element.children(this.handles[i]).first().show():(this.handles[i].jquery||this.handles[i].nodeType)&&(this.handles[i]=t(this.handles[i]),this._on(this.handles[i],{mousedown:r._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(s=t(this.handles[i],this.element),o=/sw|ne|nw|se|n|s/.test(i)?s.outerHeight():s.outerWidth(),n=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join(""),e.css(n,o),this._proportionallyResize()),this._handles=this._handles.add(this.handles[i])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.on("mouseover",function(){r.resizing||(this.className&&(o=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),r.axis=o&&o[1]?o[1]:"se")}),a.autoHide&&(this._handles.hide(),this._addClass("ui-resizable-autohide"))},_removeHandles:function(){this._handles.remove()},_mouseCapture:function(e){var i,s,n=!1;for(i in this.handles)s=t(this.handles[i])[0],(s===e.target||t.contains(s,e.target))&&(n=!0);return!this.options.disabled&&n},_mouseStart:function(e){var i,s,n,o=this.options,a=this.element;return this.resizing=!0,this._renderProxy(),i=this._num(this.helper.css("left")),s=this._num(this.helper.css("top")),o.containment&&(i+=t(o.containment).scrollLeft()||0,s+=t(o.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:i,top:s},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:a.width(),height:a.height()},this.originalSize=this._helper?{width:a.outerWidth(),height:a.outerHeight()}:{width:a.width(),height:a.height()},this.sizeDiff={width:a.outerWidth()-a.width(),height:a.outerHeight()-a.height()},this.originalPosition={left:i,top:s},this.originalMousePosition={left:e.pageX,top:e.pageY},this.aspectRatio="number"==typeof o.aspectRatio?o.aspectRatio:this.originalSize.width/this.originalSize.height||1,n=t(".ui-resizable-"+this.axis).css("cursor"),t("body").css("cursor","auto"===n?this.axis+"-resize":n),this._addClass("ui-resizable-resizing"),this._propagate("start",e),!0},_mouseDrag:function(e){var i,s,n=this.originalMousePosition,o=this.axis,a=e.pageX-n.left||0,r=e.pageY-n.top||0,h=this._change[o];return this._updatePrevProperties(),h?(i=h.apply(this,[e,a,r]),this._updateVirtualBoundaries(e.shiftKey),(this._aspectRatio||e.shiftKey)&&(i=this._updateRatio(i,e)),i=this._respectSize(i,e),this._updateCache(i),this._propagate("resize",e),s=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),t.isEmptyObject(s)||(this._updatePrevProperties(),this._trigger("resize",e,this.ui()),this._applyChanges()),!1):!1},_mouseStop:function(e){this.resizing=!1;var i,s,n,o,a,r,h,l=this.options,c=this;return this._helper&&(i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),n=s&&this._hasScroll(i[0],"left")?0:c.sizeDiff.height,o=s?0:c.sizeDiff.width,a={width:c.helper.width()-o,height:c.helper.height()-n},r=parseFloat(c.element.css("left"))+(c.position.left-c.originalPosition.left)||null,h=parseFloat(c.element.css("top"))+(c.position.top-c.originalPosition.top)||null,l.animate||this.element.css(t.extend(a,{top:h,left:r})),c.helper.height(c.size.height),c.helper.width(c.size.width),this._helper&&!l.animate&&this._proportionallyResize()),t("body").css("cursor","auto"),this._removeClass("ui-resizable-resizing"),this._propagate("stop",e),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var t={};return this.position.top!==this.prevPosition.top&&(t.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(t.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(t.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(t.height=this.size.height+"px"),this.helper.css(t),t},_updateVirtualBoundaries:function(t){var e,i,s,n,o,a=this.options;o={minWidth:this._isNumber(a.minWidth)?a.minWidth:0,maxWidth:this._isNumber(a.maxWidth)?a.maxWidth:1/0,minHeight:this._isNumber(a.minHeight)?a.minHeight:0,maxHeight:this._isNumber(a.maxHeight)?a.maxHeight:1/0},(this._aspectRatio||t)&&(e=o.minHeight*this.aspectRatio,s=o.minWidth/this.aspectRatio,i=o.maxHeight*this.aspectRatio,n=o.maxWidth/this.aspectRatio,e>o.minWidth&&(o.minWidth=e),s>o.minHeight&&(o.minHeight=s),o.maxWidth>i&&(o.maxWidth=i),o.maxHeight>n&&(o.maxHeight=n)),this._vBoundaries=o},_updateCache:function(t){this.offset=this.helper.offset(),this._isNumber(t.left)&&(this.position.left=t.left),this._isNumber(t.top)&&(this.position.top=t.top),this._isNumber(t.height)&&(this.size.height=t.height),this._isNumber(t.width)&&(this.size.width=t.width)},_updateRatio:function(t){var e=this.position,i=this.size,s=this.axis;return this._isNumber(t.height)?t.width=t.height*this.aspectRatio:this._isNumber(t.width)&&(t.height=t.width/this.aspectRatio),"sw"===s&&(t.left=e.left+(i.width-t.width),t.top=null),"nw"===s&&(t.top=e.top+(i.height-t.height),t.left=e.left+(i.width-t.width)),t},_respectSize:function(t){var e=this._vBoundaries,i=this.axis,s=this._isNumber(t.width)&&e.maxWidth&&e.maxWidtht.width,a=this._isNumber(t.height)&&e.minHeight&&e.minHeight>t.height,r=this.originalPosition.left+this.originalSize.width,h=this.originalPosition.top+this.originalSize.height,l=/sw|nw|w/.test(i),c=/nw|ne|n/.test(i);return o&&(t.width=e.minWidth),a&&(t.height=e.minHeight),s&&(t.width=e.maxWidth),n&&(t.height=e.maxHeight),o&&l&&(t.left=r-e.minWidth),s&&l&&(t.left=r-e.maxWidth),a&&c&&(t.top=h-e.minHeight),n&&c&&(t.top=h-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_getPaddingPlusBorderDimensions:function(t){for(var e=0,i=[],s=[t.css("borderTopWidth"),t.css("borderRightWidth"),t.css("borderBottomWidth"),t.css("borderLeftWidth")],n=[t.css("paddingTop"),t.css("paddingRight"),t.css("paddingBottom"),t.css("paddingLeft")];4>e;e++)i[e]=parseFloat(s[e])||0,i[e]+=parseFloat(n[e])||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var t,e=0,i=this.helper||this.element;this._proportionallyResizeElements.length>e;e++)t=this._proportionallyResizeElements[e],this.outerDimensions||(this.outerDimensions=this._getPaddingPlusBorderDimensions(t)),t.css({height:i.height()-this.outerDimensions.height||0,width:i.width()-this.outerDimensions.width||0})},_renderProxy:function(){var e=this.element,i=this.options;this.elementOffset=e.offset(),this._helper?(this.helper=this.helper||t("
"),this._addClass(this.helper,this._helper),this.helper.css({width:this.element.outerWidth(),height:this.element.outerHeight(),position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++i.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize,s=this.originalPosition;return{left:s.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize,n=this.originalPosition;return{top:n.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},sw:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[e,i,s]))},ne:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},nw:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[e,i,s]))}},_propagate:function(e,i){t.ui.plugin.call(this,e,[i,this.ui()]),"resize"!==e&&this._trigger(e,i,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),t.ui.plugin.add("resizable","animate",{stop:function(e){var i=t(this).resizable("instance"),s=i.options,n=i._proportionallyResizeElements,o=n.length&&/textarea/i.test(n[0].nodeName),a=o&&i._hasScroll(n[0],"left")?0:i.sizeDiff.height,r=o?0:i.sizeDiff.width,h={width:i.size.width-r,height:i.size.height-a},l=parseFloat(i.element.css("left"))+(i.position.left-i.originalPosition.left)||null,c=parseFloat(i.element.css("top"))+(i.position.top-i.originalPosition.top)||null;i.element.animate(t.extend(h,c&&l?{top:c,left:l}:{}),{duration:s.animateDuration,easing:s.animateEasing,step:function(){var s={width:parseFloat(i.element.css("width")),height:parseFloat(i.element.css("height")),top:parseFloat(i.element.css("top")),left:parseFloat(i.element.css("left"))};n&&n.length&&t(n[0]).css({width:s.width,height:s.height}),i._updateCache(s),i._propagate("resize",e)}})}}),t.ui.plugin.add("resizable","containment",{start:function(){var e,i,s,n,o,a,r,h=t(this).resizable("instance"),l=h.options,c=h.element,u=l.containment,d=u instanceof t?u.get(0):/parent/.test(u)?c.parent().get(0):u;d&&(h.containerElement=t(d),/document/.test(u)||u===document?(h.containerOffset={left:0,top:0},h.containerPosition={left:0,top:0},h.parentData={element:t(document),left:0,top:0,width:t(document).width(),height:t(document).height()||document.body.parentNode.scrollHeight}):(e=t(d),i=[],t(["Top","Right","Left","Bottom"]).each(function(t,s){i[t]=h._num(e.css("padding"+s))}),h.containerOffset=e.offset(),h.containerPosition=e.position(),h.containerSize={height:e.innerHeight()-i[3],width:e.innerWidth()-i[1]},s=h.containerOffset,n=h.containerSize.height,o=h.containerSize.width,a=h._hasScroll(d,"left")?d.scrollWidth:o,r=h._hasScroll(d)?d.scrollHeight:n,h.parentData={element:d,left:s.left,top:s.top,width:a,height:r}))},resize:function(e){var i,s,n,o,a=t(this).resizable("instance"),r=a.options,h=a.containerOffset,l=a.position,c=a._aspectRatio||e.shiftKey,u={top:0,left:0},d=a.containerElement,p=!0;d[0]!==document&&/static/.test(d.css("position"))&&(u=h),l.left<(a._helper?h.left:0)&&(a.size.width=a.size.width+(a._helper?a.position.left-h.left:a.position.left-u.left),c&&(a.size.height=a.size.width/a.aspectRatio,p=!1),a.position.left=r.helper?h.left:0),l.top<(a._helper?h.top:0)&&(a.size.height=a.size.height+(a._helper?a.position.top-h.top:a.position.top),c&&(a.size.width=a.size.height*a.aspectRatio,p=!1),a.position.top=a._helper?h.top:0),n=a.containerElement.get(0)===a.element.parent().get(0),o=/relative|absolute/.test(a.containerElement.css("position")),n&&o?(a.offset.left=a.parentData.left+a.position.left,a.offset.top=a.parentData.top+a.position.top):(a.offset.left=a.element.offset().left,a.offset.top=a.element.offset().top),i=Math.abs(a.sizeDiff.width+(a._helper?a.offset.left-u.left:a.offset.left-h.left)),s=Math.abs(a.sizeDiff.height+(a._helper?a.offset.top-u.top:a.offset.top-h.top)),i+a.size.width>=a.parentData.width&&(a.size.width=a.parentData.width-i,c&&(a.size.height=a.size.width/a.aspectRatio,p=!1)),s+a.size.height>=a.parentData.height&&(a.size.height=a.parentData.height-s,c&&(a.size.width=a.size.height*a.aspectRatio,p=!1)),p||(a.position.left=a.prevPosition.left,a.position.top=a.prevPosition.top,a.size.width=a.prevSize.width,a.size.height=a.prevSize.height)},stop:function(){var e=t(this).resizable("instance"),i=e.options,s=e.containerOffset,n=e.containerPosition,o=e.containerElement,a=t(e.helper),r=a.offset(),h=a.outerWidth()-e.sizeDiff.width,l=a.outerHeight()-e.sizeDiff.height;e._helper&&!i.animate&&/relative/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l}),e._helper&&!i.animate&&/static/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l})}}),t.ui.plugin.add("resizable","alsoResize",{start:function(){var e=t(this).resizable("instance"),i=e.options;t(i.alsoResize).each(function(){var e=t(this);e.data("ui-resizable-alsoresize",{width:parseFloat(e.width()),height:parseFloat(e.height()),left:parseFloat(e.css("left")),top:parseFloat(e.css("top"))})})},resize:function(e,i){var s=t(this).resizable("instance"),n=s.options,o=s.originalSize,a=s.originalPosition,r={height:s.size.height-o.height||0,width:s.size.width-o.width||0,top:s.position.top-a.top||0,left:s.position.left-a.left||0}; +t(n.alsoResize).each(function(){var e=t(this),s=t(this).data("ui-resizable-alsoresize"),n={},o=e.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];t.each(o,function(t,e){var i=(s[e]||0)+(r[e]||0);i&&i>=0&&(n[e]=i||null)}),e.css(n)})},stop:function(){t(this).removeData("ui-resizable-alsoresize")}}),t.ui.plugin.add("resizable","ghost",{start:function(){var e=t(this).resizable("instance"),i=e.size;e.ghost=e.originalElement.clone(),e.ghost.css({opacity:.25,display:"block",position:"relative",height:i.height,width:i.width,margin:0,left:0,top:0}),e._addClass(e.ghost,"ui-resizable-ghost"),t.uiBackCompat!==!1&&"string"==typeof e.options.ghost&&e.ghost.addClass(this.options.ghost),e.ghost.appendTo(e.helper)},resize:function(){var e=t(this).resizable("instance");e.ghost&&e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})},stop:function(){var e=t(this).resizable("instance");e.ghost&&e.helper&&e.helper.get(0).removeChild(e.ghost.get(0))}}),t.ui.plugin.add("resizable","grid",{resize:function(){var e,i=t(this).resizable("instance"),s=i.options,n=i.size,o=i.originalSize,a=i.originalPosition,r=i.axis,h="number"==typeof s.grid?[s.grid,s.grid]:s.grid,l=h[0]||1,c=h[1]||1,u=Math.round((n.width-o.width)/l)*l,d=Math.round((n.height-o.height)/c)*c,p=o.width+u,f=o.height+d,g=s.maxWidth&&p>s.maxWidth,m=s.maxHeight&&f>s.maxHeight,_=s.minWidth&&s.minWidth>p,v=s.minHeight&&s.minHeight>f;s.grid=h,_&&(p+=l),v&&(f+=c),g&&(p-=l),m&&(f-=c),/^(se|s|e)$/.test(r)?(i.size.width=p,i.size.height=f):/^(ne)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.top=a.top-d):/^(sw)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.left=a.left-u):((0>=f-c||0>=p-l)&&(e=i._getPaddingPlusBorderDimensions(this)),f-c>0?(i.size.height=f,i.position.top=a.top-d):(f=c-e.height,i.size.height=f,i.position.top=a.top+o.height-f),p-l>0?(i.size.width=p,i.position.left=a.left-u):(p=l-e.width,i.size.width=p,i.position.left=a.left+o.width-p))}}),t.ui.resizable,t.widget("ui.selectable",t.ui.mouse,{version:"1.12.1",options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch",selected:null,selecting:null,start:null,stop:null,unselected:null,unselecting:null},_create:function(){var e=this;this._addClass("ui-selectable"),this.dragged=!1,this.refresh=function(){e.elementPos=t(e.element[0]).offset(),e.selectees=t(e.options.filter,e.element[0]),e._addClass(e.selectees,"ui-selectee"),e.selectees.each(function(){var i=t(this),s=i.offset(),n={left:s.left-e.elementPos.left,top:s.top-e.elementPos.top};t.data(this,"selectable-item",{element:this,$element:i,left:n.left,top:n.top,right:n.left+i.outerWidth(),bottom:n.top+i.outerHeight(),startselected:!1,selected:i.hasClass("ui-selected"),selecting:i.hasClass("ui-selecting"),unselecting:i.hasClass("ui-unselecting")})})},this.refresh(),this._mouseInit(),this.helper=t("
"),this._addClass(this.helper,"ui-selectable-helper")},_destroy:function(){this.selectees.removeData("selectable-item"),this._mouseDestroy()},_mouseStart:function(e){var i=this,s=this.options;this.opos=[e.pageX,e.pageY],this.elementPos=t(this.element[0]).offset(),this.options.disabled||(this.selectees=t(s.filter,this.element[0]),this._trigger("start",e),t(s.appendTo).append(this.helper),this.helper.css({left:e.pageX,top:e.pageY,width:0,height:0}),s.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var s=t.data(this,"selectable-item");s.startselected=!0,e.metaKey||e.ctrlKey||(i._removeClass(s.$element,"ui-selected"),s.selected=!1,i._addClass(s.$element,"ui-unselecting"),s.unselecting=!0,i._trigger("unselecting",e,{unselecting:s.element}))}),t(e.target).parents().addBack().each(function(){var s,n=t.data(this,"selectable-item");return n?(s=!e.metaKey&&!e.ctrlKey||!n.$element.hasClass("ui-selected"),i._removeClass(n.$element,s?"ui-unselecting":"ui-selected")._addClass(n.$element,s?"ui-selecting":"ui-unselecting"),n.unselecting=!s,n.selecting=s,n.selected=s,s?i._trigger("selecting",e,{selecting:n.element}):i._trigger("unselecting",e,{unselecting:n.element}),!1):void 0}))},_mouseDrag:function(e){if(this.dragged=!0,!this.options.disabled){var i,s=this,n=this.options,o=this.opos[0],a=this.opos[1],r=e.pageX,h=e.pageY;return o>r&&(i=r,r=o,o=i),a>h&&(i=h,h=a,a=i),this.helper.css({left:o,top:a,width:r-o,height:h-a}),this.selectees.each(function(){var i=t.data(this,"selectable-item"),l=!1,c={};i&&i.element!==s.element[0]&&(c.left=i.left+s.elementPos.left,c.right=i.right+s.elementPos.left,c.top=i.top+s.elementPos.top,c.bottom=i.bottom+s.elementPos.top,"touch"===n.tolerance?l=!(c.left>r||o>c.right||c.top>h||a>c.bottom):"fit"===n.tolerance&&(l=c.left>o&&r>c.right&&c.top>a&&h>c.bottom),l?(i.selected&&(s._removeClass(i.$element,"ui-selected"),i.selected=!1),i.unselecting&&(s._removeClass(i.$element,"ui-unselecting"),i.unselecting=!1),i.selecting||(s._addClass(i.$element,"ui-selecting"),i.selecting=!0,s._trigger("selecting",e,{selecting:i.element}))):(i.selecting&&((e.metaKey||e.ctrlKey)&&i.startselected?(s._removeClass(i.$element,"ui-selecting"),i.selecting=!1,s._addClass(i.$element,"ui-selected"),i.selected=!0):(s._removeClass(i.$element,"ui-selecting"),i.selecting=!1,i.startselected&&(s._addClass(i.$element,"ui-unselecting"),i.unselecting=!0),s._trigger("unselecting",e,{unselecting:i.element}))),i.selected&&(e.metaKey||e.ctrlKey||i.startselected||(s._removeClass(i.$element,"ui-selected"),i.selected=!1,s._addClass(i.$element,"ui-unselecting"),i.unselecting=!0,s._trigger("unselecting",e,{unselecting:i.element})))))}),!1}},_mouseStop:function(e){var i=this;return this.dragged=!1,t(".ui-unselecting",this.element[0]).each(function(){var s=t.data(this,"selectable-item");i._removeClass(s.$element,"ui-unselecting"),s.unselecting=!1,s.startselected=!1,i._trigger("unselected",e,{unselected:s.element})}),t(".ui-selecting",this.element[0]).each(function(){var s=t.data(this,"selectable-item");i._removeClass(s.$element,"ui-selecting")._addClass(s.$element,"ui-selected"),s.selecting=!1,s.selected=!0,s.startselected=!0,i._trigger("selected",e,{selected:s.element})}),this._trigger("stop",e),this.helper.remove(),!1}}),t.widget("ui.sortable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3,activate:null,beforeStop:null,change:null,deactivate:null,out:null,over:null,receive:null,remove:null,sort:null,start:null,stop:null,update:null},_isOverAxis:function(t,e,i){return t>=e&&e+i>t},_isFloating:function(t){return/left|right/.test(t.css("float"))||/inline|table-cell/.test(t.css("display"))},_create:function(){this.containerCache={},this._addClass("ui-sortable"),this.refresh(),this.offset=this.element.offset(),this._mouseInit(),this._setHandleClassName(),this.ready=!0},_setOption:function(t,e){this._super(t,e),"handle"===t&&this._setHandleClassName()},_setHandleClassName:function(){var e=this;this._removeClass(this.element.find(".ui-sortable-handle"),"ui-sortable-handle"),t.each(this.items,function(){e._addClass(this.instance.options.handle?this.item.find(this.instance.options.handle):this.item,"ui-sortable-handle")})},_destroy:function(){this._mouseDestroy();for(var t=this.items.length-1;t>=0;t--)this.items[t].item.removeData(this.widgetName+"-item");return this},_mouseCapture:function(e,i){var s=null,n=!1,o=this;return this.reverting?!1:this.options.disabled||"static"===this.options.type?!1:(this._refreshItems(e),t(e.target).parents().each(function(){return t.data(this,o.widgetName+"-item")===o?(s=t(this),!1):void 0}),t.data(e.target,o.widgetName+"-item")===o&&(s=t(e.target)),s?!this.options.handle||i||(t(this.options.handle,s).find("*").addBack().each(function(){this===e.target&&(n=!0)}),n)?(this.currentItem=s,this._removeCurrentsFromItems(),!0):!1:!1)},_mouseStart:function(e,i,s){var n,o,a=this.options;if(this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(e),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},t.extend(this.offset,{click:{left:e.pageX-this.offset.left,top:e.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(e),this.originalPageX=e.pageX,this.originalPageY=e.pageY,a.cursorAt&&this._adjustOffsetFromHelper(a.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!==this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),a.containment&&this._setContainment(),a.cursor&&"auto"!==a.cursor&&(o=this.document.find("body"),this.storedCursor=o.css("cursor"),o.css("cursor",a.cursor),this.storedStylesheet=t("").appendTo(o)),a.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",a.opacity)),a.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",a.zIndex)),this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",e,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions(),!s)for(n=this.containers.length-1;n>=0;n--)this.containers[n]._trigger("activate",e,this._uiHash(this));return t.ui.ddmanager&&(t.ui.ddmanager.current=this),t.ui.ddmanager&&!a.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e),this.dragging=!0,this._addClass(this.helper,"ui-sortable-helper"),this._mouseDrag(e),!0},_mouseDrag:function(e){var i,s,n,o,a=this.options,r=!1;for(this.position=this._generatePosition(e),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs),this.options.scroll&&(this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-e.pageY=0;i--)if(s=this.items[i],n=s.item[0],o=this._intersectsWithPointer(s),o&&s.instance===this.currentContainer&&n!==this.currentItem[0]&&this.placeholder[1===o?"next":"prev"]()[0]!==n&&!t.contains(this.placeholder[0],n)&&("semi-dynamic"===this.options.type?!t.contains(this.element[0],n):!0)){if(this.direction=1===o?"down":"up","pointer"!==this.options.tolerance&&!this._intersectsWithSides(s))break;this._rearrange(e,s),this._trigger("change",e,this._uiHash());break}return this._contactContainers(e),t.ui.ddmanager&&t.ui.ddmanager.drag(this,e),this._trigger("sort",e,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(e,i){if(e){if(t.ui.ddmanager&&!this.options.dropBehaviour&&t.ui.ddmanager.drop(this,e),this.options.revert){var s=this,n=this.placeholder.offset(),o=this.options.axis,a={};o&&"x"!==o||(a.left=n.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollLeft)),o&&"y"!==o||(a.top=n.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollTop)),this.reverting=!0,t(this.helper).animate(a,parseInt(this.options.revert,10)||500,function(){s._clear(e)})}else this._clear(e,i);return!1}},cancel:function(){if(this.dragging){this._mouseUp(new t.Event("mouseup",{target:null})),"original"===this.options.helper?(this.currentItem.css(this._storedCSS),this._removeClass(this.currentItem,"ui-sortable-helper")):this.currentItem.show();for(var e=this.containers.length-1;e>=0;e--)this.containers[e]._trigger("deactivate",null,this._uiHash(this)),this.containers[e].containerCache.over&&(this.containers[e]._trigger("out",null,this._uiHash(this)),this.containers[e].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),"original"!==this.options.helper&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),t.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?t(this.domPosition.prev).after(this.currentItem):t(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},t(i).each(function(){var i=(t(e.item||this).attr(e.attribute||"id")||"").match(e.expression||/(.+)[\-=_](.+)/);i&&s.push((e.key||i[1]+"[]")+"="+(e.key&&e.expression?i[1]:i[2]))}),!s.length&&e.key&&s.push(e.key+"="),s.join("&")},toArray:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},i.each(function(){s.push(t(e.item||this).attr(e.attribute||"id")||"")}),s},_intersectsWith:function(t){var e=this.positionAbs.left,i=e+this.helperProportions.width,s=this.positionAbs.top,n=s+this.helperProportions.height,o=t.left,a=o+t.width,r=t.top,h=r+t.height,l=this.offset.click.top,c=this.offset.click.left,u="x"===this.options.axis||s+l>r&&h>s+l,d="y"===this.options.axis||e+c>o&&a>e+c,p=u&&d;return"pointer"===this.options.tolerance||this.options.forcePointerForContainers||"pointer"!==this.options.tolerance&&this.helperProportions[this.floating?"width":"height"]>t[this.floating?"width":"height"]?p:e+this.helperProportions.width/2>o&&a>i-this.helperProportions.width/2&&s+this.helperProportions.height/2>r&&h>n-this.helperProportions.height/2},_intersectsWithPointer:function(t){var e,i,s="x"===this.options.axis||this._isOverAxis(this.positionAbs.top+this.offset.click.top,t.top,t.height),n="y"===this.options.axis||this._isOverAxis(this.positionAbs.left+this.offset.click.left,t.left,t.width),o=s&&n;return o?(e=this._getDragVerticalDirection(),i=this._getDragHorizontalDirection(),this.floating?"right"===i||"down"===e?2:1:e&&("down"===e?2:1)):!1},_intersectsWithSides:function(t){var e=this._isOverAxis(this.positionAbs.top+this.offset.click.top,t.top+t.height/2,t.height),i=this._isOverAxis(this.positionAbs.left+this.offset.click.left,t.left+t.width/2,t.width),s=this._getDragVerticalDirection(),n=this._getDragHorizontalDirection();return this.floating&&n?"right"===n&&i||"left"===n&&!i:s&&("down"===s&&e||"up"===s&&!e)},_getDragVerticalDirection:function(){var t=this.positionAbs.top-this.lastPositionAbs.top;return 0!==t&&(t>0?"down":"up")},_getDragHorizontalDirection:function(){var t=this.positionAbs.left-this.lastPositionAbs.left;return 0!==t&&(t>0?"right":"left")},refresh:function(t){return this._refreshItems(t),this._setHandleClassName(),this.refreshPositions(),this},_connectWith:function(){var t=this.options;return t.connectWith.constructor===String?[t.connectWith]:t.connectWith},_getItemsAsjQuery:function(e){function i(){r.push(this)}var s,n,o,a,r=[],h=[],l=this._connectWith();if(l&&e)for(s=l.length-1;s>=0;s--)for(o=t(l[s],this.document[0]),n=o.length-1;n>=0;n--)a=t.data(o[n],this.widgetFullName),a&&a!==this&&!a.options.disabled&&h.push([t.isFunction(a.options.items)?a.options.items.call(a.element):t(a.options.items,a.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),a]);for(h.push([t.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):t(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]),s=h.length-1;s>=0;s--)h[s][0].each(i);return t(r)},_removeCurrentsFromItems:function(){var e=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=t.grep(this.items,function(t){for(var i=0;e.length>i;i++)if(e[i]===t.item[0])return!1;return!0})},_refreshItems:function(e){this.items=[],this.containers=[this];var i,s,n,o,a,r,h,l,c=this.items,u=[[t.isFunction(this.options.items)?this.options.items.call(this.element[0],e,{item:this.currentItem}):t(this.options.items,this.element),this]],d=this._connectWith();if(d&&this.ready)for(i=d.length-1;i>=0;i--)for(n=t(d[i],this.document[0]),s=n.length-1;s>=0;s--)o=t.data(n[s],this.widgetFullName),o&&o!==this&&!o.options.disabled&&(u.push([t.isFunction(o.options.items)?o.options.items.call(o.element[0],e,{item:this.currentItem}):t(o.options.items,o.element),o]),this.containers.push(o));for(i=u.length-1;i>=0;i--)for(a=u[i][1],r=u[i][0],s=0,l=r.length;l>s;s++)h=t(r[s]),h.data(this.widgetName+"-item",a),c.push({item:h,instance:a,width:0,height:0,left:0,top:0})},refreshPositions:function(e){this.floating=this.items.length?"x"===this.options.axis||this._isFloating(this.items[0].item):!1,this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());var i,s,n,o;for(i=this.items.length-1;i>=0;i--)s=this.items[i],s.instance!==this.currentContainer&&this.currentContainer&&s.item[0]!==this.currentItem[0]||(n=this.options.toleranceElement?t(this.options.toleranceElement,s.item):s.item,e||(s.width=n.outerWidth(),s.height=n.outerHeight()),o=n.offset(),s.left=o.left,s.top=o.top);if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(i=this.containers.length-1;i>=0;i--)o=this.containers[i].element.offset(),this.containers[i].containerCache.left=o.left,this.containers[i].containerCache.top=o.top,this.containers[i].containerCache.width=this.containers[i].element.outerWidth(),this.containers[i].containerCache.height=this.containers[i].element.outerHeight();return this},_createPlaceholder:function(e){e=e||this;var i,s=e.options;s.placeholder&&s.placeholder.constructor!==String||(i=s.placeholder,s.placeholder={element:function(){var s=e.currentItem[0].nodeName.toLowerCase(),n=t("<"+s+">",e.document[0]);return e._addClass(n,"ui-sortable-placeholder",i||e.currentItem[0].className)._removeClass(n,"ui-sortable-helper"),"tbody"===s?e._createTrPlaceholder(e.currentItem.find("tr").eq(0),t("",e.document[0]).appendTo(n)):"tr"===s?e._createTrPlaceholder(e.currentItem,n):"img"===s&&n.attr("src",e.currentItem.attr("src")),i||n.css("visibility","hidden"),n},update:function(t,n){(!i||s.forcePlaceholderSize)&&(n.height()||n.height(e.currentItem.innerHeight()-parseInt(e.currentItem.css("paddingTop")||0,10)-parseInt(e.currentItem.css("paddingBottom")||0,10)),n.width()||n.width(e.currentItem.innerWidth()-parseInt(e.currentItem.css("paddingLeft")||0,10)-parseInt(e.currentItem.css("paddingRight")||0,10)))}}),e.placeholder=t(s.placeholder.element.call(e.element,e.currentItem)),e.currentItem.after(e.placeholder),s.placeholder.update(e,e.placeholder)},_createTrPlaceholder:function(e,i){var s=this;e.children().each(function(){t(" ",s.document[0]).attr("colspan",t(this).attr("colspan")||1).appendTo(i)})},_contactContainers:function(e){var i,s,n,o,a,r,h,l,c,u,d=null,p=null;for(i=this.containers.length-1;i>=0;i--)if(!t.contains(this.currentItem[0],this.containers[i].element[0]))if(this._intersectsWith(this.containers[i].containerCache)){if(d&&t.contains(this.containers[i].element[0],d.element[0]))continue;d=this.containers[i],p=i}else this.containers[i].containerCache.over&&(this.containers[i]._trigger("out",e,this._uiHash(this)),this.containers[i].containerCache.over=0);if(d)if(1===this.containers.length)this.containers[p].containerCache.over||(this.containers[p]._trigger("over",e,this._uiHash(this)),this.containers[p].containerCache.over=1);else{for(n=1e4,o=null,c=d.floating||this._isFloating(this.currentItem),a=c?"left":"top",r=c?"width":"height",u=c?"pageX":"pageY",s=this.items.length-1;s>=0;s--)t.contains(this.containers[p].element[0],this.items[s].item[0])&&this.items[s].item[0]!==this.currentItem[0]&&(h=this.items[s].item.offset()[a],l=!1,e[u]-h>this.items[s][r]/2&&(l=!0),n>Math.abs(e[u]-h)&&(n=Math.abs(e[u]-h),o=this.items[s],this.direction=l?"up":"down"));if(!o&&!this.options.dropOnEmpty)return;if(this.currentContainer===this.containers[p])return this.currentContainer.containerCache.over||(this.containers[p]._trigger("over",e,this._uiHash()),this.currentContainer.containerCache.over=1),void 0;o?this._rearrange(e,o,null,!0):this._rearrange(e,null,this.containers[p].element,!0),this._trigger("change",e,this._uiHash()),this.containers[p]._trigger("change",e,this._uiHash(this)),this.currentContainer=this.containers[p],this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[p]._trigger("over",e,this._uiHash(this)),this.containers[p].containerCache.over=1}},_createHelper:function(e){var i=this.options,s=t.isFunction(i.helper)?t(i.helper.apply(this.element[0],[e,this.currentItem])):"clone"===i.helper?this.currentItem.clone():this.currentItem;return s.parents("body").length||t("parent"!==i.appendTo?i.appendTo:this.currentItem[0].parentNode)[0].appendChild(s[0]),s[0]===this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),(!s[0].style.width||i.forceHelperSize)&&s.width(this.currentItem.width()),(!s[0].style.height||i.forceHelperSize)&&s.height(this.currentItem.height()),s},_adjustOffsetFromHelper:function(e){"string"==typeof e&&(e=e.split(" ")),t.isArray(e)&&(e={left:+e[0],top:+e[1]||0}),"left"in e&&(this.offset.click.left=e.left+this.margins.left),"right"in e&&(this.offset.click.left=this.helperProportions.width-e.right+this.margins.left),"top"in e&&(this.offset.click.top=e.top+this.margins.top),"bottom"in e&&(this.offset.click.top=this.helperProportions.height-e.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var e=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==this.document[0]&&t.contains(this.scrollParent[0],this.offsetParent[0])&&(e.left+=this.scrollParent.scrollLeft(),e.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===this.document[0].body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&t.ui.ie)&&(e={top:0,left:0}),{top:e.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:e.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"===this.cssPosition){var t=this.currentItem.position();return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:t.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e,i,s,n=this.options;"parent"===n.containment&&(n.containment=this.helper[0].parentNode),("document"===n.containment||"window"===n.containment)&&(this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,"document"===n.containment?this.document.width():this.window.width()-this.helperProportions.width-this.margins.left,("document"===n.containment?this.document.height()||document.body.parentNode.scrollHeight:this.window.height()||this.document[0].body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]),/^(document|window|parent)$/.test(n.containment)||(e=t(n.containment)[0],i=t(n.containment).offset(),s="hidden"!==t(e).css("overflow"),this.containment=[i.left+(parseInt(t(e).css("borderLeftWidth"),10)||0)+(parseInt(t(e).css("paddingLeft"),10)||0)-this.margins.left,i.top+(parseInt(t(e).css("borderTopWidth"),10)||0)+(parseInt(t(e).css("paddingTop"),10)||0)-this.margins.top,i.left+(s?Math.max(e.scrollWidth,e.offsetWidth):e.offsetWidth)-(parseInt(t(e).css("borderLeftWidth"),10)||0)-(parseInt(t(e).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,i.top+(s?Math.max(e.scrollHeight,e.offsetHeight):e.offsetHeight)-(parseInt(t(e).css("borderTopWidth"),10)||0)-(parseInt(t(e).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top])},_convertPositionTo:function(e,i){i||(i=this.position);var s="absolute"===e?1:-1,n="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,o=/(html|body)/i.test(n[0].tagName);return{top:i.top+this.offset.relative.top*s+this.offset.parent.top*s-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():o?0:n.scrollTop())*s,left:i.left+this.offset.relative.left*s+this.offset.parent.left*s-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():o?0:n.scrollLeft())*s}},_generatePosition:function(e){var i,s,n=this.options,o=e.pageX,a=e.pageY,r="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,h=/(html|body)/i.test(r[0].tagName);return"relative"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&this.scrollParent[0]!==this.offsetParent[0]||(this.offset.relative=this._getRelativeOffset()),this.originalPosition&&(this.containment&&(e.pageX-this.offset.click.leftthis.containment[2]&&(o=this.containment[2]+this.offset.click.left),e.pageY-this.offset.click.top>this.containment[3]&&(a=this.containment[3]+this.offset.click.top)),n.grid&&(i=this.originalPageY+Math.round((a-this.originalPageY)/n.grid[1])*n.grid[1],a=this.containment?i-this.offset.click.top>=this.containment[1]&&i-this.offset.click.top<=this.containment[3]?i:i-this.offset.click.top>=this.containment[1]?i-n.grid[1]:i+n.grid[1]:i,s=this.originalPageX+Math.round((o-this.originalPageX)/n.grid[0])*n.grid[0],o=this.containment?s-this.offset.click.left>=this.containment[0]&&s-this.offset.click.left<=this.containment[2]?s:s-this.offset.click.left>=this.containment[0]?s-n.grid[0]:s+n.grid[0]:s)),{top:a-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():h?0:r.scrollTop()),left:o-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():h?0:r.scrollLeft())}},_rearrange:function(t,e,i,s){i?i[0].appendChild(this.placeholder[0]):e.item[0].parentNode.insertBefore(this.placeholder[0],"down"===this.direction?e.item[0]:e.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var n=this.counter;this._delay(function(){n===this.counter&&this.refreshPositions(!s)})},_clear:function(t,e){function i(t,e,i){return function(s){i._trigger(t,s,e._uiHash(e))}}this.reverting=!1;var s,n=[];if(!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null,this.helper[0]===this.currentItem[0]){for(s in this._storedCSS)("auto"===this._storedCSS[s]||"static"===this._storedCSS[s])&&(this._storedCSS[s]="");this.currentItem.css(this._storedCSS),this._removeClass(this.currentItem,"ui-sortable-helper")}else this.currentItem.show();for(this.fromOutside&&!e&&n.push(function(t){this._trigger("receive",t,this._uiHash(this.fromOutside))}),!this.fromOutside&&this.domPosition.prev===this.currentItem.prev().not(".ui-sortable-helper")[0]&&this.domPosition.parent===this.currentItem.parent()[0]||e||n.push(function(t){this._trigger("update",t,this._uiHash())}),this!==this.currentContainer&&(e||(n.push(function(t){this._trigger("remove",t,this._uiHash())}),n.push(function(t){return function(e){t._trigger("receive",e,this._uiHash(this))}}.call(this,this.currentContainer)),n.push(function(t){return function(e){t._trigger("update",e,this._uiHash(this))}}.call(this,this.currentContainer)))),s=this.containers.length-1;s>=0;s--)e||n.push(i("deactivate",this,this.containers[s])),this.containers[s].containerCache.over&&(n.push(i("out",this,this.containers[s])),this.containers[s].containerCache.over=0);if(this.storedCursor&&(this.document.find("body").css("cursor",this.storedCursor),this.storedStylesheet.remove()),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex","auto"===this._storedZIndex?"":this._storedZIndex),this.dragging=!1,e||this._trigger("beforeStop",t,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.cancelHelperRemoval||(this.helper[0]!==this.currentItem[0]&&this.helper.remove(),this.helper=null),!e){for(s=0;n.length>s;s++)n[s].call(this,t);this._trigger("stop",t,this._uiHash())}return this.fromOutside=!1,!this.cancelHelperRemoval},_trigger:function(){t.Widget.prototype._trigger.apply(this,arguments)===!1&&this.cancel()},_uiHash:function(e){var i=e||this;return{helper:i.helper,placeholder:i.placeholder||t([]),position:i.position,originalPosition:i.originalPosition,offset:i.positionAbs,item:i.currentItem,sender:e?e.element:null}}}),t.widget("ui.accordion",{version:"1.12.1",options:{active:0,animate:{},classes:{"ui-accordion-header":"ui-corner-top","ui-accordion-header-collapsed":"ui-corner-all","ui-accordion-content":"ui-corner-bottom"},collapsible:!1,event:"click",header:"> li > :first-child, > :not(li):even",heightStyle:"auto",icons:{activeHeader:"ui-icon-triangle-1-s",header:"ui-icon-triangle-1-e"},activate:null,beforeActivate:null},hideProps:{borderTopWidth:"hide",borderBottomWidth:"hide",paddingTop:"hide",paddingBottom:"hide",height:"hide"},showProps:{borderTopWidth:"show",borderBottomWidth:"show",paddingTop:"show",paddingBottom:"show",height:"show"},_create:function(){var e=this.options;this.prevShow=this.prevHide=t(),this._addClass("ui-accordion","ui-widget ui-helper-reset"),this.element.attr("role","tablist"),e.collapsible||e.active!==!1&&null!=e.active||(e.active=0),this._processPanels(),0>e.active&&(e.active+=this.headers.length),this._refresh()},_getCreateEventData:function(){return{header:this.active,panel:this.active.length?this.active.next():t()}},_createIcons:function(){var e,i,s=this.options.icons;s&&(e=t(""),this._addClass(e,"ui-accordion-header-icon","ui-icon "+s.header),e.prependTo(this.headers),i=this.active.children(".ui-accordion-header-icon"),this._removeClass(i,s.header)._addClass(i,null,s.activeHeader)._addClass(this.headers,"ui-accordion-icons")) +},_destroyIcons:function(){this._removeClass(this.headers,"ui-accordion-icons"),this.headers.children(".ui-accordion-header-icon").remove()},_destroy:function(){var t;this.element.removeAttr("role"),this.headers.removeAttr("role aria-expanded aria-selected aria-controls tabIndex").removeUniqueId(),this._destroyIcons(),t=this.headers.next().css("display","").removeAttr("role aria-hidden aria-labelledby").removeUniqueId(),"content"!==this.options.heightStyle&&t.css("height","")},_setOption:function(t,e){return"active"===t?(this._activate(e),void 0):("event"===t&&(this.options.event&&this._off(this.headers,this.options.event),this._setupEvents(e)),this._super(t,e),"collapsible"!==t||e||this.options.active!==!1||this._activate(0),"icons"===t&&(this._destroyIcons(),e&&this._createIcons()),void 0)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",t),this._toggleClass(null,"ui-state-disabled",!!t),this._toggleClass(this.headers.add(this.headers.next()),null,"ui-state-disabled",!!t)},_keydown:function(e){if(!e.altKey&&!e.ctrlKey){var i=t.ui.keyCode,s=this.headers.length,n=this.headers.index(e.target),o=!1;switch(e.keyCode){case i.RIGHT:case i.DOWN:o=this.headers[(n+1)%s];break;case i.LEFT:case i.UP:o=this.headers[(n-1+s)%s];break;case i.SPACE:case i.ENTER:this._eventHandler(e);break;case i.HOME:o=this.headers[0];break;case i.END:o=this.headers[s-1]}o&&(t(e.target).attr("tabIndex",-1),t(o).attr("tabIndex",0),t(o).trigger("focus"),e.preventDefault())}},_panelKeyDown:function(e){e.keyCode===t.ui.keyCode.UP&&e.ctrlKey&&t(e.currentTarget).prev().trigger("focus")},refresh:function(){var e=this.options;this._processPanels(),e.active===!1&&e.collapsible===!0||!this.headers.length?(e.active=!1,this.active=t()):e.active===!1?this._activate(0):this.active.length&&!t.contains(this.element[0],this.active[0])?this.headers.length===this.headers.find(".ui-state-disabled").length?(e.active=!1,this.active=t()):this._activate(Math.max(0,e.active-1)):e.active=this.headers.index(this.active),this._destroyIcons(),this._refresh()},_processPanels:function(){var t=this.headers,e=this.panels;this.headers=this.element.find(this.options.header),this._addClass(this.headers,"ui-accordion-header ui-accordion-header-collapsed","ui-state-default"),this.panels=this.headers.next().filter(":not(.ui-accordion-content-active)").hide(),this._addClass(this.panels,"ui-accordion-content","ui-helper-reset ui-widget-content"),e&&(this._off(t.not(this.headers)),this._off(e.not(this.panels)))},_refresh:function(){var e,i=this.options,s=i.heightStyle,n=this.element.parent();this.active=this._findActive(i.active),this._addClass(this.active,"ui-accordion-header-active","ui-state-active")._removeClass(this.active,"ui-accordion-header-collapsed"),this._addClass(this.active.next(),"ui-accordion-content-active"),this.active.next().show(),this.headers.attr("role","tab").each(function(){var e=t(this),i=e.uniqueId().attr("id"),s=e.next(),n=s.uniqueId().attr("id");e.attr("aria-controls",n),s.attr("aria-labelledby",i)}).next().attr("role","tabpanel"),this.headers.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}).next().attr({"aria-hidden":"true"}).hide(),this.active.length?this.active.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}).next().attr({"aria-hidden":"false"}):this.headers.eq(0).attr("tabIndex",0),this._createIcons(),this._setupEvents(i.event),"fill"===s?(e=n.height(),this.element.siblings(":visible").each(function(){var i=t(this),s=i.css("position");"absolute"!==s&&"fixed"!==s&&(e-=i.outerHeight(!0))}),this.headers.each(function(){e-=t(this).outerHeight(!0)}),this.headers.next().each(function(){t(this).height(Math.max(0,e-t(this).innerHeight()+t(this).height()))}).css("overflow","auto")):"auto"===s&&(e=0,this.headers.next().each(function(){var i=t(this).is(":visible");i||t(this).show(),e=Math.max(e,t(this).css("height","").height()),i||t(this).hide()}).height(e))},_activate:function(e){var i=this._findActive(e)[0];i!==this.active[0]&&(i=i||this.active[0],this._eventHandler({target:i,currentTarget:i,preventDefault:t.noop}))},_findActive:function(e){return"number"==typeof e?this.headers.eq(e):t()},_setupEvents:function(e){var i={keydown:"_keydown"};e&&t.each(e.split(" "),function(t,e){i[e]="_eventHandler"}),this._off(this.headers.add(this.headers.next())),this._on(this.headers,i),this._on(this.headers.next(),{keydown:"_panelKeyDown"}),this._hoverable(this.headers),this._focusable(this.headers)},_eventHandler:function(e){var i,s,n=this.options,o=this.active,a=t(e.currentTarget),r=a[0]===o[0],h=r&&n.collapsible,l=h?t():a.next(),c=o.next(),u={oldHeader:o,oldPanel:c,newHeader:h?t():a,newPanel:l};e.preventDefault(),r&&!n.collapsible||this._trigger("beforeActivate",e,u)===!1||(n.active=h?!1:this.headers.index(a),this.active=r?t():a,this._toggle(u),this._removeClass(o,"ui-accordion-header-active","ui-state-active"),n.icons&&(i=o.children(".ui-accordion-header-icon"),this._removeClass(i,null,n.icons.activeHeader)._addClass(i,null,n.icons.header)),r||(this._removeClass(a,"ui-accordion-header-collapsed")._addClass(a,"ui-accordion-header-active","ui-state-active"),n.icons&&(s=a.children(".ui-accordion-header-icon"),this._removeClass(s,null,n.icons.header)._addClass(s,null,n.icons.activeHeader)),this._addClass(a.next(),"ui-accordion-content-active")))},_toggle:function(e){var i=e.newPanel,s=this.prevShow.length?this.prevShow:e.oldPanel;this.prevShow.add(this.prevHide).stop(!0,!0),this.prevShow=i,this.prevHide=s,this.options.animate?this._animate(i,s,e):(s.hide(),i.show(),this._toggleComplete(e)),s.attr({"aria-hidden":"true"}),s.prev().attr({"aria-selected":"false","aria-expanded":"false"}),i.length&&s.length?s.prev().attr({tabIndex:-1,"aria-expanded":"false"}):i.length&&this.headers.filter(function(){return 0===parseInt(t(this).attr("tabIndex"),10)}).attr("tabIndex",-1),i.attr("aria-hidden","false").prev().attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0})},_animate:function(t,e,i){var s,n,o,a=this,r=0,h=t.css("box-sizing"),l=t.length&&(!e.length||t.index()",delay:300,options:{icons:{submenu:"ui-icon-caret-1-e"},items:"> *",menus:"ul",position:{my:"left top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.mouseHandled=!1,this.element.uniqueId().attr({role:this.options.role,tabIndex:0}),this._addClass("ui-menu","ui-widget ui-widget-content"),this._on({"mousedown .ui-menu-item":function(t){t.preventDefault()},"click .ui-menu-item":function(e){var i=t(e.target),s=t(t.ui.safeActiveElement(this.document[0]));!this.mouseHandled&&i.not(".ui-state-disabled").length&&(this.select(e),e.isPropagationStopped()||(this.mouseHandled=!0),i.has(".ui-menu").length?this.expand(e):!this.element.is(":focus")&&s.closest(".ui-menu").length&&(this.element.trigger("focus",[!0]),this.active&&1===this.active.parents(".ui-menu").length&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":function(e){if(!this.previousFilter){var i=t(e.target).closest(".ui-menu-item"),s=t(e.currentTarget);i[0]===s[0]&&(this._removeClass(s.siblings().children(".ui-state-active"),null,"ui-state-active"),this.focus(e,s))}},mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(t,e){var i=this.active||this.element.find(this.options.items).eq(0);e||this.focus(t,i)},blur:function(e){this._delay(function(){var i=!t.contains(this.element[0],t.ui.safeActiveElement(this.document[0]));i&&this.collapseAll(e)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(t){this._closeOnDocumentClick(t)&&this.collapseAll(t),this.mouseHandled=!1}})},_destroy:function(){var e=this.element.find(".ui-menu-item").removeAttr("role aria-disabled"),i=e.children(".ui-menu-item-wrapper").removeUniqueId().removeAttr("tabIndex role aria-haspopup");this.element.removeAttr("aria-activedescendant").find(".ui-menu").addBack().removeAttr("role aria-labelledby aria-expanded aria-hidden aria-disabled tabIndex").removeUniqueId().show(),i.children().each(function(){var e=t(this);e.data("ui-menu-submenu-caret")&&e.remove()})},_keydown:function(e){var i,s,n,o,a=!0;switch(e.keyCode){case t.ui.keyCode.PAGE_UP:this.previousPage(e);break;case t.ui.keyCode.PAGE_DOWN:this.nextPage(e);break;case t.ui.keyCode.HOME:this._move("first","first",e);break;case t.ui.keyCode.END:this._move("last","last",e);break;case t.ui.keyCode.UP:this.previous(e);break;case t.ui.keyCode.DOWN:this.next(e);break;case t.ui.keyCode.LEFT:this.collapse(e);break;case t.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(e);break;case t.ui.keyCode.ENTER:case t.ui.keyCode.SPACE:this._activate(e);break;case t.ui.keyCode.ESCAPE:this.collapse(e);break;default:a=!1,s=this.previousFilter||"",o=!1,n=e.keyCode>=96&&105>=e.keyCode?""+(e.keyCode-96):String.fromCharCode(e.keyCode),clearTimeout(this.filterTimer),n===s?o=!0:n=s+n,i=this._filterMenuItems(n),i=o&&-1!==i.index(this.active.next())?this.active.nextAll(".ui-menu-item"):i,i.length||(n=String.fromCharCode(e.keyCode),i=this._filterMenuItems(n)),i.length?(this.focus(e,i),this.previousFilter=n,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter}a&&e.preventDefault()},_activate:function(t){this.active&&!this.active.is(".ui-state-disabled")&&(this.active.children("[aria-haspopup='true']").length?this.expand(t):this.select(t))},refresh:function(){var e,i,s,n,o,a=this,r=this.options.icons.submenu,h=this.element.find(this.options.menus);this._toggleClass("ui-menu-icons",null,!!this.element.find(".ui-icon").length),s=h.filter(":not(.ui-menu)").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var e=t(this),i=e.prev(),s=t("").data("ui-menu-submenu-caret",!0);a._addClass(s,"ui-menu-icon","ui-icon "+r),i.attr("aria-haspopup","true").prepend(s),e.attr("aria-labelledby",i.attr("id"))}),this._addClass(s,"ui-menu","ui-widget ui-widget-content ui-front"),e=h.add(this.element),i=e.find(this.options.items),i.not(".ui-menu-item").each(function(){var e=t(this);a._isDivider(e)&&a._addClass(e,"ui-menu-divider","ui-widget-content")}),n=i.not(".ui-menu-item, .ui-menu-divider"),o=n.children().not(".ui-menu").uniqueId().attr({tabIndex:-1,role:this._itemRole()}),this._addClass(n,"ui-menu-item")._addClass(o,"ui-menu-item-wrapper"),i.filter(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!t.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},_setOption:function(t,e){if("icons"===t){var i=this.element.find(".ui-menu-icon");this._removeClass(i,null,this.options.icons.submenu)._addClass(i,null,e.submenu)}this._super(t,e)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",t+""),this._toggleClass(null,"ui-state-disabled",!!t)},focus:function(t,e){var i,s,n;this.blur(t,t&&"focus"===t.type),this._scrollIntoView(e),this.active=e.first(),s=this.active.children(".ui-menu-item-wrapper"),this._addClass(s,null,"ui-state-active"),this.options.role&&this.element.attr("aria-activedescendant",s.attr("id")),n=this.active.parent().closest(".ui-menu-item").children(".ui-menu-item-wrapper"),this._addClass(n,null,"ui-state-active"),t&&"keydown"===t.type?this._close():this.timer=this._delay(function(){this._close()},this.delay),i=e.children(".ui-menu"),i.length&&t&&/^mouse/.test(t.type)&&this._startOpening(i),this.activeMenu=e.parent(),this._trigger("focus",t,{item:e})},_scrollIntoView:function(e){var i,s,n,o,a,r;this._hasScroll()&&(i=parseFloat(t.css(this.activeMenu[0],"borderTopWidth"))||0,s=parseFloat(t.css(this.activeMenu[0],"paddingTop"))||0,n=e.offset().top-this.activeMenu.offset().top-i-s,o=this.activeMenu.scrollTop(),a=this.activeMenu.height(),r=e.outerHeight(),0>n?this.activeMenu.scrollTop(o+n):n+r>a&&this.activeMenu.scrollTop(o+n-a+r))},blur:function(t,e){e||clearTimeout(this.timer),this.active&&(this._removeClass(this.active.children(".ui-menu-item-wrapper"),null,"ui-state-active"),this._trigger("blur",t,{item:this.active}),this.active=null)},_startOpening:function(t){clearTimeout(this.timer),"true"===t.attr("aria-hidden")&&(this.timer=this._delay(function(){this._close(),this._open(t)},this.delay))},_open:function(e){var i=t.extend({of:this.active},this.options.position);clearTimeout(this.timer),this.element.find(".ui-menu").not(e.parents(".ui-menu")).hide().attr("aria-hidden","true"),e.show().removeAttr("aria-hidden").attr("aria-expanded","true").position(i)},collapseAll:function(e,i){clearTimeout(this.timer),this.timer=this._delay(function(){var s=i?this.element:t(e&&e.target).closest(this.element.find(".ui-menu"));s.length||(s=this.element),this._close(s),this.blur(e),this._removeClass(s.find(".ui-state-active"),null,"ui-state-active"),this.activeMenu=s},this.delay)},_close:function(t){t||(t=this.active?this.active.parent():this.element),t.find(".ui-menu").hide().attr("aria-hidden","true").attr("aria-expanded","false")},_closeOnDocumentClick:function(e){return!t(e.target).closest(".ui-menu").length},_isDivider:function(t){return!/[^\-\u2014\u2013\s]/.test(t.text())},collapse:function(t){var e=this.active&&this.active.parent().closest(".ui-menu-item",this.element);e&&e.length&&(this._close(),this.focus(t,e))},expand:function(t){var e=this.active&&this.active.children(".ui-menu ").find(this.options.items).first();e&&e.length&&(this._open(e.parent()),this._delay(function(){this.focus(t,e)}))},next:function(t){this._move("next","first",t)},previous:function(t){this._move("prev","last",t)},isFirstItem:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},isLastItem:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},_move:function(t,e,i){var s;this.active&&(s="first"===t||"last"===t?this.active["first"===t?"prevAll":"nextAll"](".ui-menu-item").eq(-1):this.active[t+"All"](".ui-menu-item").eq(0)),s&&s.length&&this.active||(s=this.activeMenu.find(this.options.items)[e]()),this.focus(i,s)},nextPage:function(e){var i,s,n;return this.active?(this.isLastItem()||(this._hasScroll()?(s=this.active.offset().top,n=this.element.height(),this.active.nextAll(".ui-menu-item").each(function(){return i=t(this),0>i.offset().top-s-n}),this.focus(e,i)):this.focus(e,this.activeMenu.find(this.options.items)[this.active?"last":"first"]())),void 0):(this.next(e),void 0)},previousPage:function(e){var i,s,n;return this.active?(this.isFirstItem()||(this._hasScroll()?(s=this.active.offset().top,n=this.element.height(),this.active.prevAll(".ui-menu-item").each(function(){return i=t(this),i.offset().top-s+n>0}),this.focus(e,i)):this.focus(e,this.activeMenu.find(this.options.items).first())),void 0):(this.next(e),void 0)},_hasScroll:function(){return this.element.outerHeight()",options:{appendTo:null,autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},requestIndex:0,pending:0,_create:function(){var e,i,s,n=this.element[0].nodeName.toLowerCase(),o="textarea"===n,a="input"===n;this.isMultiLine=o||!a&&this._isContentEditable(this.element),this.valueMethod=this.element[o||a?"val":"text"],this.isNewMenu=!0,this._addClass("ui-autocomplete-input"),this.element.attr("autocomplete","off"),this._on(this.element,{keydown:function(n){if(this.element.prop("readOnly"))return e=!0,s=!0,i=!0,void 0;e=!1,s=!1,i=!1;var o=t.ui.keyCode;switch(n.keyCode){case o.PAGE_UP:e=!0,this._move("previousPage",n);break;case o.PAGE_DOWN:e=!0,this._move("nextPage",n);break;case o.UP:e=!0,this._keyEvent("previous",n);break;case o.DOWN:e=!0,this._keyEvent("next",n);break;case o.ENTER:this.menu.active&&(e=!0,n.preventDefault(),this.menu.select(n));break;case o.TAB:this.menu.active&&this.menu.select(n);break;case o.ESCAPE:this.menu.element.is(":visible")&&(this.isMultiLine||this._value(this.term),this.close(n),n.preventDefault());break;default:i=!0,this._searchTimeout(n)}},keypress:function(s){if(e)return e=!1,(!this.isMultiLine||this.menu.element.is(":visible"))&&s.preventDefault(),void 0;if(!i){var n=t.ui.keyCode;switch(s.keyCode){case n.PAGE_UP:this._move("previousPage",s);break;case n.PAGE_DOWN:this._move("nextPage",s);break;case n.UP:this._keyEvent("previous",s);break;case n.DOWN:this._keyEvent("next",s)}}},input:function(t){return s?(s=!1,t.preventDefault(),void 0):(this._searchTimeout(t),void 0)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(t){return this.cancelBlur?(delete this.cancelBlur,void 0):(clearTimeout(this.searching),this.close(t),this._change(t),void 0)}}),this._initSource(),this.menu=t("
    ").appendTo(this._appendTo()).menu({role:null}).hide().menu("instance"),this._addClass(this.menu.element,"ui-autocomplete","ui-front"),this._on(this.menu.element,{mousedown:function(e){e.preventDefault(),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur,this.element[0]!==t.ui.safeActiveElement(this.document[0])&&this.element.trigger("focus")})},menufocus:function(e,i){var s,n;return this.isNewMenu&&(this.isNewMenu=!1,e.originalEvent&&/^mouse/.test(e.originalEvent.type))?(this.menu.blur(),this.document.one("mousemove",function(){t(e.target).trigger(e.originalEvent)}),void 0):(n=i.item.data("ui-autocomplete-item"),!1!==this._trigger("focus",e,{item:n})&&e.originalEvent&&/^key/.test(e.originalEvent.type)&&this._value(n.value),s=i.item.attr("aria-label")||n.value,s&&t.trim(s).length&&(this.liveRegion.children().hide(),t("
    ").text(s).appendTo(this.liveRegion)),void 0)},menuselect:function(e,i){var s=i.item.data("ui-autocomplete-item"),n=this.previous;this.element[0]!==t.ui.safeActiveElement(this.document[0])&&(this.element.trigger("focus"),this.previous=n,this._delay(function(){this.previous=n,this.selectedItem=s})),!1!==this._trigger("select",e,{item:s})&&this._value(s.value),this.term=this._value(),this.close(e),this.selectedItem=s}}),this.liveRegion=t("
    ",{role:"status","aria-live":"assertive","aria-relevant":"additions"}).appendTo(this.document[0].body),this._addClass(this.liveRegion,null,"ui-helper-hidden-accessible"),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_destroy:function(){clearTimeout(this.searching),this.element.removeAttr("autocomplete"),this.menu.element.remove(),this.liveRegion.remove()},_setOption:function(t,e){this._super(t,e),"source"===t&&this._initSource(),"appendTo"===t&&this.menu.element.appendTo(this._appendTo()),"disabled"===t&&e&&this.xhr&&this.xhr.abort()},_isEventTargetInWidget:function(e){var i=this.menu.element[0];return e.target===this.element[0]||e.target===i||t.contains(i,e.target)},_closeOnClickOutside:function(t){this._isEventTargetInWidget(t)||this.close()},_appendTo:function(){var e=this.options.appendTo;return e&&(e=e.jquery||e.nodeType?t(e):this.document.find(e).eq(0)),e&&e[0]||(e=this.element.closest(".ui-front, dialog")),e.length||(e=this.document[0].body),e},_initSource:function(){var e,i,s=this;t.isArray(this.options.source)?(e=this.options.source,this.source=function(i,s){s(t.ui.autocomplete.filter(e,i.term))}):"string"==typeof this.options.source?(i=this.options.source,this.source=function(e,n){s.xhr&&s.xhr.abort(),s.xhr=t.ajax({url:i,data:e,dataType:"json",success:function(t){n(t)},error:function(){n([])}})}):this.source=this.options.source},_searchTimeout:function(t){clearTimeout(this.searching),this.searching=this._delay(function(){var e=this.term===this._value(),i=this.menu.element.is(":visible"),s=t.altKey||t.ctrlKey||t.metaKey||t.shiftKey;(!e||e&&!i&&!s)&&(this.selectedItem=null,this.search(null,t))},this.options.delay)},search:function(t,e){return t=null!=t?t:this._value(),this.term=this._value(),t.length").append(t("
    ").text(i.label)).appendTo(e)},_move:function(t,e){return this.menu.element.is(":visible")?this.menu.isFirstItem()&&/^previous/.test(t)||this.menu.isLastItem()&&/^next/.test(t)?(this.isMultiLine||this._value(this.term),this.menu.blur(),void 0):(this.menu[t](e),void 0):(this.search(null,e),void 0)},widget:function(){return this.menu.element},_value:function(){return this.valueMethod.apply(this.element,arguments)},_keyEvent:function(t,e){(!this.isMultiLine||this.menu.element.is(":visible"))&&(this._move(t,e),e.preventDefault())},_isContentEditable:function(t){if(!t.length)return!1;var e=t.prop("contentEditable");return"inherit"===e?this._isContentEditable(t.parent()):"true"===e}}),t.extend(t.ui.autocomplete,{escapeRegex:function(t){return t.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")},filter:function(e,i){var s=RegExp(t.ui.autocomplete.escapeRegex(i),"i");return t.grep(e,function(t){return s.test(t.label||t.value||t)})}}),t.widget("ui.autocomplete",t.ui.autocomplete,{options:{messages:{noResults:"No search results.",results:function(t){return t+(t>1?" results are":" result is")+" available, use up and down arrow keys to navigate."}}},__response:function(e){var i;this._superApply(arguments),this.options.disabled||this.cancelSearch||(i=e&&e.length?this.options.messages.results(e.length):this.options.messages.noResults,this.liveRegion.children().hide(),t("
    ").text(i).appendTo(this.liveRegion))}}),t.ui.autocomplete;var d=/ui-corner-([a-z]){2,6}/g;t.widget("ui.controlgroup",{version:"1.12.1",defaultElement:"
    ",options:{direction:"horizontal",disabled:null,onlyVisible:!0,items:{button:"input[type=button], input[type=submit], input[type=reset], button, a",controlgroupLabel:".ui-controlgroup-label",checkboxradio:"input[type='checkbox'], input[type='radio']",selectmenu:"select",spinner:".ui-spinner-input"}},_create:function(){this._enhance()},_enhance:function(){this.element.attr("role","toolbar"),this.refresh()},_destroy:function(){this._callChildMethod("destroy"),this.childWidgets.removeData("ui-controlgroup-data"),this.element.removeAttr("role"),this.options.items.controlgroupLabel&&this.element.find(this.options.items.controlgroupLabel).find(".ui-controlgroup-label-contents").contents().unwrap()},_initWidgets:function(){var e=this,i=[];t.each(this.options.items,function(s,n){var o,a={};return n?"controlgroupLabel"===s?(o=e.element.find(n),o.each(function(){var e=t(this);e.children(".ui-controlgroup-label-contents").length||e.contents().wrapAll("")}),e._addClass(o,null,"ui-widget ui-widget-content ui-state-default"),i=i.concat(o.get()),void 0):(t.fn[s]&&(a=e["_"+s+"Options"]?e["_"+s+"Options"]("middle"):{classes:{}},e.element.find(n).each(function(){var n=t(this),o=n[s]("instance"),r=t.widget.extend({},a);if("button"!==s||!n.parent(".ui-spinner").length){o||(o=n[s]()[s]("instance")),o&&(r.classes=e._resolveClassesValues(r.classes,o)),n[s](r);var h=n[s]("widget");t.data(h[0],"ui-controlgroup-data",o?o:n[s]("instance")),i.push(h[0])}})),void 0):void 0}),this.childWidgets=t(t.unique(i)),this._addClass(this.childWidgets,"ui-controlgroup-item")},_callChildMethod:function(e){this.childWidgets.each(function(){var i=t(this),s=i.data("ui-controlgroup-data");s&&s[e]&&s[e]()})},_updateCornerClass:function(t,e){var i="ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all",s=this._buildSimpleOptions(e,"label").classes.label;this._removeClass(t,null,i),this._addClass(t,null,s)},_buildSimpleOptions:function(t,e){var i="vertical"===this.options.direction,s={classes:{}};return s.classes[e]={middle:"",first:"ui-corner-"+(i?"top":"left"),last:"ui-corner-"+(i?"bottom":"right"),only:"ui-corner-all"}[t],s},_spinnerOptions:function(t){var e=this._buildSimpleOptions(t,"ui-spinner");return e.classes["ui-spinner-up"]="",e.classes["ui-spinner-down"]="",e},_buttonOptions:function(t){return this._buildSimpleOptions(t,"ui-button")},_checkboxradioOptions:function(t){return this._buildSimpleOptions(t,"ui-checkboxradio-label")},_selectmenuOptions:function(t){var e="vertical"===this.options.direction;return{width:e?"auto":!1,classes:{middle:{"ui-selectmenu-button-open":"","ui-selectmenu-button-closed":""},first:{"ui-selectmenu-button-open":"ui-corner-"+(e?"top":"tl"),"ui-selectmenu-button-closed":"ui-corner-"+(e?"top":"left")},last:{"ui-selectmenu-button-open":e?"":"ui-corner-tr","ui-selectmenu-button-closed":"ui-corner-"+(e?"bottom":"right")},only:{"ui-selectmenu-button-open":"ui-corner-top","ui-selectmenu-button-closed":"ui-corner-all"}}[t]}},_resolveClassesValues:function(e,i){var s={};return t.each(e,function(n){var o=i.options.classes[n]||"";o=t.trim(o.replace(d,"")),s[n]=(o+" "+e[n]).replace(/\s+/g," ")}),s},_setOption:function(t,e){return"direction"===t&&this._removeClass("ui-controlgroup-"+this.options.direction),this._super(t,e),"disabled"===t?(this._callChildMethod(e?"disable":"enable"),void 0):(this.refresh(),void 0)},refresh:function(){var e,i=this;this._addClass("ui-controlgroup ui-controlgroup-"+this.options.direction),"horizontal"===this.options.direction&&this._addClass(null,"ui-helper-clearfix"),this._initWidgets(),e=this.childWidgets,this.options.onlyVisible&&(e=e.filter(":visible")),e.length&&(t.each(["first","last"],function(t,s){var n=e[s]().data("ui-controlgroup-data");if(n&&i["_"+n.widgetName+"Options"]){var o=i["_"+n.widgetName+"Options"](1===e.length?"only":s);o.classes=i._resolveClassesValues(o.classes,n),n.element[n.widgetName](o)}else i._updateCornerClass(e[s](),s)}),this._callChildMethod("refresh"))}}),t.widget("ui.checkboxradio",[t.ui.formResetMixin,{version:"1.12.1",options:{disabled:null,label:null,icon:!0,classes:{"ui-checkboxradio-label":"ui-corner-all","ui-checkboxradio-icon":"ui-corner-all"}},_getCreateOptions:function(){var e,i,s=this,n=this._super()||{};return this._readType(),i=this.element.labels(),this.label=t(i[i.length-1]),this.label.length||t.error("No label found for checkboxradio widget"),this.originalLabel="",this.label.contents().not(this.element[0]).each(function(){s.originalLabel+=3===this.nodeType?t(this).text():this.outerHTML}),this.originalLabel&&(n.label=this.originalLabel),e=this.element[0].disabled,null!=e&&(n.disabled=e),n},_create:function(){var t=this.element[0].checked;this._bindFormResetHandler(),null==this.options.disabled&&(this.options.disabled=this.element[0].disabled),this._setOption("disabled",this.options.disabled),this._addClass("ui-checkboxradio","ui-helper-hidden-accessible"),this._addClass(this.label,"ui-checkboxradio-label","ui-button ui-widget"),"radio"===this.type&&this._addClass(this.label,"ui-checkboxradio-radio-label"),this.options.label&&this.options.label!==this.originalLabel?this._updateLabel():this.originalLabel&&(this.options.label=this.originalLabel),this._enhance(),t&&(this._addClass(this.label,"ui-checkboxradio-checked","ui-state-active"),this.icon&&this._addClass(this.icon,null,"ui-state-hover")),this._on({change:"_toggleClasses",focus:function(){this._addClass(this.label,null,"ui-state-focus ui-visual-focus")},blur:function(){this._removeClass(this.label,null,"ui-state-focus ui-visual-focus")}})},_readType:function(){var e=this.element[0].nodeName.toLowerCase();this.type=this.element[0].type,"input"===e&&/radio|checkbox/.test(this.type)||t.error("Can't create checkboxradio on element.nodeName="+e+" and element.type="+this.type)},_enhance:function(){this._updateIcon(this.element[0].checked)},widget:function(){return this.label},_getRadioGroup:function(){var e,i=this.element[0].name,s="input[name='"+t.ui.escapeSelector(i)+"']";return i?(e=this.form.length?t(this.form[0].elements).filter(s):t(s).filter(function(){return 0===t(this).form().length}),e.not(this.element)):t([])},_toggleClasses:function(){var e=this.element[0].checked;this._toggleClass(this.label,"ui-checkboxradio-checked","ui-state-active",e),this.options.icon&&"checkbox"===this.type&&this._toggleClass(this.icon,null,"ui-icon-check ui-state-checked",e)._toggleClass(this.icon,null,"ui-icon-blank",!e),"radio"===this.type&&this._getRadioGroup().each(function(){var e=t(this).checkboxradio("instance");e&&e._removeClass(e.label,"ui-checkboxradio-checked","ui-state-active")})},_destroy:function(){this._unbindFormResetHandler(),this.icon&&(this.icon.remove(),this.iconSpace.remove())},_setOption:function(t,e){return"label"!==t||e?(this._super(t,e),"disabled"===t?(this._toggleClass(this.label,null,"ui-state-disabled",e),this.element[0].disabled=e,void 0):(this.refresh(),void 0)):void 0},_updateIcon:function(e){var i="ui-icon ui-icon-background ";this.options.icon?(this.icon||(this.icon=t(""),this.iconSpace=t(" "),this._addClass(this.iconSpace,"ui-checkboxradio-icon-space")),"checkbox"===this.type?(i+=e?"ui-icon-check ui-state-checked":"ui-icon-blank",this._removeClass(this.icon,null,e?"ui-icon-blank":"ui-icon-check")):i+="ui-icon-blank",this._addClass(this.icon,"ui-checkboxradio-icon",i),e||this._removeClass(this.icon,null,"ui-icon-check ui-state-checked"),this.icon.prependTo(this.label).after(this.iconSpace)):void 0!==this.icon&&(this.icon.remove(),this.iconSpace.remove(),delete this.icon) +},_updateLabel:function(){var t=this.label.contents().not(this.element[0]);this.icon&&(t=t.not(this.icon[0])),this.iconSpace&&(t=t.not(this.iconSpace[0])),t.remove(),this.label.append(this.options.label)},refresh:function(){var t=this.element[0].checked,e=this.element[0].disabled;this._updateIcon(t),this._toggleClass(this.label,"ui-checkboxradio-checked","ui-state-active",t),null!==this.options.label&&this._updateLabel(),e!==this.options.disabled&&this._setOptions({disabled:e})}}]),t.ui.checkboxradio,t.widget("ui.button",{version:"1.12.1",defaultElement:"").addClass(this._triggerClass).html(o?t("").attr({src:o,alt:n,title:n}):n)),e[r?"before":"after"](i.trigger),i.trigger.on("click",function(){return t.datepicker._datepickerShowing&&t.datepicker._lastInput===e[0]?t.datepicker._hideDatepicker():t.datepicker._datepickerShowing&&t.datepicker._lastInput!==e[0]?(t.datepicker._hideDatepicker(),t.datepicker._showDatepicker(e[0])):t.datepicker._showDatepicker(e[0]),!1}))},_autoSize:function(t){if(this._get(t,"autoSize")&&!t.inline){var e,i,s,n,o=new Date(2009,11,20),a=this._get(t,"dateFormat");a.match(/[DM]/)&&(e=function(t){for(i=0,s=0,n=0;t.length>n;n++)t[n].length>i&&(i=t[n].length,s=n);return s},o.setMonth(e(this._get(t,a.match(/MM/)?"monthNames":"monthNamesShort"))),o.setDate(e(this._get(t,a.match(/DD/)?"dayNames":"dayNamesShort"))+20-o.getDay())),t.input.attr("size",this._formatDate(t,o).length)}},_inlineDatepicker:function(e,i){var s=t(e);s.hasClass(this.markerClassName)||(s.addClass(this.markerClassName).append(i.dpDiv),t.data(e,"datepicker",i),this._setDate(i,this._getDefaultDate(i),!0),this._updateDatepicker(i),this._updateAlternate(i),i.settings.disabled&&this._disableDatepicker(e),i.dpDiv.css("display","block"))},_dialogDatepicker:function(e,i,s,n,o){var r,h,l,c,u,d=this._dialogInst;return d||(this.uuid+=1,r="dp"+this.uuid,this._dialogInput=t(""),this._dialogInput.on("keydown",this._doKeyDown),t("body").append(this._dialogInput),d=this._dialogInst=this._newInst(this._dialogInput,!1),d.settings={},t.data(this._dialogInput[0],"datepicker",d)),a(d.settings,n||{}),i=i&&i.constructor===Date?this._formatDate(d,i):i,this._dialogInput.val(i),this._pos=o?o.length?o:[o.pageX,o.pageY]:null,this._pos||(h=document.documentElement.clientWidth,l=document.documentElement.clientHeight,c=document.documentElement.scrollLeft||document.body.scrollLeft,u=document.documentElement.scrollTop||document.body.scrollTop,this._pos=[h/2-100+c,l/2-150+u]),this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px"),d.settings.onSelect=s,this._inDialog=!0,this.dpDiv.addClass(this._dialogClass),this._showDatepicker(this._dialogInput[0]),t.blockUI&&t.blockUI(this.dpDiv),t.data(this._dialogInput[0],"datepicker",d),this},_destroyDatepicker:function(e){var i,s=t(e),n=t.data(e,"datepicker");s.hasClass(this.markerClassName)&&(i=e.nodeName.toLowerCase(),t.removeData(e,"datepicker"),"input"===i?(n.append.remove(),n.trigger.remove(),s.removeClass(this.markerClassName).off("focus",this._showDatepicker).off("keydown",this._doKeyDown).off("keypress",this._doKeyPress).off("keyup",this._doKeyUp)):("div"===i||"span"===i)&&s.removeClass(this.markerClassName).empty(),p===n&&(p=null))},_enableDatepicker:function(e){var i,s,n=t(e),o=t.data(e,"datepicker");n.hasClass(this.markerClassName)&&(i=e.nodeName.toLowerCase(),"input"===i?(e.disabled=!1,o.trigger.filter("button").each(function(){this.disabled=!1}).end().filter("img").css({opacity:"1.0",cursor:""})):("div"===i||"span"===i)&&(s=n.children("."+this._inlineClass),s.children().removeClass("ui-state-disabled"),s.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!1)),this._disabledInputs=t.map(this._disabledInputs,function(t){return t===e?null:t}))},_disableDatepicker:function(e){var i,s,n=t(e),o=t.data(e,"datepicker");n.hasClass(this.markerClassName)&&(i=e.nodeName.toLowerCase(),"input"===i?(e.disabled=!0,o.trigger.filter("button").each(function(){this.disabled=!0}).end().filter("img").css({opacity:"0.5",cursor:"default"})):("div"===i||"span"===i)&&(s=n.children("."+this._inlineClass),s.children().addClass("ui-state-disabled"),s.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!0)),this._disabledInputs=t.map(this._disabledInputs,function(t){return t===e?null:t}),this._disabledInputs[this._disabledInputs.length]=e)},_isDisabledDatepicker:function(t){if(!t)return!1;for(var e=0;this._disabledInputs.length>e;e++)if(this._disabledInputs[e]===t)return!0;return!1},_getInst:function(e){try{return t.data(e,"datepicker")}catch(i){throw"Missing instance data for this datepicker"}},_optionDatepicker:function(e,i,s){var n,o,r,h,l=this._getInst(e);return 2===arguments.length&&"string"==typeof i?"defaults"===i?t.extend({},t.datepicker._defaults):l?"all"===i?t.extend({},l.settings):this._get(l,i):null:(n=i||{},"string"==typeof i&&(n={},n[i]=s),l&&(this._curInst===l&&this._hideDatepicker(),o=this._getDateDatepicker(e,!0),r=this._getMinMaxDate(l,"min"),h=this._getMinMaxDate(l,"max"),a(l.settings,n),null!==r&&void 0!==n.dateFormat&&void 0===n.minDate&&(l.settings.minDate=this._formatDate(l,r)),null!==h&&void 0!==n.dateFormat&&void 0===n.maxDate&&(l.settings.maxDate=this._formatDate(l,h)),"disabled"in n&&(n.disabled?this._disableDatepicker(e):this._enableDatepicker(e)),this._attachments(t(e),l),this._autoSize(l),this._setDate(l,o),this._updateAlternate(l),this._updateDatepicker(l)),void 0)},_changeDatepicker:function(t,e,i){this._optionDatepicker(t,e,i)},_refreshDatepicker:function(t){var e=this._getInst(t);e&&this._updateDatepicker(e)},_setDateDatepicker:function(t,e){var i=this._getInst(t);i&&(this._setDate(i,e),this._updateDatepicker(i),this._updateAlternate(i))},_getDateDatepicker:function(t,e){var i=this._getInst(t);return i&&!i.inline&&this._setDateFromField(i,e),i?this._getDate(i):null},_doKeyDown:function(e){var i,s,n,o=t.datepicker._getInst(e.target),a=!0,r=o.dpDiv.is(".ui-datepicker-rtl");if(o._keyEvent=!0,t.datepicker._datepickerShowing)switch(e.keyCode){case 9:t.datepicker._hideDatepicker(),a=!1;break;case 13:return n=t("td."+t.datepicker._dayOverClass+":not(."+t.datepicker._currentClass+")",o.dpDiv),n[0]&&t.datepicker._selectDay(e.target,o.selectedMonth,o.selectedYear,n[0]),i=t.datepicker._get(o,"onSelect"),i?(s=t.datepicker._formatDate(o),i.apply(o.input?o.input[0]:null,[s,o])):t.datepicker._hideDatepicker(),!1;case 27:t.datepicker._hideDatepicker();break;case 33:t.datepicker._adjustDate(e.target,e.ctrlKey?-t.datepicker._get(o,"stepBigMonths"):-t.datepicker._get(o,"stepMonths"),"M");break;case 34:t.datepicker._adjustDate(e.target,e.ctrlKey?+t.datepicker._get(o,"stepBigMonths"):+t.datepicker._get(o,"stepMonths"),"M");break;case 35:(e.ctrlKey||e.metaKey)&&t.datepicker._clearDate(e.target),a=e.ctrlKey||e.metaKey;break;case 36:(e.ctrlKey||e.metaKey)&&t.datepicker._gotoToday(e.target),a=e.ctrlKey||e.metaKey;break;case 37:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,r?1:-1,"D"),a=e.ctrlKey||e.metaKey,e.originalEvent.altKey&&t.datepicker._adjustDate(e.target,e.ctrlKey?-t.datepicker._get(o,"stepBigMonths"):-t.datepicker._get(o,"stepMonths"),"M");break;case 38:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,-7,"D"),a=e.ctrlKey||e.metaKey;break;case 39:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,r?-1:1,"D"),a=e.ctrlKey||e.metaKey,e.originalEvent.altKey&&t.datepicker._adjustDate(e.target,e.ctrlKey?+t.datepicker._get(o,"stepBigMonths"):+t.datepicker._get(o,"stepMonths"),"M");break;case 40:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,7,"D"),a=e.ctrlKey||e.metaKey;break;default:a=!1}else 36===e.keyCode&&e.ctrlKey?t.datepicker._showDatepicker(this):a=!1;a&&(e.preventDefault(),e.stopPropagation())},_doKeyPress:function(e){var i,s,n=t.datepicker._getInst(e.target);return t.datepicker._get(n,"constrainInput")?(i=t.datepicker._possibleChars(t.datepicker._get(n,"dateFormat")),s=String.fromCharCode(null==e.charCode?e.keyCode:e.charCode),e.ctrlKey||e.metaKey||" ">s||!i||i.indexOf(s)>-1):void 0},_doKeyUp:function(e){var i,s=t.datepicker._getInst(e.target);if(s.input.val()!==s.lastVal)try{i=t.datepicker.parseDate(t.datepicker._get(s,"dateFormat"),s.input?s.input.val():null,t.datepicker._getFormatConfig(s)),i&&(t.datepicker._setDateFromField(s),t.datepicker._updateAlternate(s),t.datepicker._updateDatepicker(s))}catch(n){}return!0},_showDatepicker:function(e){if(e=e.target||e,"input"!==e.nodeName.toLowerCase()&&(e=t("input",e.parentNode)[0]),!t.datepicker._isDisabledDatepicker(e)&&t.datepicker._lastInput!==e){var s,n,o,r,h,l,c;s=t.datepicker._getInst(e),t.datepicker._curInst&&t.datepicker._curInst!==s&&(t.datepicker._curInst.dpDiv.stop(!0,!0),s&&t.datepicker._datepickerShowing&&t.datepicker._hideDatepicker(t.datepicker._curInst.input[0])),n=t.datepicker._get(s,"beforeShow"),o=n?n.apply(e,[e,s]):{},o!==!1&&(a(s.settings,o),s.lastVal=null,t.datepicker._lastInput=e,t.datepicker._setDateFromField(s),t.datepicker._inDialog&&(e.value=""),t.datepicker._pos||(t.datepicker._pos=t.datepicker._findPos(e),t.datepicker._pos[1]+=e.offsetHeight),r=!1,t(e).parents().each(function(){return r|="fixed"===t(this).css("position"),!r}),h={left:t.datepicker._pos[0],top:t.datepicker._pos[1]},t.datepicker._pos=null,s.dpDiv.empty(),s.dpDiv.css({position:"absolute",display:"block",top:"-1000px"}),t.datepicker._updateDatepicker(s),h=t.datepicker._checkOffset(s,h,r),s.dpDiv.css({position:t.datepicker._inDialog&&t.blockUI?"static":r?"fixed":"absolute",display:"none",left:h.left+"px",top:h.top+"px"}),s.inline||(l=t.datepicker._get(s,"showAnim"),c=t.datepicker._get(s,"duration"),s.dpDiv.css("z-index",i(t(e))+1),t.datepicker._datepickerShowing=!0,t.effects&&t.effects.effect[l]?s.dpDiv.show(l,t.datepicker._get(s,"showOptions"),c):s.dpDiv[l||"show"](l?c:null),t.datepicker._shouldFocusInput(s)&&s.input.trigger("focus"),t.datepicker._curInst=s))}},_updateDatepicker:function(e){this.maxRows=4,p=e,e.dpDiv.empty().append(this._generateHTML(e)),this._attachHandlers(e);var i,s=this._getNumberOfMonths(e),n=s[1],a=17,r=e.dpDiv.find("."+this._dayOverClass+" a");r.length>0&&o.apply(r.get(0)),e.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""),n>1&&e.dpDiv.addClass("ui-datepicker-multi-"+n).css("width",a*n+"em"),e.dpDiv[(1!==s[0]||1!==s[1]?"add":"remove")+"Class"]("ui-datepicker-multi"),e.dpDiv[(this._get(e,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl"),e===t.datepicker._curInst&&t.datepicker._datepickerShowing&&t.datepicker._shouldFocusInput(e)&&e.input.trigger("focus"),e.yearshtml&&(i=e.yearshtml,setTimeout(function(){i===e.yearshtml&&e.yearshtml&&e.dpDiv.find("select.ui-datepicker-year:first").replaceWith(e.yearshtml),i=e.yearshtml=null},0))},_shouldFocusInput:function(t){return t.input&&t.input.is(":visible")&&!t.input.is(":disabled")&&!t.input.is(":focus")},_checkOffset:function(e,i,s){var n=e.dpDiv.outerWidth(),o=e.dpDiv.outerHeight(),a=e.input?e.input.outerWidth():0,r=e.input?e.input.outerHeight():0,h=document.documentElement.clientWidth+(s?0:t(document).scrollLeft()),l=document.documentElement.clientHeight+(s?0:t(document).scrollTop());return i.left-=this._get(e,"isRTL")?n-a:0,i.left-=s&&i.left===e.input.offset().left?t(document).scrollLeft():0,i.top-=s&&i.top===e.input.offset().top+r?t(document).scrollTop():0,i.left-=Math.min(i.left,i.left+n>h&&h>n?Math.abs(i.left+n-h):0),i.top-=Math.min(i.top,i.top+o>l&&l>o?Math.abs(o+r):0),i},_findPos:function(e){for(var i,s=this._getInst(e),n=this._get(s,"isRTL");e&&("hidden"===e.type||1!==e.nodeType||t.expr.filters.hidden(e));)e=e[n?"previousSibling":"nextSibling"];return i=t(e).offset(),[i.left,i.top]},_hideDatepicker:function(e){var i,s,n,o,a=this._curInst;!a||e&&a!==t.data(e,"datepicker")||this._datepickerShowing&&(i=this._get(a,"showAnim"),s=this._get(a,"duration"),n=function(){t.datepicker._tidyDialog(a)},t.effects&&(t.effects.effect[i]||t.effects[i])?a.dpDiv.hide(i,t.datepicker._get(a,"showOptions"),s,n):a.dpDiv["slideDown"===i?"slideUp":"fadeIn"===i?"fadeOut":"hide"](i?s:null,n),i||n(),this._datepickerShowing=!1,o=this._get(a,"onClose"),o&&o.apply(a.input?a.input[0]:null,[a.input?a.input.val():"",a]),this._lastInput=null,this._inDialog&&(this._dialogInput.css({position:"absolute",left:"0",top:"-100px"}),t.blockUI&&(t.unblockUI(),t("body").append(this.dpDiv))),this._inDialog=!1)},_tidyDialog:function(t){t.dpDiv.removeClass(this._dialogClass).off(".ui-datepicker-calendar")},_checkExternalClick:function(e){if(t.datepicker._curInst){var i=t(e.target),s=t.datepicker._getInst(i[0]);(i[0].id!==t.datepicker._mainDivId&&0===i.parents("#"+t.datepicker._mainDivId).length&&!i.hasClass(t.datepicker.markerClassName)&&!i.closest("."+t.datepicker._triggerClass).length&&t.datepicker._datepickerShowing&&(!t.datepicker._inDialog||!t.blockUI)||i.hasClass(t.datepicker.markerClassName)&&t.datepicker._curInst!==s)&&t.datepicker._hideDatepicker()}},_adjustDate:function(e,i,s){var n=t(e),o=this._getInst(n[0]);this._isDisabledDatepicker(n[0])||(this._adjustInstDate(o,i+("M"===s?this._get(o,"showCurrentAtPos"):0),s),this._updateDatepicker(o))},_gotoToday:function(e){var i,s=t(e),n=this._getInst(s[0]);this._get(n,"gotoCurrent")&&n.currentDay?(n.selectedDay=n.currentDay,n.drawMonth=n.selectedMonth=n.currentMonth,n.drawYear=n.selectedYear=n.currentYear):(i=new Date,n.selectedDay=i.getDate(),n.drawMonth=n.selectedMonth=i.getMonth(),n.drawYear=n.selectedYear=i.getFullYear()),this._notifyChange(n),this._adjustDate(s)},_selectMonthYear:function(e,i,s){var n=t(e),o=this._getInst(n[0]);o["selected"+("M"===s?"Month":"Year")]=o["draw"+("M"===s?"Month":"Year")]=parseInt(i.options[i.selectedIndex].value,10),this._notifyChange(o),this._adjustDate(n)},_selectDay:function(e,i,s,n){var o,a=t(e);t(n).hasClass(this._unselectableClass)||this._isDisabledDatepicker(a[0])||(o=this._getInst(a[0]),o.selectedDay=o.currentDay=t("a",n).html(),o.selectedMonth=o.currentMonth=i,o.selectedYear=o.currentYear=s,this._selectDate(e,this._formatDate(o,o.currentDay,o.currentMonth,o.currentYear)))},_clearDate:function(e){var i=t(e);this._selectDate(i,"")},_selectDate:function(e,i){var s,n=t(e),o=this._getInst(n[0]);i=null!=i?i:this._formatDate(o),o.input&&o.input.val(i),this._updateAlternate(o),s=this._get(o,"onSelect"),s?s.apply(o.input?o.input[0]:null,[i,o]):o.input&&o.input.trigger("change"),o.inline?this._updateDatepicker(o):(this._hideDatepicker(),this._lastInput=o.input[0],"object"!=typeof o.input[0]&&o.input.trigger("focus"),this._lastInput=null)},_updateAlternate:function(e){var i,s,n,o=this._get(e,"altField");o&&(i=this._get(e,"altFormat")||this._get(e,"dateFormat"),s=this._getDate(e),n=this.formatDate(i,s,this._getFormatConfig(e)),t(o).val(n))},noWeekends:function(t){var e=t.getDay();return[e>0&&6>e,""]},iso8601Week:function(t){var e,i=new Date(t.getTime());return i.setDate(i.getDate()+4-(i.getDay()||7)),e=i.getTime(),i.setMonth(0),i.setDate(1),Math.floor(Math.round((e-i)/864e5)/7)+1},parseDate:function(e,i,s){if(null==e||null==i)throw"Invalid arguments";if(i="object"==typeof i?""+i:i+"",""===i)return null;var n,o,a,r,h=0,l=(s?s.shortYearCutoff:null)||this._defaults.shortYearCutoff,c="string"!=typeof l?l:(new Date).getFullYear()%100+parseInt(l,10),u=(s?s.dayNamesShort:null)||this._defaults.dayNamesShort,d=(s?s.dayNames:null)||this._defaults.dayNames,p=(s?s.monthNamesShort:null)||this._defaults.monthNamesShort,f=(s?s.monthNames:null)||this._defaults.monthNames,g=-1,m=-1,_=-1,v=-1,b=!1,y=function(t){var i=e.length>n+1&&e.charAt(n+1)===t;return i&&n++,i},w=function(t){var e=y(t),s="@"===t?14:"!"===t?20:"y"===t&&e?4:"o"===t?3:2,n="y"===t?s:1,o=RegExp("^\\d{"+n+","+s+"}"),a=i.substring(h).match(o);if(!a)throw"Missing number at position "+h;return h+=a[0].length,parseInt(a[0],10)},k=function(e,s,n){var o=-1,a=t.map(y(e)?n:s,function(t,e){return[[e,t]]}).sort(function(t,e){return-(t[1].length-e[1].length)});if(t.each(a,function(t,e){var s=e[1];return i.substr(h,s.length).toLowerCase()===s.toLowerCase()?(o=e[0],h+=s.length,!1):void 0}),-1!==o)return o+1;throw"Unknown name at position "+h},x=function(){if(i.charAt(h)!==e.charAt(n))throw"Unexpected literal at position "+h;h++};for(n=0;e.length>n;n++)if(b)"'"!==e.charAt(n)||y("'")?x():b=!1;else switch(e.charAt(n)){case"d":_=w("d");break;case"D":k("D",u,d);break;case"o":v=w("o");break;case"m":m=w("m");break;case"M":m=k("M",p,f);break;case"y":g=w("y");break;case"@":r=new Date(w("@")),g=r.getFullYear(),m=r.getMonth()+1,_=r.getDate();break;case"!":r=new Date((w("!")-this._ticksTo1970)/1e4),g=r.getFullYear(),m=r.getMonth()+1,_=r.getDate();break;case"'":y("'")?x():b=!0;break;default:x()}if(i.length>h&&(a=i.substr(h),!/^\s+/.test(a)))throw"Extra/unparsed characters found in date: "+a;if(-1===g?g=(new Date).getFullYear():100>g&&(g+=(new Date).getFullYear()-(new Date).getFullYear()%100+(c>=g?0:-100)),v>-1)for(m=1,_=v;;){if(o=this._getDaysInMonth(g,m-1),o>=_)break;m++,_-=o}if(r=this._daylightSavingAdjust(new Date(g,m-1,_)),r.getFullYear()!==g||r.getMonth()+1!==m||r.getDate()!==_)throw"Invalid date";return r},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:1e7*60*60*24*(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925)),formatDate:function(t,e,i){if(!e)return"";var s,n=(i?i.dayNamesShort:null)||this._defaults.dayNamesShort,o=(i?i.dayNames:null)||this._defaults.dayNames,a=(i?i.monthNamesShort:null)||this._defaults.monthNamesShort,r=(i?i.monthNames:null)||this._defaults.monthNames,h=function(e){var i=t.length>s+1&&t.charAt(s+1)===e;return i&&s++,i},l=function(t,e,i){var s=""+e;if(h(t))for(;i>s.length;)s="0"+s;return s},c=function(t,e,i,s){return h(t)?s[e]:i[e]},u="",d=!1;if(e)for(s=0;t.length>s;s++)if(d)"'"!==t.charAt(s)||h("'")?u+=t.charAt(s):d=!1;else switch(t.charAt(s)){case"d":u+=l("d",e.getDate(),2);break;case"D":u+=c("D",e.getDay(),n,o);break;case"o":u+=l("o",Math.round((new Date(e.getFullYear(),e.getMonth(),e.getDate()).getTime()-new Date(e.getFullYear(),0,0).getTime())/864e5),3);break;case"m":u+=l("m",e.getMonth()+1,2);break;case"M":u+=c("M",e.getMonth(),a,r);break;case"y":u+=h("y")?e.getFullYear():(10>e.getFullYear()%100?"0":"")+e.getFullYear()%100;break;case"@":u+=e.getTime();break;case"!":u+=1e4*e.getTime()+this._ticksTo1970;break;case"'":h("'")?u+="'":d=!0;break;default:u+=t.charAt(s)}return u},_possibleChars:function(t){var e,i="",s=!1,n=function(i){var s=t.length>e+1&&t.charAt(e+1)===i;return s&&e++,s};for(e=0;t.length>e;e++)if(s)"'"!==t.charAt(e)||n("'")?i+=t.charAt(e):s=!1;else switch(t.charAt(e)){case"d":case"m":case"y":case"@":i+="0123456789";break;case"D":case"M":return null;case"'":n("'")?i+="'":s=!0;break;default:i+=t.charAt(e)}return i},_get:function(t,e){return void 0!==t.settings[e]?t.settings[e]:this._defaults[e]},_setDateFromField:function(t,e){if(t.input.val()!==t.lastVal){var i=this._get(t,"dateFormat"),s=t.lastVal=t.input?t.input.val():null,n=this._getDefaultDate(t),o=n,a=this._getFormatConfig(t);try{o=this.parseDate(i,s,a)||n}catch(r){s=e?"":s}t.selectedDay=o.getDate(),t.drawMonth=t.selectedMonth=o.getMonth(),t.drawYear=t.selectedYear=o.getFullYear(),t.currentDay=s?o.getDate():0,t.currentMonth=s?o.getMonth():0,t.currentYear=s?o.getFullYear():0,this._adjustInstDate(t)}},_getDefaultDate:function(t){return this._restrictMinMax(t,this._determineDate(t,this._get(t,"defaultDate"),new Date))},_determineDate:function(e,i,s){var n=function(t){var e=new Date;return e.setDate(e.getDate()+t),e},o=function(i){try{return t.datepicker.parseDate(t.datepicker._get(e,"dateFormat"),i,t.datepicker._getFormatConfig(e))}catch(s){}for(var n=(i.toLowerCase().match(/^c/)?t.datepicker._getDate(e):null)||new Date,o=n.getFullYear(),a=n.getMonth(),r=n.getDate(),h=/([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,l=h.exec(i);l;){switch(l[2]||"d"){case"d":case"D":r+=parseInt(l[1],10);break;case"w":case"W":r+=7*parseInt(l[1],10);break;case"m":case"M":a+=parseInt(l[1],10),r=Math.min(r,t.datepicker._getDaysInMonth(o,a));break;case"y":case"Y":o+=parseInt(l[1],10),r=Math.min(r,t.datepicker._getDaysInMonth(o,a))}l=h.exec(i)}return new Date(o,a,r)},a=null==i||""===i?s:"string"==typeof i?o(i):"number"==typeof i?isNaN(i)?s:n(i):new Date(i.getTime());return a=a&&"Invalid Date"==""+a?s:a,a&&(a.setHours(0),a.setMinutes(0),a.setSeconds(0),a.setMilliseconds(0)),this._daylightSavingAdjust(a)},_daylightSavingAdjust:function(t){return t?(t.setHours(t.getHours()>12?t.getHours()+2:0),t):null},_setDate:function(t,e,i){var s=!e,n=t.selectedMonth,o=t.selectedYear,a=this._restrictMinMax(t,this._determineDate(t,e,new Date));t.selectedDay=t.currentDay=a.getDate(),t.drawMonth=t.selectedMonth=t.currentMonth=a.getMonth(),t.drawYear=t.selectedYear=t.currentYear=a.getFullYear(),n===t.selectedMonth&&o===t.selectedYear||i||this._notifyChange(t),this._adjustInstDate(t),t.input&&t.input.val(s?"":this._formatDate(t))},_getDate:function(t){var e=!t.currentYear||t.input&&""===t.input.val()?null:this._daylightSavingAdjust(new Date(t.currentYear,t.currentMonth,t.currentDay));return e},_attachHandlers:function(e){var i=this._get(e,"stepMonths"),s="#"+e.id.replace(/\\\\/g,"\\");e.dpDiv.find("[data-handler]").map(function(){var e={prev:function(){t.datepicker._adjustDate(s,-i,"M")},next:function(){t.datepicker._adjustDate(s,+i,"M")},hide:function(){t.datepicker._hideDatepicker()},today:function(){t.datepicker._gotoToday(s)},selectDay:function(){return t.datepicker._selectDay(s,+this.getAttribute("data-month"),+this.getAttribute("data-year"),this),!1},selectMonth:function(){return t.datepicker._selectMonthYear(s,this,"M"),!1},selectYear:function(){return t.datepicker._selectMonthYear(s,this,"Y"),!1}};t(this).on(this.getAttribute("data-event"),e[this.getAttribute("data-handler")])})},_generateHTML:function(t){var e,i,s,n,o,a,r,h,l,c,u,d,p,f,g,m,_,v,b,y,w,k,x,C,D,I,T,P,M,S,H,z,O,A,N,W,E,F,L,R=new Date,B=this._daylightSavingAdjust(new Date(R.getFullYear(),R.getMonth(),R.getDate())),Y=this._get(t,"isRTL"),j=this._get(t,"showButtonPanel"),q=this._get(t,"hideIfNoPrevNext"),K=this._get(t,"navigationAsDateFormat"),U=this._getNumberOfMonths(t),V=this._get(t,"showCurrentAtPos"),$=this._get(t,"stepMonths"),X=1!==U[0]||1!==U[1],G=this._daylightSavingAdjust(t.currentDay?new Date(t.currentYear,t.currentMonth,t.currentDay):new Date(9999,9,9)),Q=this._getMinMaxDate(t,"min"),J=this._getMinMaxDate(t,"max"),Z=t.drawMonth-V,te=t.drawYear;if(0>Z&&(Z+=12,te--),J)for(e=this._daylightSavingAdjust(new Date(J.getFullYear(),J.getMonth()-U[0]*U[1]+1,J.getDate())),e=Q&&Q>e?Q:e;this._daylightSavingAdjust(new Date(te,Z,1))>e;)Z--,0>Z&&(Z=11,te--);for(t.drawMonth=Z,t.drawYear=te,i=this._get(t,"prevText"),i=K?this.formatDate(i,this._daylightSavingAdjust(new Date(te,Z-$,1)),this._getFormatConfig(t)):i,s=this._canAdjustMonth(t,-1,te,Z)?""+i+"":q?"":""+i+"",n=this._get(t,"nextText"),n=K?this.formatDate(n,this._daylightSavingAdjust(new Date(te,Z+$,1)),this._getFormatConfig(t)):n,o=this._canAdjustMonth(t,1,te,Z)?""+n+"":q?"":""+n+"",a=this._get(t,"currentText"),r=this._get(t,"gotoCurrent")&&t.currentDay?G:B,a=K?this.formatDate(a,r,this._getFormatConfig(t)):a,h=t.inline?"":"",l=j?"
    "+(Y?h:"")+(this._isInRange(t,r)?"":"")+(Y?"":h)+"
    ":"",c=parseInt(this._get(t,"firstDay"),10),c=isNaN(c)?0:c,u=this._get(t,"showWeek"),d=this._get(t,"dayNames"),p=this._get(t,"dayNamesMin"),f=this._get(t,"monthNames"),g=this._get(t,"monthNamesShort"),m=this._get(t,"beforeShowDay"),_=this._get(t,"showOtherMonths"),v=this._get(t,"selectOtherMonths"),b=this._getDefaultDate(t),y="",k=0;U[0]>k;k++){for(x="",this.maxRows=4,C=0;U[1]>C;C++){if(D=this._daylightSavingAdjust(new Date(te,Z,t.selectedDay)),I=" ui-corner-all",T="",X){if(T+="
    "}for(T+="
    "+(/all|left/.test(I)&&0===k?Y?o:s:"")+(/all|right/.test(I)&&0===k?Y?s:o:"")+this._generateMonthYearHeader(t,Z,te,Q,J,k>0||C>0,f,g)+"
    "+"",P=u?"":"",w=0;7>w;w++)M=(w+c)%7,P+="";for(T+=P+"",S=this._getDaysInMonth(te,Z),te===t.selectedYear&&Z===t.selectedMonth&&(t.selectedDay=Math.min(t.selectedDay,S)),H=(this._getFirstDayOfMonth(te,Z)-c+7)%7,z=Math.ceil((H+S)/7),O=X?this.maxRows>z?this.maxRows:z:z,this.maxRows=O,A=this._daylightSavingAdjust(new Date(te,Z,1-H)),N=0;O>N;N++){for(T+="",W=u?"":"",w=0;7>w;w++)E=m?m.apply(t.input?t.input[0]:null,[A]):[!0,""],F=A.getMonth()!==Z,L=F&&!v||!E[0]||Q&&Q>A||J&&A>J,W+="",A.setDate(A.getDate()+1),A=this._daylightSavingAdjust(A);T+=W+""}Z++,Z>11&&(Z=0,te++),T+="
    "+this._get(t,"weekHeader")+"=5?" class='ui-datepicker-week-end'":"")+">"+""+p[M]+"
    "+this._get(t,"calculateWeek")(A)+""+(F&&!_?" ":L?""+A.getDate()+"":""+A.getDate()+"")+"
    "+(X?"
    "+(U[0]>0&&C===U[1]-1?"
    ":""):""),x+=T}y+=x}return y+=l,t._keyEvent=!1,y},_generateMonthYearHeader:function(t,e,i,s,n,o,a,r){var h,l,c,u,d,p,f,g,m=this._get(t,"changeMonth"),_=this._get(t,"changeYear"),v=this._get(t,"showMonthAfterYear"),b="
    ",y="";if(o||!m)y+=""+a[e]+"";else{for(h=s&&s.getFullYear()===i,l=n&&n.getFullYear()===i,y+=""}if(v||(b+=y+(!o&&m&&_?"":" ")),!t.yearshtml)if(t.yearshtml="",o||!_)b+=""+i+"";else{for(u=this._get(t,"yearRange").split(":"),d=(new Date).getFullYear(),p=function(t){var e=t.match(/c[+\-].*/)?i+parseInt(t.substring(1),10):t.match(/[+\-].*/)?d+parseInt(t,10):parseInt(t,10);return isNaN(e)?d:e},f=p(u[0]),g=Math.max(f,p(u[1]||"")),f=s?Math.max(f,s.getFullYear()):f,g=n?Math.min(g,n.getFullYear()):g,t.yearshtml+="",b+=t.yearshtml,t.yearshtml=null}return b+=this._get(t,"yearSuffix"),v&&(b+=(!o&&m&&_?"":" ")+y),b+="
    "},_adjustInstDate:function(t,e,i){var s=t.selectedYear+("Y"===i?e:0),n=t.selectedMonth+("M"===i?e:0),o=Math.min(t.selectedDay,this._getDaysInMonth(s,n))+("D"===i?e:0),a=this._restrictMinMax(t,this._daylightSavingAdjust(new Date(s,n,o)));t.selectedDay=a.getDate(),t.drawMonth=t.selectedMonth=a.getMonth(),t.drawYear=t.selectedYear=a.getFullYear(),("M"===i||"Y"===i)&&this._notifyChange(t)},_restrictMinMax:function(t,e){var i=this._getMinMaxDate(t,"min"),s=this._getMinMaxDate(t,"max"),n=i&&i>e?i:e;return s&&n>s?s:n},_notifyChange:function(t){var e=this._get(t,"onChangeMonthYear");e&&e.apply(t.input?t.input[0]:null,[t.selectedYear,t.selectedMonth+1,t])},_getNumberOfMonths:function(t){var e=this._get(t,"numberOfMonths");return null==e?[1,1]:"number"==typeof e?[1,e]:e},_getMinMaxDate:function(t,e){return this._determineDate(t,this._get(t,e+"Date"),null)},_getDaysInMonth:function(t,e){return 32-this._daylightSavingAdjust(new Date(t,e,32)).getDate()},_getFirstDayOfMonth:function(t,e){return new Date(t,e,1).getDay()},_canAdjustMonth:function(t,e,i,s){var n=this._getNumberOfMonths(t),o=this._daylightSavingAdjust(new Date(i,s+(0>e?e:n[0]*n[1]),1));return 0>e&&o.setDate(this._getDaysInMonth(o.getFullYear(),o.getMonth())),this._isInRange(t,o)},_isInRange:function(t,e){var i,s,n=this._getMinMaxDate(t,"min"),o=this._getMinMaxDate(t,"max"),a=null,r=null,h=this._get(t,"yearRange");return h&&(i=h.split(":"),s=(new Date).getFullYear(),a=parseInt(i[0],10),r=parseInt(i[1],10),i[0].match(/[+\-].*/)&&(a+=s),i[1].match(/[+\-].*/)&&(r+=s)),(!n||e.getTime()>=n.getTime())&&(!o||e.getTime()<=o.getTime())&&(!a||e.getFullYear()>=a)&&(!r||r>=e.getFullYear())},_getFormatConfig:function(t){var e=this._get(t,"shortYearCutoff");return e="string"!=typeof e?e:(new Date).getFullYear()%100+parseInt(e,10),{shortYearCutoff:e,dayNamesShort:this._get(t,"dayNamesShort"),dayNames:this._get(t,"dayNames"),monthNamesShort:this._get(t,"monthNamesShort"),monthNames:this._get(t,"monthNames")}},_formatDate:function(t,e,i,s){e||(t.currentDay=t.selectedDay,t.currentMonth=t.selectedMonth,t.currentYear=t.selectedYear);var n=e?"object"==typeof e?e:this._daylightSavingAdjust(new Date(s,i,e)):this._daylightSavingAdjust(new Date(t.currentYear,t.currentMonth,t.currentDay));return this.formatDate(this._get(t,"dateFormat"),n,this._getFormatConfig(t))}}),t.fn.datepicker=function(e){if(!this.length)return this;t.datepicker.initialized||(t(document).on("mousedown",t.datepicker._checkExternalClick),t.datepicker.initialized=!0),0===t("#"+t.datepicker._mainDivId).length&&t("body").append(t.datepicker.dpDiv);var i=Array.prototype.slice.call(arguments,1);return"string"!=typeof e||"isDisabled"!==e&&"getDate"!==e&&"widget"!==e?"option"===e&&2===arguments.length&&"string"==typeof arguments[1]?t.datepicker["_"+e+"Datepicker"].apply(t.datepicker,[this[0]].concat(i)):this.each(function(){"string"==typeof e?t.datepicker["_"+e+"Datepicker"].apply(t.datepicker,[this].concat(i)):t.datepicker._attachDatepicker(this,e)}):t.datepicker["_"+e+"Datepicker"].apply(t.datepicker,[this[0]].concat(i))},t.datepicker=new s,t.datepicker.initialized=!1,t.datepicker.uuid=(new Date).getTime(),t.datepicker.version="1.12.1",t.datepicker,t.widget("ui.dialog",{version:"1.12.1",options:{appendTo:"body",autoOpen:!0,buttons:[],classes:{"ui-dialog":"ui-corner-all","ui-dialog-titlebar":"ui-corner-all"},closeOnEscape:!0,closeText:"Close",draggable:!0,hide:null,height:"auto",maxHeight:null,maxWidth:null,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",of:window,collision:"fit",using:function(e){var i=t(this).css(e).offset().top;0>i&&t(this).css("top",e.top-i)}},resizable:!0,show:null,title:null,width:300,beforeClose:null,close:null,drag:null,dragStart:null,dragStop:null,focus:null,open:null,resize:null,resizeStart:null,resizeStop:null},sizeRelatedOptions:{buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},resizableRelatedOptions:{maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0},_create:function(){this.originalCss={display:this.element[0].style.display,width:this.element[0].style.width,minHeight:this.element[0].style.minHeight,maxHeight:this.element[0].style.maxHeight,height:this.element[0].style.height},this.originalPosition={parent:this.element.parent(),index:this.element.parent().children().index(this.element)},this.originalTitle=this.element.attr("title"),null==this.options.title&&null!=this.originalTitle&&(this.options.title=this.originalTitle),this.options.disabled&&(this.options.disabled=!1),this._createWrapper(),this.element.show().removeAttr("title").appendTo(this.uiDialog),this._addClass("ui-dialog-content","ui-widget-content"),this._createTitlebar(),this._createButtonPane(),this.options.draggable&&t.fn.draggable&&this._makeDraggable(),this.options.resizable&&t.fn.resizable&&this._makeResizable(),this._isOpen=!1,this._trackFocus()},_init:function(){this.options.autoOpen&&this.open()},_appendTo:function(){var e=this.options.appendTo;return e&&(e.jquery||e.nodeType)?t(e):this.document.find(e||"body").eq(0)},_destroy:function(){var t,e=this.originalPosition;this._untrackInstance(),this._destroyOverlay(),this.element.removeUniqueId().css(this.originalCss).detach(),this.uiDialog.remove(),this.originalTitle&&this.element.attr("title",this.originalTitle),t=e.parent.children().eq(e.index),t.length&&t[0]!==this.element[0]?t.before(this.element):e.parent.append(this.element)},widget:function(){return this.uiDialog},disable:t.noop,enable:t.noop,close:function(e){var i=this;this._isOpen&&this._trigger("beforeClose",e)!==!1&&(this._isOpen=!1,this._focusedElement=null,this._destroyOverlay(),this._untrackInstance(),this.opener.filter(":focusable").trigger("focus").length||t.ui.safeBlur(t.ui.safeActiveElement(this.document[0])),this._hide(this.uiDialog,this.options.hide,function(){i._trigger("close",e)}))},isOpen:function(){return this._isOpen},moveToTop:function(){this._moveToTop()},_moveToTop:function(e,i){var s=!1,n=this.uiDialog.siblings(".ui-front:visible").map(function(){return+t(this).css("z-index")}).get(),o=Math.max.apply(null,n);return o>=+this.uiDialog.css("z-index")&&(this.uiDialog.css("z-index",o+1),s=!0),s&&!i&&this._trigger("focus",e),s},open:function(){var e=this;return this._isOpen?(this._moveToTop()&&this._focusTabbable(),void 0):(this._isOpen=!0,this.opener=t(t.ui.safeActiveElement(this.document[0])),this._size(),this._position(),this._createOverlay(),this._moveToTop(null,!0),this.overlay&&this.overlay.css("z-index",this.uiDialog.css("z-index")-1),this._show(this.uiDialog,this.options.show,function(){e._focusTabbable(),e._trigger("focus")}),this._makeFocusTarget(),this._trigger("open"),void 0)},_focusTabbable:function(){var t=this._focusedElement;t||(t=this.element.find("[autofocus]")),t.length||(t=this.element.find(":tabbable")),t.length||(t=this.uiDialogButtonPane.find(":tabbable")),t.length||(t=this.uiDialogTitlebarClose.filter(":tabbable")),t.length||(t=this.uiDialog),t.eq(0).trigger("focus")},_keepFocus:function(e){function i(){var e=t.ui.safeActiveElement(this.document[0]),i=this.uiDialog[0]===e||t.contains(this.uiDialog[0],e);i||this._focusTabbable()}e.preventDefault(),i.call(this),this._delay(i)},_createWrapper:function(){this.uiDialog=t("
    ").hide().attr({tabIndex:-1,role:"dialog"}).appendTo(this._appendTo()),this._addClass(this.uiDialog,"ui-dialog","ui-widget ui-widget-content ui-front"),this._on(this.uiDialog,{keydown:function(e){if(this.options.closeOnEscape&&!e.isDefaultPrevented()&&e.keyCode&&e.keyCode===t.ui.keyCode.ESCAPE)return e.preventDefault(),this.close(e),void 0;if(e.keyCode===t.ui.keyCode.TAB&&!e.isDefaultPrevented()){var i=this.uiDialog.find(":tabbable"),s=i.filter(":first"),n=i.filter(":last");e.target!==n[0]&&e.target!==this.uiDialog[0]||e.shiftKey?e.target!==s[0]&&e.target!==this.uiDialog[0]||!e.shiftKey||(this._delay(function(){n.trigger("focus")}),e.preventDefault()):(this._delay(function(){s.trigger("focus")}),e.preventDefault())}},mousedown:function(t){this._moveToTop(t)&&this._focusTabbable()}}),this.element.find("[aria-describedby]").length||this.uiDialog.attr({"aria-describedby":this.element.uniqueId().attr("id")})},_createTitlebar:function(){var e;this.uiDialogTitlebar=t("
    "),this._addClass(this.uiDialogTitlebar,"ui-dialog-titlebar","ui-widget-header ui-helper-clearfix"),this._on(this.uiDialogTitlebar,{mousedown:function(e){t(e.target).closest(".ui-dialog-titlebar-close")||this.uiDialog.trigger("focus")}}),this.uiDialogTitlebarClose=t("").button({label:t("").text(this.options.closeText).html(),icon:"ui-icon-closethick",showLabel:!1}).appendTo(this.uiDialogTitlebar),this._addClass(this.uiDialogTitlebarClose,"ui-dialog-titlebar-close"),this._on(this.uiDialogTitlebarClose,{click:function(t){t.preventDefault(),this.close(t)}}),e=t("").uniqueId().prependTo(this.uiDialogTitlebar),this._addClass(e,"ui-dialog-title"),this._title(e),this.uiDialogTitlebar.prependTo(this.uiDialog),this.uiDialog.attr({"aria-labelledby":e.attr("id")})},_title:function(t){this.options.title?t.text(this.options.title):t.html(" ")},_createButtonPane:function(){this.uiDialogButtonPane=t("
    "),this._addClass(this.uiDialogButtonPane,"ui-dialog-buttonpane","ui-widget-content ui-helper-clearfix"),this.uiButtonSet=t("
    ").appendTo(this.uiDialogButtonPane),this._addClass(this.uiButtonSet,"ui-dialog-buttonset"),this._createButtons()},_createButtons:function(){var e=this,i=this.options.buttons;return this.uiDialogButtonPane.remove(),this.uiButtonSet.empty(),t.isEmptyObject(i)||t.isArray(i)&&!i.length?(this._removeClass(this.uiDialog,"ui-dialog-buttons"),void 0):(t.each(i,function(i,s){var n,o;s=t.isFunction(s)?{click:s,text:i}:s,s=t.extend({type:"button"},s),n=s.click,o={icon:s.icon,iconPosition:s.iconPosition,showLabel:s.showLabel,icons:s.icons,text:s.text},delete s.click,delete s.icon,delete s.iconPosition,delete s.showLabel,delete s.icons,"boolean"==typeof s.text&&delete s.text,t("",s).button(o).appendTo(e.uiButtonSet).on("click",function(){n.apply(e.element[0],arguments)})}),this._addClass(this.uiDialog,"ui-dialog-buttons"),this.uiDialogButtonPane.appendTo(this.uiDialog),void 0)},_makeDraggable:function(){function e(t){return{position:t.position,offset:t.offset}}var i=this,s=this.options;this.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(s,n){i._addClass(t(this),"ui-dialog-dragging"),i._blockFrames(),i._trigger("dragStart",s,e(n))},drag:function(t,s){i._trigger("drag",t,e(s))},stop:function(n,o){var a=o.offset.left-i.document.scrollLeft(),r=o.offset.top-i.document.scrollTop();s.position={my:"left top",at:"left"+(a>=0?"+":"")+a+" "+"top"+(r>=0?"+":"")+r,of:i.window},i._removeClass(t(this),"ui-dialog-dragging"),i._unblockFrames(),i._trigger("dragStop",n,e(o))}})},_makeResizable:function(){function e(t){return{originalPosition:t.originalPosition,originalSize:t.originalSize,position:t.position,size:t.size}}var i=this,s=this.options,n=s.resizable,o=this.uiDialog.css("position"),a="string"==typeof n?n:"n,e,s,w,se,sw,ne,nw";this.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:this.element,maxWidth:s.maxWidth,maxHeight:s.maxHeight,minWidth:s.minWidth,minHeight:this._minHeight(),handles:a,start:function(s,n){i._addClass(t(this),"ui-dialog-resizing"),i._blockFrames(),i._trigger("resizeStart",s,e(n))},resize:function(t,s){i._trigger("resize",t,e(s))},stop:function(n,o){var a=i.uiDialog.offset(),r=a.left-i.document.scrollLeft(),h=a.top-i.document.scrollTop();s.height=i.uiDialog.height(),s.width=i.uiDialog.width(),s.position={my:"left top",at:"left"+(r>=0?"+":"")+r+" "+"top"+(h>=0?"+":"")+h,of:i.window},i._removeClass(t(this),"ui-dialog-resizing"),i._unblockFrames(),i._trigger("resizeStop",n,e(o))}}).css("position",o)},_trackFocus:function(){this._on(this.widget(),{focusin:function(e){this._makeFocusTarget(),this._focusedElement=t(e.target)}})},_makeFocusTarget:function(){this._untrackInstance(),this._trackingInstances().unshift(this)},_untrackInstance:function(){var e=this._trackingInstances(),i=t.inArray(this,e);-1!==i&&e.splice(i,1)},_trackingInstances:function(){var t=this.document.data("ui-dialog-instances");return t||(t=[],this.document.data("ui-dialog-instances",t)),t},_minHeight:function(){var t=this.options;return"auto"===t.height?t.minHeight:Math.min(t.minHeight,t.height)},_position:function(){var t=this.uiDialog.is(":visible");t||this.uiDialog.show(),this.uiDialog.position(this.options.position),t||this.uiDialog.hide()},_setOptions:function(e){var i=this,s=!1,n={};t.each(e,function(t,e){i._setOption(t,e),t in i.sizeRelatedOptions&&(s=!0),t in i.resizableRelatedOptions&&(n[t]=e)}),s&&(this._size(),this._position()),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option",n)},_setOption:function(e,i){var s,n,o=this.uiDialog;"disabled"!==e&&(this._super(e,i),"appendTo"===e&&this.uiDialog.appendTo(this._appendTo()),"buttons"===e&&this._createButtons(),"closeText"===e&&this.uiDialogTitlebarClose.button({label:t("").text(""+this.options.closeText).html()}),"draggable"===e&&(s=o.is(":data(ui-draggable)"),s&&!i&&o.draggable("destroy"),!s&&i&&this._makeDraggable()),"position"===e&&this._position(),"resizable"===e&&(n=o.is(":data(ui-resizable)"),n&&!i&&o.resizable("destroy"),n&&"string"==typeof i&&o.resizable("option","handles",i),n||i===!1||this._makeResizable()),"title"===e&&this._title(this.uiDialogTitlebar.find(".ui-dialog-title")))},_size:function(){var t,e,i,s=this.options;this.element.show().css({width:"auto",minHeight:0,maxHeight:"none",height:0}),s.minWidth>s.width&&(s.width=s.minWidth),t=this.uiDialog.css({height:"auto",width:s.width}).outerHeight(),e=Math.max(0,s.minHeight-t),i="number"==typeof s.maxHeight?Math.max(0,s.maxHeight-t):"none","auto"===s.height?this.element.css({minHeight:e,maxHeight:i,height:"auto"}):this.element.height(Math.max(0,s.height-t)),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())},_blockFrames:function(){this.iframeBlocks=this.document.find("iframe").map(function(){var e=t(this);return t("
    ").css({position:"absolute",width:e.outerWidth(),height:e.outerHeight()}).appendTo(e.parent()).offset(e.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_allowInteraction:function(e){return t(e.target).closest(".ui-dialog").length?!0:!!t(e.target).closest(".ui-datepicker").length},_createOverlay:function(){if(this.options.modal){var e=!0;this._delay(function(){e=!1}),this.document.data("ui-dialog-overlays")||this._on(this.document,{focusin:function(t){e||this._allowInteraction(t)||(t.preventDefault(),this._trackingInstances()[0]._focusTabbable())}}),this.overlay=t("
    ").appendTo(this._appendTo()),this._addClass(this.overlay,null,"ui-widget-overlay ui-front"),this._on(this.overlay,{mousedown:"_keepFocus"}),this.document.data("ui-dialog-overlays",(this.document.data("ui-dialog-overlays")||0)+1)}},_destroyOverlay:function(){if(this.options.modal&&this.overlay){var t=this.document.data("ui-dialog-overlays")-1;t?this.document.data("ui-dialog-overlays",t):(this._off(this.document,"focusin"),this.document.removeData("ui-dialog-overlays")),this.overlay.remove(),this.overlay=null}}}),t.uiBackCompat!==!1&&t.widget("ui.dialog",t.ui.dialog,{options:{dialogClass:""},_createWrapper:function(){this._super(),this.uiDialog.addClass(this.options.dialogClass)},_setOption:function(t,e){"dialogClass"===t&&this.uiDialog.removeClass(this.options.dialogClass).addClass(e),this._superApply(arguments)}}),t.ui.dialog,t.widget("ui.progressbar",{version:"1.12.1",options:{classes:{"ui-progressbar":"ui-corner-all","ui-progressbar-value":"ui-corner-left","ui-progressbar-complete":"ui-corner-right"},max:100,value:0,change:null,complete:null},min:0,_create:function(){this.oldValue=this.options.value=this._constrainedValue(),this.element.attr({role:"progressbar","aria-valuemin":this.min}),this._addClass("ui-progressbar","ui-widget ui-widget-content"),this.valueDiv=t("
    ").appendTo(this.element),this._addClass(this.valueDiv,"ui-progressbar-value","ui-widget-header"),this._refreshValue()},_destroy:function(){this.element.removeAttr("role aria-valuemin aria-valuemax aria-valuenow"),this.valueDiv.remove()},value:function(t){return void 0===t?this.options.value:(this.options.value=this._constrainedValue(t),this._refreshValue(),void 0)},_constrainedValue:function(t){return void 0===t&&(t=this.options.value),this.indeterminate=t===!1,"number"!=typeof t&&(t=0),this.indeterminate?!1:Math.min(this.options.max,Math.max(this.min,t))},_setOptions:function(t){var e=t.value;delete t.value,this._super(t),this.options.value=this._constrainedValue(e),this._refreshValue()},_setOption:function(t,e){"max"===t&&(e=Math.max(this.min,e)),this._super(t,e)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",t),this._toggleClass(null,"ui-state-disabled",!!t)},_percentage:function(){return this.indeterminate?100:100*(this.options.value-this.min)/(this.options.max-this.min)},_refreshValue:function(){var e=this.options.value,i=this._percentage();this.valueDiv.toggle(this.indeterminate||e>this.min).width(i.toFixed(0)+"%"),this._toggleClass(this.valueDiv,"ui-progressbar-complete",null,e===this.options.max)._toggleClass("ui-progressbar-indeterminate",null,this.indeterminate),this.indeterminate?(this.element.removeAttr("aria-valuenow"),this.overlayDiv||(this.overlayDiv=t("
    ").appendTo(this.valueDiv),this._addClass(this.overlayDiv,"ui-progressbar-overlay"))):(this.element.attr({"aria-valuemax":this.options.max,"aria-valuenow":e}),this.overlayDiv&&(this.overlayDiv.remove(),this.overlayDiv=null)),this.oldValue!==e&&(this.oldValue=e,this._trigger("change")),e===this.options.max&&this._trigger("complete")}}),t.widget("ui.selectmenu",[t.ui.formResetMixin,{version:"1.12.1",defaultElement:"",widgetEventPrefix:"spin",options:{classes:{"ui-spinner":"ui-corner-all","ui-spinner-down":"ui-corner-br","ui-spinner-up":"ui-corner-tr"},culture:null,icons:{down:"ui-icon-triangle-1-s",up:"ui-icon-triangle-1-n"},incremental:!0,max:null,min:null,numberFormat:null,page:10,step:1,change:null,spin:null,start:null,stop:null},_create:function(){this._setOption("max",this.options.max),this._setOption("min",this.options.min),this._setOption("step",this.options.step),""!==this.value()&&this._value(this.element.val(),!0),this._draw(),this._on(this._events),this._refresh(),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_getCreateOptions:function(){var e=this._super(),i=this.element;return t.each(["min","max","step"],function(t,s){var n=i.attr(s);null!=n&&n.length&&(e[s]=n)}),e},_events:{keydown:function(t){this._start(t)&&this._keydown(t)&&t.preventDefault()},keyup:"_stop",focus:function(){this.previous=this.element.val()},blur:function(t){return this.cancelBlur?(delete this.cancelBlur,void 0):(this._stop(),this._refresh(),this.previous!==this.element.val()&&this._trigger("change",t),void 0)},mousewheel:function(t,e){if(e){if(!this.spinning&&!this._start(t))return!1;this._spin((e>0?1:-1)*this.options.step,t),clearTimeout(this.mousewheelTimer),this.mousewheelTimer=this._delay(function(){this.spinning&&this._stop(t)},100),t.preventDefault()}},"mousedown .ui-spinner-button":function(e){function i(){var e=this.element[0]===t.ui.safeActiveElement(this.document[0]);e||(this.element.trigger("focus"),this.previous=s,this._delay(function(){this.previous=s}))}var s;s=this.element[0]===t.ui.safeActiveElement(this.document[0])?this.previous:this.element.val(),e.preventDefault(),i.call(this),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur,i.call(this)}),this._start(e)!==!1&&this._repeat(null,t(e.currentTarget).hasClass("ui-spinner-up")?1:-1,e)},"mouseup .ui-spinner-button":"_stop","mouseenter .ui-spinner-button":function(e){return t(e.currentTarget).hasClass("ui-state-active")?this._start(e)===!1?!1:(this._repeat(null,t(e.currentTarget).hasClass("ui-spinner-up")?1:-1,e),void 0):void 0},"mouseleave .ui-spinner-button":"_stop"},_enhance:function(){this.uiSpinner=this.element.attr("autocomplete","off").wrap("").parent().append("")},_draw:function(){this._enhance(),this._addClass(this.uiSpinner,"ui-spinner","ui-widget ui-widget-content"),this._addClass("ui-spinner-input"),this.element.attr("role","spinbutton"),this.buttons=this.uiSpinner.children("a").attr("tabIndex",-1).attr("aria-hidden",!0).button({classes:{"ui-button":""}}),this._removeClass(this.buttons,"ui-corner-all"),this._addClass(this.buttons.first(),"ui-spinner-button ui-spinner-up"),this._addClass(this.buttons.last(),"ui-spinner-button ui-spinner-down"),this.buttons.first().button({icon:this.options.icons.up,showLabel:!1}),this.buttons.last().button({icon:this.options.icons.down,showLabel:!1}),this.buttons.height()>Math.ceil(.5*this.uiSpinner.height())&&this.uiSpinner.height()>0&&this.uiSpinner.height(this.uiSpinner.height())},_keydown:function(e){var i=this.options,s=t.ui.keyCode;switch(e.keyCode){case s.UP:return this._repeat(null,1,e),!0;case s.DOWN:return this._repeat(null,-1,e),!0;case s.PAGE_UP:return this._repeat(null,i.page,e),!0;case s.PAGE_DOWN:return this._repeat(null,-i.page,e),!0}return!1},_start:function(t){return this.spinning||this._trigger("start",t)!==!1?(this.counter||(this.counter=1),this.spinning=!0,!0):!1},_repeat:function(t,e,i){t=t||500,clearTimeout(this.timer),this.timer=this._delay(function(){this._repeat(40,e,i)},t),this._spin(e*this.options.step,i)},_spin:function(t,e){var i=this.value()||0;this.counter||(this.counter=1),i=this._adjustValue(i+t*this._increment(this.counter)),this.spinning&&this._trigger("spin",e,{value:i})===!1||(this._value(i),this.counter++)},_increment:function(e){var i=this.options.incremental;return i?t.isFunction(i)?i(e):Math.floor(e*e*e/5e4-e*e/500+17*e/200+1):1},_precision:function(){var t=this._precisionOf(this.options.step);return null!==this.options.min&&(t=Math.max(t,this._precisionOf(this.options.min))),t},_precisionOf:function(t){var e=""+t,i=e.indexOf(".");return-1===i?0:e.length-i-1},_adjustValue:function(t){var e,i,s=this.options;return e=null!==s.min?s.min:0,i=t-e,i=Math.round(i/s.step)*s.step,t=e+i,t=parseFloat(t.toFixed(this._precision())),null!==s.max&&t>s.max?s.max:null!==s.min&&s.min>t?s.min:t},_stop:function(t){this.spinning&&(clearTimeout(this.timer),clearTimeout(this.mousewheelTimer),this.counter=0,this.spinning=!1,this._trigger("stop",t))},_setOption:function(t,e){var i,s,n;return"culture"===t||"numberFormat"===t?(i=this._parse(this.element.val()),this.options[t]=e,this.element.val(this._format(i)),void 0):(("max"===t||"min"===t||"step"===t)&&"string"==typeof e&&(e=this._parse(e)),"icons"===t&&(s=this.buttons.first().find(".ui-icon"),this._removeClass(s,null,this.options.icons.up),this._addClass(s,null,e.up),n=this.buttons.last().find(".ui-icon"),this._removeClass(n,null,this.options.icons.down),this._addClass(n,null,e.down)),this._super(t,e),void 0)},_setOptionDisabled:function(t){this._super(t),this._toggleClass(this.uiSpinner,null,"ui-state-disabled",!!t),this.element.prop("disabled",!!t),this.buttons.button(t?"disable":"enable")},_setOptions:r(function(t){this._super(t)}),_parse:function(t){return"string"==typeof t&&""!==t&&(t=window.Globalize&&this.options.numberFormat?Globalize.parseFloat(t,10,this.options.culture):+t),""===t||isNaN(t)?null:t},_format:function(t){return""===t?"":window.Globalize&&this.options.numberFormat?Globalize.format(t,this.options.numberFormat,this.options.culture):t},_refresh:function(){this.element.attr({"aria-valuemin":this.options.min,"aria-valuemax":this.options.max,"aria-valuenow":this._parse(this.element.val())})},isValid:function(){var t=this.value();return null===t?!1:t===this._adjustValue(t)},_value:function(t,e){var i;""!==t&&(i=this._parse(t),null!==i&&(e||(i=this._adjustValue(i)),t=this._format(i))),this.element.val(t),this._refresh()},_destroy:function(){this.element.prop("disabled",!1).removeAttr("autocomplete role aria-valuemin aria-valuemax aria-valuenow"),this.uiSpinner.replaceWith(this.element)},stepUp:r(function(t){this._stepUp(t)}),_stepUp:function(t){this._start()&&(this._spin((t||1)*this.options.step),this._stop())},stepDown:r(function(t){this._stepDown(t)}),_stepDown:function(t){this._start()&&(this._spin((t||1)*-this.options.step),this._stop())},pageUp:r(function(t){this._stepUp((t||1)*this.options.page)}),pageDown:r(function(t){this._stepDown((t||1)*this.options.page)}),value:function(t){return arguments.length?(r(this._value).call(this,t),void 0):this._parse(this.element.val())},widget:function(){return this.uiSpinner}}),t.uiBackCompat!==!1&&t.widget("ui.spinner",t.ui.spinner,{_enhance:function(){this.uiSpinner=this.element.attr("autocomplete","off").wrap(this._uiSpinnerHtml()).parent().append(this._buttonHtml())},_uiSpinnerHtml:function(){return""},_buttonHtml:function(){return""}}),t.ui.spinner,t.widget("ui.tabs",{version:"1.12.1",delay:300,options:{active:null,classes:{"ui-tabs":"ui-corner-all","ui-tabs-nav":"ui-corner-all","ui-tabs-panel":"ui-corner-bottom","ui-tabs-tab":"ui-corner-top"},collapsible:!1,event:"click",heightStyle:"content",hide:null,show:null,activate:null,beforeActivate:null,beforeLoad:null,load:null},_isLocal:function(){var t=/#.*$/;return function(e){var i,s;i=e.href.replace(t,""),s=location.href.replace(t,"");try{i=decodeURIComponent(i)}catch(n){}try{s=decodeURIComponent(s)}catch(n){}return e.hash.length>1&&i===s}}(),_create:function(){var e=this,i=this.options;this.running=!1,this._addClass("ui-tabs","ui-widget ui-widget-content"),this._toggleClass("ui-tabs-collapsible",null,i.collapsible),this._processTabs(),i.active=this._initialActive(),t.isArray(i.disabled)&&(i.disabled=t.unique(i.disabled.concat(t.map(this.tabs.filter(".ui-state-disabled"),function(t){return e.tabs.index(t)}))).sort()),this.active=this.options.active!==!1&&this.anchors.length?this._findActive(i.active):t(),this._refresh(),this.active.length&&this.load(i.active)},_initialActive:function(){var e=this.options.active,i=this.options.collapsible,s=location.hash.substring(1);return null===e&&(s&&this.tabs.each(function(i,n){return t(n).attr("aria-controls")===s?(e=i,!1):void 0}),null===e&&(e=this.tabs.index(this.tabs.filter(".ui-tabs-active"))),(null===e||-1===e)&&(e=this.tabs.length?0:!1)),e!==!1&&(e=this.tabs.index(this.tabs.eq(e)),-1===e&&(e=i?!1:0)),!i&&e===!1&&this.anchors.length&&(e=0),e},_getCreateEventData:function(){return{tab:this.active,panel:this.active.length?this._getPanelForTab(this.active):t()}},_tabKeydown:function(e){var i=t(t.ui.safeActiveElement(this.document[0])).closest("li"),s=this.tabs.index(i),n=!0;if(!this._handlePageNav(e)){switch(e.keyCode){case t.ui.keyCode.RIGHT:case t.ui.keyCode.DOWN:s++;break;case t.ui.keyCode.UP:case t.ui.keyCode.LEFT:n=!1,s--;break;case t.ui.keyCode.END:s=this.anchors.length-1;break;case t.ui.keyCode.HOME:s=0;break;case t.ui.keyCode.SPACE:return e.preventDefault(),clearTimeout(this.activating),this._activate(s),void 0;case t.ui.keyCode.ENTER:return e.preventDefault(),clearTimeout(this.activating),this._activate(s===this.options.active?!1:s),void 0;default:return}e.preventDefault(),clearTimeout(this.activating),s=this._focusNextTab(s,n),e.ctrlKey||e.metaKey||(i.attr("aria-selected","false"),this.tabs.eq(s).attr("aria-selected","true"),this.activating=this._delay(function(){this.option("active",s)},this.delay))}},_panelKeydown:function(e){this._handlePageNav(e)||e.ctrlKey&&e.keyCode===t.ui.keyCode.UP&&(e.preventDefault(),this.active.trigger("focus"))},_handlePageNav:function(e){return e.altKey&&e.keyCode===t.ui.keyCode.PAGE_UP?(this._activate(this._focusNextTab(this.options.active-1,!1)),!0):e.altKey&&e.keyCode===t.ui.keyCode.PAGE_DOWN?(this._activate(this._focusNextTab(this.options.active+1,!0)),!0):void 0},_findNextTab:function(e,i){function s(){return e>n&&(e=0),0>e&&(e=n),e}for(var n=this.tabs.length-1;-1!==t.inArray(s(),this.options.disabled);)e=i?e+1:e-1;return e},_focusNextTab:function(t,e){return t=this._findNextTab(t,e),this.tabs.eq(t).trigger("focus"),t},_setOption:function(t,e){return"active"===t?(this._activate(e),void 0):(this._super(t,e),"collapsible"===t&&(this._toggleClass("ui-tabs-collapsible",null,e),e||this.options.active!==!1||this._activate(0)),"event"===t&&this._setupEvents(e),"heightStyle"===t&&this._setupHeightStyle(e),void 0)},_sanitizeSelector:function(t){return t?t.replace(/[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g,"\\$&"):""},refresh:function(){var e=this.options,i=this.tablist.children(":has(a[href])");e.disabled=t.map(i.filter(".ui-state-disabled"),function(t){return i.index(t)}),this._processTabs(),e.active!==!1&&this.anchors.length?this.active.length&&!t.contains(this.tablist[0],this.active[0])?this.tabs.length===e.disabled.length?(e.active=!1,this.active=t()):this._activate(this._findNextTab(Math.max(0,e.active-1),!1)):e.active=this.tabs.index(this.active):(e.active=!1,this.active=t()),this._refresh()},_refresh:function(){this._setOptionDisabled(this.options.disabled),this._setupEvents(this.options.event),this._setupHeightStyle(this.options.heightStyle),this.tabs.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}),this.panels.not(this._getPanelForTab(this.active)).hide().attr({"aria-hidden":"true"}),this.active.length?(this.active.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}),this._addClass(this.active,"ui-tabs-active","ui-state-active"),this._getPanelForTab(this.active).show().attr({"aria-hidden":"false"})):this.tabs.eq(0).attr("tabIndex",0)},_processTabs:function(){var e=this,i=this.tabs,s=this.anchors,n=this.panels;this.tablist=this._getList().attr("role","tablist"),this._addClass(this.tablist,"ui-tabs-nav","ui-helper-reset ui-helper-clearfix ui-widget-header"),this.tablist.on("mousedown"+this.eventNamespace,"> li",function(e){t(this).is(".ui-state-disabled")&&e.preventDefault()}).on("focus"+this.eventNamespace,".ui-tabs-anchor",function(){t(this).closest("li").is(".ui-state-disabled")&&this.blur()}),this.tabs=this.tablist.find("> li:has(a[href])").attr({role:"tab",tabIndex:-1}),this._addClass(this.tabs,"ui-tabs-tab","ui-state-default"),this.anchors=this.tabs.map(function(){return t("a",this)[0]}).attr({role:"presentation",tabIndex:-1}),this._addClass(this.anchors,"ui-tabs-anchor"),this.panels=t(),this.anchors.each(function(i,s){var n,o,a,r=t(s).uniqueId().attr("id"),h=t(s).closest("li"),l=h.attr("aria-controls");e._isLocal(s)?(n=s.hash,a=n.substring(1),o=e.element.find(e._sanitizeSelector(n))):(a=h.attr("aria-controls")||t({}).uniqueId()[0].id,n="#"+a,o=e.element.find(n),o.length||(o=e._createPanel(a),o.insertAfter(e.panels[i-1]||e.tablist)),o.attr("aria-live","polite")),o.length&&(e.panels=e.panels.add(o)),l&&h.data("ui-tabs-aria-controls",l),h.attr({"aria-controls":a,"aria-labelledby":r}),o.attr("aria-labelledby",r)}),this.panels.attr("role","tabpanel"),this._addClass(this.panels,"ui-tabs-panel","ui-widget-content"),i&&(this._off(i.not(this.tabs)),this._off(s.not(this.anchors)),this._off(n.not(this.panels)))},_getList:function(){return this.tablist||this.element.find("ol, ul").eq(0)},_createPanel:function(e){return t("
    ").attr("id",e).data("ui-tabs-destroy",!0)},_setOptionDisabled:function(e){var i,s,n;for(t.isArray(e)&&(e.length?e.length===this.anchors.length&&(e=!0):e=!1),n=0;s=this.tabs[n];n++)i=t(s),e===!0||-1!==t.inArray(n,e)?(i.attr("aria-disabled","true"),this._addClass(i,null,"ui-state-disabled")):(i.removeAttr("aria-disabled"),this._removeClass(i,null,"ui-state-disabled"));this.options.disabled=e,this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,e===!0)},_setupEvents:function(e){var i={};e&&t.each(e.split(" "),function(t,e){i[e]="_eventHandler"}),this._off(this.anchors.add(this.tabs).add(this.panels)),this._on(!0,this.anchors,{click:function(t){t.preventDefault()}}),this._on(this.anchors,i),this._on(this.tabs,{keydown:"_tabKeydown"}),this._on(this.panels,{keydown:"_panelKeydown"}),this._focusable(this.tabs),this._hoverable(this.tabs)},_setupHeightStyle:function(e){var i,s=this.element.parent();"fill"===e?(i=s.height(),i-=this.element.outerHeight()-this.element.height(),this.element.siblings(":visible").each(function(){var e=t(this),s=e.css("position");"absolute"!==s&&"fixed"!==s&&(i-=e.outerHeight(!0))}),this.element.children().not(this.panels).each(function(){i-=t(this).outerHeight(!0)}),this.panels.each(function(){t(this).height(Math.max(0,i-t(this).innerHeight()+t(this).height()))}).css("overflow","auto")):"auto"===e&&(i=0,this.panels.each(function(){i=Math.max(i,t(this).height("").height())}).height(i))},_eventHandler:function(e){var i=this.options,s=this.active,n=t(e.currentTarget),o=n.closest("li"),a=o[0]===s[0],r=a&&i.collapsible,h=r?t():this._getPanelForTab(o),l=s.length?this._getPanelForTab(s):t(),c={oldTab:s,oldPanel:l,newTab:r?t():o,newPanel:h};e.preventDefault(),o.hasClass("ui-state-disabled")||o.hasClass("ui-tabs-loading")||this.running||a&&!i.collapsible||this._trigger("beforeActivate",e,c)===!1||(i.active=r?!1:this.tabs.index(o),this.active=a?t():o,this.xhr&&this.xhr.abort(),l.length||h.length||t.error("jQuery UI Tabs: Mismatching fragment identifier."),h.length&&this.load(this.tabs.index(o),e),this._toggle(e,c))},_toggle:function(e,i){function s(){o.running=!1,o._trigger("activate",e,i)}function n(){o._addClass(i.newTab.closest("li"),"ui-tabs-active","ui-state-active"),a.length&&o.options.show?o._show(a,o.options.show,s):(a.show(),s())}var o=this,a=i.newPanel,r=i.oldPanel;this.running=!0,r.length&&this.options.hide?this._hide(r,this.options.hide,function(){o._removeClass(i.oldTab.closest("li"),"ui-tabs-active","ui-state-active"),n()}):(this._removeClass(i.oldTab.closest("li"),"ui-tabs-active","ui-state-active"),r.hide(),n()),r.attr("aria-hidden","true"),i.oldTab.attr({"aria-selected":"false","aria-expanded":"false"}),a.length&&r.length?i.oldTab.attr("tabIndex",-1):a.length&&this.tabs.filter(function(){return 0===t(this).attr("tabIndex")}).attr("tabIndex",-1),a.attr("aria-hidden","false"),i.newTab.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0})},_activate:function(e){var i,s=this._findActive(e);s[0]!==this.active[0]&&(s.length||(s=this.active),i=s.find(".ui-tabs-anchor")[0],this._eventHandler({target:i,currentTarget:i,preventDefault:t.noop}))},_findActive:function(e){return e===!1?t():this.tabs.eq(e)},_getIndex:function(e){return"string"==typeof e&&(e=this.anchors.index(this.anchors.filter("[href$='"+t.ui.escapeSelector(e)+"']"))),e},_destroy:function(){this.xhr&&this.xhr.abort(),this.tablist.removeAttr("role").off(this.eventNamespace),this.anchors.removeAttr("role tabIndex").removeUniqueId(),this.tabs.add(this.panels).each(function(){t.data(this,"ui-tabs-destroy")?t(this).remove():t(this).removeAttr("role tabIndex aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded")}),this.tabs.each(function(){var e=t(this),i=e.data("ui-tabs-aria-controls");i?e.attr("aria-controls",i).removeData("ui-tabs-aria-controls"):e.removeAttr("aria-controls")}),this.panels.show(),"content"!==this.options.heightStyle&&this.panels.css("height","")},enable:function(e){var i=this.options.disabled;i!==!1&&(void 0===e?i=!1:(e=this._getIndex(e),i=t.isArray(i)?t.map(i,function(t){return t!==e?t:null}):t.map(this.tabs,function(t,i){return i!==e?i:null})),this._setOptionDisabled(i))},disable:function(e){var i=this.options.disabled;if(i!==!0){if(void 0===e)i=!0;else{if(e=this._getIndex(e),-1!==t.inArray(e,i))return;i=t.isArray(i)?t.merge([e],i).sort():[e]}this._setOptionDisabled(i)}},load:function(e,i){e=this._getIndex(e);var s=this,n=this.tabs.eq(e),o=n.find(".ui-tabs-anchor"),a=this._getPanelForTab(n),r={tab:n,panel:a},h=function(t,e){"abort"===e&&s.panels.stop(!1,!0),s._removeClass(n,"ui-tabs-loading"),a.removeAttr("aria-busy"),t===s.xhr&&delete s.xhr};this._isLocal(o[0])||(this.xhr=t.ajax(this._ajaxSettings(o,i,r)),this.xhr&&"canceled"!==this.xhr.statusText&&(this._addClass(n,"ui-tabs-loading"),a.attr("aria-busy","true"),this.xhr.done(function(t,e,n){setTimeout(function(){a.html(t),s._trigger("load",i,r),h(n,e)},1)}).fail(function(t,e){setTimeout(function(){h(t,e)},1)})))},_ajaxSettings:function(e,i,s){var n=this;return{url:e.attr("href").replace(/#.*$/,""),beforeSend:function(e,o){return n._trigger("beforeLoad",i,t.extend({jqXHR:e,ajaxSettings:o},s))}}},_getPanelForTab:function(e){var i=t(e).attr("aria-controls");return this.element.find(this._sanitizeSelector("#"+i))}}),t.uiBackCompat!==!1&&t.widget("ui.tabs",t.ui.tabs,{_processTabs:function(){this._superApply(arguments),this._addClass(this.tabs,"ui-tab")}}),t.ui.tabs,t.widget("ui.tooltip",{version:"1.12.1",options:{classes:{"ui-tooltip":"ui-corner-all ui-widget-shadow"},content:function(){var e=t(this).attr("title")||"";return t("").text(e).html()},hide:!0,items:"[title]:not([disabled])",position:{my:"left top+15",at:"left bottom",collision:"flipfit flip"},show:!0,track:!1,close:null,open:null},_addDescribedBy:function(e,i){var s=(e.attr("aria-describedby")||"").split(/\s+/);s.push(i),e.data("ui-tooltip-id",i).attr("aria-describedby",t.trim(s.join(" ")))},_removeDescribedBy:function(e){var i=e.data("ui-tooltip-id"),s=(e.attr("aria-describedby")||"").split(/\s+/),n=t.inArray(i,s);-1!==n&&s.splice(n,1),e.removeData("ui-tooltip-id"),s=t.trim(s.join(" ")),s?e.attr("aria-describedby",s):e.removeAttr("aria-describedby")},_create:function(){this._on({mouseover:"open",focusin:"open"}),this.tooltips={},this.parents={},this.liveRegion=t("
    ").attr({role:"log","aria-live":"assertive","aria-relevant":"additions"}).appendTo(this.document[0].body),this._addClass(this.liveRegion,null,"ui-helper-hidden-accessible"),this.disabledTitles=t([])},_setOption:function(e,i){var s=this;this._super(e,i),"content"===e&&t.each(this.tooltips,function(t,e){s._updateContent(e.element)})},_setOptionDisabled:function(t){this[t?"_disable":"_enable"]()},_disable:function(){var e=this;t.each(this.tooltips,function(i,s){var n=t.Event("blur");n.target=n.currentTarget=s.element[0],e.close(n,!0)}),this.disabledTitles=this.disabledTitles.add(this.element.find(this.options.items).addBack().filter(function(){var e=t(this);return e.is("[title]")?e.data("ui-tooltip-title",e.attr("title")).removeAttr("title"):void 0}))},_enable:function(){this.disabledTitles.each(function(){var e=t(this);e.data("ui-tooltip-title")&&e.attr("title",e.data("ui-tooltip-title"))}),this.disabledTitles=t([])},open:function(e){var i=this,s=t(e?e.target:this.element).closest(this.options.items);s.length&&!s.data("ui-tooltip-id")&&(s.attr("title")&&s.data("ui-tooltip-title",s.attr("title")),s.data("ui-tooltip-open",!0),e&&"mouseover"===e.type&&s.parents().each(function(){var e,s=t(this);s.data("ui-tooltip-open")&&(e=t.Event("blur"),e.target=e.currentTarget=this,i.close(e,!0)),s.attr("title")&&(s.uniqueId(),i.parents[this.id]={element:this,title:s.attr("title")},s.attr("title",""))}),this._registerCloseHandlers(e,s),this._updateContent(s,e))},_updateContent:function(t,e){var i,s=this.options.content,n=this,o=e?e.type:null;return"string"==typeof s||s.nodeType||s.jquery?this._open(e,t,s):(i=s.call(t[0],function(i){n._delay(function(){t.data("ui-tooltip-open")&&(e&&(e.type=o),this._open(e,t,i))})}),i&&this._open(e,t,i),void 0)},_open:function(e,i,s){function n(t){l.of=t,a.is(":hidden")||a.position(l)}var o,a,r,h,l=t.extend({},this.options.position);if(s){if(o=this._find(i))return o.tooltip.find(".ui-tooltip-content").html(s),void 0;i.is("[title]")&&(e&&"mouseover"===e.type?i.attr("title",""):i.removeAttr("title")),o=this._tooltip(i),a=o.tooltip,this._addDescribedBy(i,a.attr("id")),a.find(".ui-tooltip-content").html(s),this.liveRegion.children().hide(),h=t("
    ").html(a.find(".ui-tooltip-content").html()),h.removeAttr("name").find("[name]").removeAttr("name"),h.removeAttr("id").find("[id]").removeAttr("id"),h.appendTo(this.liveRegion),this.options.track&&e&&/^mouse/.test(e.type)?(this._on(this.document,{mousemove:n}),n(e)):a.position(t.extend({of:i},this.options.position)),a.hide(),this._show(a,this.options.show),this.options.track&&this.options.show&&this.options.show.delay&&(r=this.delayedShow=setInterval(function(){a.is(":visible")&&(n(l.of),clearInterval(r))},t.fx.interval)),this._trigger("open",e,{tooltip:a})}},_registerCloseHandlers:function(e,i){var s={keyup:function(e){if(e.keyCode===t.ui.keyCode.ESCAPE){var s=t.Event(e);s.currentTarget=i[0],this.close(s,!0)}}};i[0]!==this.element[0]&&(s.remove=function(){this._removeTooltip(this._find(i).tooltip)}),e&&"mouseover"!==e.type||(s.mouseleave="close"),e&&"focusin"!==e.type||(s.focusout="close"),this._on(!0,i,s)},close:function(e){var i,s=this,n=t(e?e.currentTarget:this.element),o=this._find(n);return o?(i=o.tooltip,o.closing||(clearInterval(this.delayedShow),n.data("ui-tooltip-title")&&!n.attr("title")&&n.attr("title",n.data("ui-tooltip-title")),this._removeDescribedBy(n),o.hiding=!0,i.stop(!0),this._hide(i,this.options.hide,function(){s._removeTooltip(t(this))}),n.removeData("ui-tooltip-open"),this._off(n,"mouseleave focusout keyup"),n[0]!==this.element[0]&&this._off(n,"remove"),this._off(this.document,"mousemove"),e&&"mouseleave"===e.type&&t.each(this.parents,function(e,i){t(i.element).attr("title",i.title),delete s.parents[e] +}),o.closing=!0,this._trigger("close",e,{tooltip:i}),o.hiding||(o.closing=!1)),void 0):(n.removeData("ui-tooltip-open"),void 0)},_tooltip:function(e){var i=t("
    ").attr("role","tooltip"),s=t("
    ").appendTo(i),n=i.uniqueId().attr("id");return this._addClass(s,"ui-tooltip-content"),this._addClass(i,"ui-tooltip","ui-widget ui-widget-content"),i.appendTo(this._appendTo(e)),this.tooltips[n]={element:e,tooltip:i}},_find:function(t){var e=t.data("ui-tooltip-id");return e?this.tooltips[e]:null},_removeTooltip:function(t){t.remove(),delete this.tooltips[t.attr("id")]},_appendTo:function(t){var e=t.closest(".ui-front, dialog");return e.length||(e=this.document[0].body),e},_destroy:function(){var e=this;t.each(this.tooltips,function(i,s){var n=t.Event("blur"),o=s.element;n.target=n.currentTarget=o[0],e.close(n,!0),t("#"+i).remove(),o.data("ui-tooltip-title")&&(o.attr("title")||o.attr("title",o.data("ui-tooltip-title")),o.removeData("ui-tooltip-title"))}),this.liveRegion.remove()}}),t.uiBackCompat!==!1&&t.widget("ui.tooltip",t.ui.tooltip,{options:{tooltipClass:null},_tooltip:function(){var t=this._superApply(arguments);return this.options.tooltipClass&&t.tooltip.addClass(this.options.tooltipClass),t}}),t.ui.tooltip;var f="ui-effects-",g="ui-effects-style",m="ui-effects-animated",_=t;t.effects={effect:{}},function(t,e){function i(t,e,i){var s=u[e.type]||{};return null==t?i||!e.def?null:e.def:(t=s.floor?~~t:parseFloat(t),isNaN(t)?e.def:s.mod?(t+s.mod)%s.mod:0>t?0:t>s.max?s.max:t)}function s(i){var s=l(),n=s._rgba=[];return i=i.toLowerCase(),f(h,function(t,o){var a,r=o.re.exec(i),h=r&&o.parse(r),l=o.space||"rgba";return h?(a=s[l](h),s[c[l].cache]=a[c[l].cache],n=s._rgba=a._rgba,!1):e}),n.length?("0,0,0,0"===n.join()&&t.extend(n,o.transparent),s):o[i]}function n(t,e,i){return i=(i+1)%1,1>6*i?t+6*(e-t)*i:1>2*i?e:2>3*i?t+6*(e-t)*(2/3-i):t}var o,a="backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",r=/^([\-+])=\s*(\d+\.?\d*)/,h=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[t[1],t[2],t[3],t[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[2.55*t[1],2.55*t[2],2.55*t[3],t[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,parse:function(t){return[parseInt(t[1],16),parseInt(t[2],16),parseInt(t[3],16)]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])/,parse:function(t){return[parseInt(t[1]+t[1],16),parseInt(t[2]+t[2],16),parseInt(t[3]+t[3],16)]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(t){return[t[1],t[2]/100,t[3]/100,t[4]]}}],l=t.Color=function(e,i,s,n){return new t.Color.fn.parse(e,i,s,n)},c={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},u={"byte":{floor:!0,max:255},percent:{max:1},degrees:{mod:360,floor:!0}},d=l.support={},p=t("

    ")[0],f=t.each;p.style.cssText="background-color:rgba(1,1,1,.5)",d.rgba=p.style.backgroundColor.indexOf("rgba")>-1,f(c,function(t,e){e.cache="_"+t,e.props.alpha={idx:3,type:"percent",def:1}}),l.fn=t.extend(l.prototype,{parse:function(n,a,r,h){if(n===e)return this._rgba=[null,null,null,null],this;(n.jquery||n.nodeType)&&(n=t(n).css(a),a=e);var u=this,d=t.type(n),p=this._rgba=[];return a!==e&&(n=[n,a,r,h],d="array"),"string"===d?this.parse(s(n)||o._default):"array"===d?(f(c.rgba.props,function(t,e){p[e.idx]=i(n[e.idx],e)}),this):"object"===d?(n instanceof l?f(c,function(t,e){n[e.cache]&&(u[e.cache]=n[e.cache].slice())}):f(c,function(e,s){var o=s.cache;f(s.props,function(t,e){if(!u[o]&&s.to){if("alpha"===t||null==n[t])return;u[o]=s.to(u._rgba)}u[o][e.idx]=i(n[t],e,!0)}),u[o]&&0>t.inArray(null,u[o].slice(0,3))&&(u[o][3]=1,s.from&&(u._rgba=s.from(u[o])))}),this):e},is:function(t){var i=l(t),s=!0,n=this;return f(c,function(t,o){var a,r=i[o.cache];return r&&(a=n[o.cache]||o.to&&o.to(n._rgba)||[],f(o.props,function(t,i){return null!=r[i.idx]?s=r[i.idx]===a[i.idx]:e})),s}),s},_space:function(){var t=[],e=this;return f(c,function(i,s){e[s.cache]&&t.push(i)}),t.pop()},transition:function(t,e){var s=l(t),n=s._space(),o=c[n],a=0===this.alpha()?l("transparent"):this,r=a[o.cache]||o.to(a._rgba),h=r.slice();return s=s[o.cache],f(o.props,function(t,n){var o=n.idx,a=r[o],l=s[o],c=u[n.type]||{};null!==l&&(null===a?h[o]=l:(c.mod&&(l-a>c.mod/2?a+=c.mod:a-l>c.mod/2&&(a-=c.mod)),h[o]=i((l-a)*e+a,n)))}),this[n](h)},blend:function(e){if(1===this._rgba[3])return this;var i=this._rgba.slice(),s=i.pop(),n=l(e)._rgba;return l(t.map(i,function(t,e){return(1-s)*n[e]+s*t}))},toRgbaString:function(){var e="rgba(",i=t.map(this._rgba,function(t,e){return null==t?e>2?1:0:t});return 1===i[3]&&(i.pop(),e="rgb("),e+i.join()+")"},toHslaString:function(){var e="hsla(",i=t.map(this.hsla(),function(t,e){return null==t&&(t=e>2?1:0),e&&3>e&&(t=Math.round(100*t)+"%"),t});return 1===i[3]&&(i.pop(),e="hsl("),e+i.join()+")"},toHexString:function(e){var i=this._rgba.slice(),s=i.pop();return e&&i.push(~~(255*s)),"#"+t.map(i,function(t){return t=(t||0).toString(16),1===t.length?"0"+t:t}).join("")},toString:function(){return 0===this._rgba[3]?"transparent":this.toRgbaString()}}),l.fn.parse.prototype=l.fn,c.hsla.to=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e,i,s=t[0]/255,n=t[1]/255,o=t[2]/255,a=t[3],r=Math.max(s,n,o),h=Math.min(s,n,o),l=r-h,c=r+h,u=.5*c;return e=h===r?0:s===r?60*(n-o)/l+360:n===r?60*(o-s)/l+120:60*(s-n)/l+240,i=0===l?0:.5>=u?l/c:l/(2-c),[Math.round(e)%360,i,u,null==a?1:a]},c.hsla.from=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e=t[0]/360,i=t[1],s=t[2],o=t[3],a=.5>=s?s*(1+i):s+i-s*i,r=2*s-a;return[Math.round(255*n(r,a,e+1/3)),Math.round(255*n(r,a,e)),Math.round(255*n(r,a,e-1/3)),o]},f(c,function(s,n){var o=n.props,a=n.cache,h=n.to,c=n.from;l.fn[s]=function(s){if(h&&!this[a]&&(this[a]=h(this._rgba)),s===e)return this[a].slice();var n,r=t.type(s),u="array"===r||"object"===r?s:arguments,d=this[a].slice();return f(o,function(t,e){var s=u["object"===r?t:e.idx];null==s&&(s=d[e.idx]),d[e.idx]=i(s,e)}),c?(n=l(c(d)),n[a]=d,n):l(d)},f(o,function(e,i){l.fn[e]||(l.fn[e]=function(n){var o,a=t.type(n),h="alpha"===e?this._hsla?"hsla":"rgba":s,l=this[h](),c=l[i.idx];return"undefined"===a?c:("function"===a&&(n=n.call(this,c),a=t.type(n)),null==n&&i.empty?this:("string"===a&&(o=r.exec(n),o&&(n=c+parseFloat(o[2])*("+"===o[1]?1:-1))),l[i.idx]=n,this[h](l)))})})}),l.hook=function(e){var i=e.split(" ");f(i,function(e,i){t.cssHooks[i]={set:function(e,n){var o,a,r="";if("transparent"!==n&&("string"!==t.type(n)||(o=s(n)))){if(n=l(o||n),!d.rgba&&1!==n._rgba[3]){for(a="backgroundColor"===i?e.parentNode:e;(""===r||"transparent"===r)&&a&&a.style;)try{r=t.css(a,"backgroundColor"),a=a.parentNode}catch(h){}n=n.blend(r&&"transparent"!==r?r:"_default")}n=n.toRgbaString()}try{e.style[i]=n}catch(h){}}},t.fx.step[i]=function(e){e.colorInit||(e.start=l(e.elem,i),e.end=l(e.end),e.colorInit=!0),t.cssHooks[i].set(e.elem,e.start.transition(e.end,e.pos))}})},l.hook(a),t.cssHooks.borderColor={expand:function(t){var e={};return f(["Top","Right","Bottom","Left"],function(i,s){e["border"+s+"Color"]=t}),e}},o=t.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}}(_),function(){function e(e){var i,s,n=e.ownerDocument.defaultView?e.ownerDocument.defaultView.getComputedStyle(e,null):e.currentStyle,o={};if(n&&n.length&&n[0]&&n[n[0]])for(s=n.length;s--;)i=n[s],"string"==typeof n[i]&&(o[t.camelCase(i)]=n[i]);else for(i in n)"string"==typeof n[i]&&(o[i]=n[i]);return o}function i(e,i){var s,o,a={};for(s in i)o=i[s],e[s]!==o&&(n[s]||(t.fx.step[s]||!isNaN(parseFloat(o)))&&(a[s]=o));return a}var s=["add","remove","toggle"],n={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};t.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(e,i){t.fx.step[i]=function(t){("none"!==t.end&&!t.setAttr||1===t.pos&&!t.setAttr)&&(_.style(t.elem,i,t.end),t.setAttr=!0)}}),t.fn.addBack||(t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t.effects.animateClass=function(n,o,a,r){var h=t.speed(o,a,r);return this.queue(function(){var o,a=t(this),r=a.attr("class")||"",l=h.children?a.find("*").addBack():a;l=l.map(function(){var i=t(this);return{el:i,start:e(this)}}),o=function(){t.each(s,function(t,e){n[e]&&a[e+"Class"](n[e])})},o(),l=l.map(function(){return this.end=e(this.el[0]),this.diff=i(this.start,this.end),this}),a.attr("class",r),l=l.map(function(){var e=this,i=t.Deferred(),s=t.extend({},h,{queue:!1,complete:function(){i.resolve(e)}});return this.el.animate(this.diff,s),i.promise()}),t.when.apply(t,l.get()).done(function(){o(),t.each(arguments,function(){var e=this.el;t.each(this.diff,function(t){e.css(t,"")})}),h.complete.call(a[0])})})},t.fn.extend({addClass:function(e){return function(i,s,n,o){return s?t.effects.animateClass.call(this,{add:i},s,n,o):e.apply(this,arguments)}}(t.fn.addClass),removeClass:function(e){return function(i,s,n,o){return arguments.length>1?t.effects.animateClass.call(this,{remove:i},s,n,o):e.apply(this,arguments)}}(t.fn.removeClass),toggleClass:function(e){return function(i,s,n,o,a){return"boolean"==typeof s||void 0===s?n?t.effects.animateClass.call(this,s?{add:i}:{remove:i},n,o,a):e.apply(this,arguments):t.effects.animateClass.call(this,{toggle:i},s,n,o)}}(t.fn.toggleClass),switchClass:function(e,i,s,n,o){return t.effects.animateClass.call(this,{add:i,remove:e},s,n,o)}})}(),function(){function e(e,i,s,n){return t.isPlainObject(e)&&(i=e,e=e.effect),e={effect:e},null==i&&(i={}),t.isFunction(i)&&(n=i,s=null,i={}),("number"==typeof i||t.fx.speeds[i])&&(n=s,s=i,i={}),t.isFunction(s)&&(n=s,s=null),i&&t.extend(e,i),s=s||i.duration,e.duration=t.fx.off?0:"number"==typeof s?s:s in t.fx.speeds?t.fx.speeds[s]:t.fx.speeds._default,e.complete=n||i.complete,e}function i(e){return!e||"number"==typeof e||t.fx.speeds[e]?!0:"string"!=typeof e||t.effects.effect[e]?t.isFunction(e)?!0:"object"!=typeof e||e.effect?!1:!0:!0}function s(t,e){var i=e.outerWidth(),s=e.outerHeight(),n=/^rect\((-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto)\)$/,o=n.exec(t)||["",0,i,s,0];return{top:parseFloat(o[1])||0,right:"auto"===o[2]?i:parseFloat(o[2]),bottom:"auto"===o[3]?s:parseFloat(o[3]),left:parseFloat(o[4])||0}}t.expr&&t.expr.filters&&t.expr.filters.animated&&(t.expr.filters.animated=function(e){return function(i){return!!t(i).data(m)||e(i)}}(t.expr.filters.animated)),t.uiBackCompat!==!1&&t.extend(t.effects,{save:function(t,e){for(var i=0,s=e.length;s>i;i++)null!==e[i]&&t.data(f+e[i],t[0].style[e[i]])},restore:function(t,e){for(var i,s=0,n=e.length;n>s;s++)null!==e[s]&&(i=t.data(f+e[s]),t.css(e[s],i))},setMode:function(t,e){return"toggle"===e&&(e=t.is(":hidden")?"show":"hide"),e},createWrapper:function(e){if(e.parent().is(".ui-effects-wrapper"))return e.parent();var i={width:e.outerWidth(!0),height:e.outerHeight(!0),"float":e.css("float")},s=t("

    ").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),n={width:e.width(),height:e.height()},o=document.activeElement;try{o.id}catch(a){o=document.body}return e.wrap(s),(e[0]===o||t.contains(e[0],o))&&t(o).trigger("focus"),s=e.parent(),"static"===e.css("position")?(s.css({position:"relative"}),e.css({position:"relative"})):(t.extend(i,{position:e.css("position"),zIndex:e.css("z-index")}),t.each(["top","left","bottom","right"],function(t,s){i[s]=e.css(s),isNaN(parseInt(i[s],10))&&(i[s]="auto")}),e.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),e.css(n),s.css(i).show()},removeWrapper:function(e){var i=document.activeElement;return e.parent().is(".ui-effects-wrapper")&&(e.parent().replaceWith(e),(e[0]===i||t.contains(e[0],i))&&t(i).trigger("focus")),e}}),t.extend(t.effects,{version:"1.12.1",define:function(e,i,s){return s||(s=i,i="effect"),t.effects.effect[e]=s,t.effects.effect[e].mode=i,s},scaledDimensions:function(t,e,i){if(0===e)return{height:0,width:0,outerHeight:0,outerWidth:0};var s="horizontal"!==i?(e||100)/100:1,n="vertical"!==i?(e||100)/100:1;return{height:t.height()*n,width:t.width()*s,outerHeight:t.outerHeight()*n,outerWidth:t.outerWidth()*s}},clipToBox:function(t){return{width:t.clip.right-t.clip.left,height:t.clip.bottom-t.clip.top,left:t.clip.left,top:t.clip.top}},unshift:function(t,e,i){var s=t.queue();e>1&&s.splice.apply(s,[1,0].concat(s.splice(e,i))),t.dequeue()},saveStyle:function(t){t.data(g,t[0].style.cssText)},restoreStyle:function(t){t[0].style.cssText=t.data(g)||"",t.removeData(g)},mode:function(t,e){var i=t.is(":hidden");return"toggle"===e&&(e=i?"show":"hide"),(i?"hide"===e:"show"===e)&&(e="none"),e},getBaseline:function(t,e){var i,s;switch(t[0]){case"top":i=0;break;case"middle":i=.5;break;case"bottom":i=1;break;default:i=t[0]/e.height}switch(t[1]){case"left":s=0;break;case"center":s=.5;break;case"right":s=1;break;default:s=t[1]/e.width}return{x:s,y:i}},createPlaceholder:function(e){var i,s=e.css("position"),n=e.position();return e.css({marginTop:e.css("marginTop"),marginBottom:e.css("marginBottom"),marginLeft:e.css("marginLeft"),marginRight:e.css("marginRight")}).outerWidth(e.outerWidth()).outerHeight(e.outerHeight()),/^(static|relative)/.test(s)&&(s="absolute",i=t("<"+e[0].nodeName+">").insertAfter(e).css({display:/^(inline|ruby)/.test(e.css("display"))?"inline-block":"block",visibility:"hidden",marginTop:e.css("marginTop"),marginBottom:e.css("marginBottom"),marginLeft:e.css("marginLeft"),marginRight:e.css("marginRight"),"float":e.css("float")}).outerWidth(e.outerWidth()).outerHeight(e.outerHeight()).addClass("ui-effects-placeholder"),e.data(f+"placeholder",i)),e.css({position:s,left:n.left,top:n.top}),i},removePlaceholder:function(t){var e=f+"placeholder",i=t.data(e);i&&(i.remove(),t.removeData(e))},cleanUp:function(e){t.effects.restoreStyle(e),t.effects.removePlaceholder(e)},setTransition:function(e,i,s,n){return n=n||{},t.each(i,function(t,i){var o=e.cssUnit(i);o[0]>0&&(n[i]=o[0]*s+o[1])}),n}}),t.fn.extend({effect:function(){function i(e){function i(){r.removeData(m),t.effects.cleanUp(r),"hide"===s.mode&&r.hide(),a()}function a(){t.isFunction(h)&&h.call(r[0]),t.isFunction(e)&&e()}var r=t(this);s.mode=c.shift(),t.uiBackCompat===!1||o?"none"===s.mode?(r[l](),a()):n.call(r[0],s,i):(r.is(":hidden")?"hide"===l:"show"===l)?(r[l](),a()):n.call(r[0],s,a)}var s=e.apply(this,arguments),n=t.effects.effect[s.effect],o=n.mode,a=s.queue,r=a||"fx",h=s.complete,l=s.mode,c=[],u=function(e){var i=t(this),s=t.effects.mode(i,l)||o;i.data(m,!0),c.push(s),o&&("show"===s||s===o&&"hide"===s)&&i.show(),o&&"none"===s||t.effects.saveStyle(i),t.isFunction(e)&&e()};return t.fx.off||!n?l?this[l](s.duration,h):this.each(function(){h&&h.call(this)}):a===!1?this.each(u).each(i):this.queue(r,u).queue(r,i)},show:function(t){return function(s){if(i(s))return t.apply(this,arguments);var n=e.apply(this,arguments);return n.mode="show",this.effect.call(this,n)}}(t.fn.show),hide:function(t){return function(s){if(i(s))return t.apply(this,arguments);var n=e.apply(this,arguments);return n.mode="hide",this.effect.call(this,n)}}(t.fn.hide),toggle:function(t){return function(s){if(i(s)||"boolean"==typeof s)return t.apply(this,arguments);var n=e.apply(this,arguments);return n.mode="toggle",this.effect.call(this,n)}}(t.fn.toggle),cssUnit:function(e){var i=this.css(e),s=[];return t.each(["em","px","%","pt"],function(t,e){i.indexOf(e)>0&&(s=[parseFloat(i),e])}),s},cssClip:function(t){return t?this.css("clip","rect("+t.top+"px "+t.right+"px "+t.bottom+"px "+t.left+"px)"):s(this.css("clip"),this)},transfer:function(e,i){var s=t(this),n=t(e.to),o="fixed"===n.css("position"),a=t("body"),r=o?a.scrollTop():0,h=o?a.scrollLeft():0,l=n.offset(),c={top:l.top-r,left:l.left-h,height:n.innerHeight(),width:n.innerWidth()},u=s.offset(),d=t("
    ").appendTo("body").addClass(e.className).css({top:u.top-r,left:u.left-h,height:s.innerHeight(),width:s.innerWidth(),position:o?"fixed":"absolute"}).animate(c,e.duration,e.easing,function(){d.remove(),t.isFunction(i)&&i()})}}),t.fx.step.clip=function(e){e.clipInit||(e.start=t(e.elem).cssClip(),"string"==typeof e.end&&(e.end=s(e.end,e.elem)),e.clipInit=!0),t(e.elem).cssClip({top:e.pos*(e.end.top-e.start.top)+e.start.top,right:e.pos*(e.end.right-e.start.right)+e.start.right,bottom:e.pos*(e.end.bottom-e.start.bottom)+e.start.bottom,left:e.pos*(e.end.left-e.start.left)+e.start.left})}}(),function(){var e={};t.each(["Quad","Cubic","Quart","Quint","Expo"],function(t,i){e[i]=function(e){return Math.pow(e,t+2)}}),t.extend(e,{Sine:function(t){return 1-Math.cos(t*Math.PI/2)},Circ:function(t){return 1-Math.sqrt(1-t*t)},Elastic:function(t){return 0===t||1===t?t:-Math.pow(2,8*(t-1))*Math.sin((80*(t-1)-7.5)*Math.PI/15)},Back:function(t){return t*t*(3*t-2)},Bounce:function(t){for(var e,i=4;((e=Math.pow(2,--i))-1)/11>t;);return 1/Math.pow(4,3-i)-7.5625*Math.pow((3*e-2)/22-t,2)}}),t.each(e,function(e,i){t.easing["easeIn"+e]=i,t.easing["easeOut"+e]=function(t){return 1-i(1-t)},t.easing["easeInOut"+e]=function(t){return.5>t?i(2*t)/2:1-i(-2*t+2)/2}})}();var v=t.effects;t.effects.define("blind","hide",function(e,i){var s={up:["bottom","top"],vertical:["bottom","top"],down:["top","bottom"],left:["right","left"],horizontal:["right","left"],right:["left","right"]},n=t(this),o=e.direction||"up",a=n.cssClip(),r={clip:t.extend({},a)},h=t.effects.createPlaceholder(n);r.clip[s[o][0]]=r.clip[s[o][1]],"show"===e.mode&&(n.cssClip(r.clip),h&&h.css(t.effects.clipToBox(r)),r.clip=a),h&&h.animate(t.effects.clipToBox(r),e.duration,e.easing),n.animate(r,{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("bounce",function(e,i){var s,n,o,a=t(this),r=e.mode,h="hide"===r,l="show"===r,c=e.direction||"up",u=e.distance,d=e.times||5,p=2*d+(l||h?1:0),f=e.duration/p,g=e.easing,m="up"===c||"down"===c?"top":"left",_="up"===c||"left"===c,v=0,b=a.queue().length;for(t.effects.createPlaceholder(a),o=a.css(m),u||(u=a["top"===m?"outerHeight":"outerWidth"]()/3),l&&(n={opacity:1},n[m]=o,a.css("opacity",0).css(m,_?2*-u:2*u).animate(n,f,g)),h&&(u/=Math.pow(2,d-1)),n={},n[m]=o;d>v;v++)s={},s[m]=(_?"-=":"+=")+u,a.animate(s,f,g).animate(n,f,g),u=h?2*u:u/2;h&&(s={opacity:0},s[m]=(_?"-=":"+=")+u,a.animate(s,f,g)),a.queue(i),t.effects.unshift(a,b,p+1)}),t.effects.define("clip","hide",function(e,i){var s,n={},o=t(this),a=e.direction||"vertical",r="both"===a,h=r||"horizontal"===a,l=r||"vertical"===a;s=o.cssClip(),n.clip={top:l?(s.bottom-s.top)/2:s.top,right:h?(s.right-s.left)/2:s.right,bottom:l?(s.bottom-s.top)/2:s.bottom,left:h?(s.right-s.left)/2:s.left},t.effects.createPlaceholder(o),"show"===e.mode&&(o.cssClip(n.clip),n.clip=s),o.animate(n,{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("drop","hide",function(e,i){var s,n=t(this),o=e.mode,a="show"===o,r=e.direction||"left",h="up"===r||"down"===r?"top":"left",l="up"===r||"left"===r?"-=":"+=",c="+="===l?"-=":"+=",u={opacity:0};t.effects.createPlaceholder(n),s=e.distance||n["top"===h?"outerHeight":"outerWidth"](!0)/2,u[h]=l+s,a&&(n.css(u),u[h]=c+s,u.opacity=1),n.animate(u,{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("explode","hide",function(e,i){function s(){b.push(this),b.length===u*d&&n()}function n(){p.css({visibility:"visible"}),t(b).remove(),i()}var o,a,r,h,l,c,u=e.pieces?Math.round(Math.sqrt(e.pieces)):3,d=u,p=t(this),f=e.mode,g="show"===f,m=p.show().css("visibility","hidden").offset(),_=Math.ceil(p.outerWidth()/d),v=Math.ceil(p.outerHeight()/u),b=[];for(o=0;u>o;o++)for(h=m.top+o*v,c=o-(u-1)/2,a=0;d>a;a++)r=m.left+a*_,l=a-(d-1)/2,p.clone().appendTo("body").wrap("
    ").css({position:"absolute",visibility:"visible",left:-a*_,top:-o*v}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:_,height:v,left:r+(g?l*_:0),top:h+(g?c*v:0),opacity:g?0:1}).animate({left:r+(g?0:l*_),top:h+(g?0:c*v),opacity:g?1:0},e.duration||500,e.easing,s)}),t.effects.define("fade","toggle",function(e,i){var s="show"===e.mode;t(this).css("opacity",s?0:1).animate({opacity:s?1:0},{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("fold","hide",function(e,i){var s=t(this),n=e.mode,o="show"===n,a="hide"===n,r=e.size||15,h=/([0-9]+)%/.exec(r),l=!!e.horizFirst,c=l?["right","bottom"]:["bottom","right"],u=e.duration/2,d=t.effects.createPlaceholder(s),p=s.cssClip(),f={clip:t.extend({},p)},g={clip:t.extend({},p)},m=[p[c[0]],p[c[1]]],_=s.queue().length;h&&(r=parseInt(h[1],10)/100*m[a?0:1]),f.clip[c[0]]=r,g.clip[c[0]]=r,g.clip[c[1]]=0,o&&(s.cssClip(g.clip),d&&d.css(t.effects.clipToBox(g)),g.clip=p),s.queue(function(i){d&&d.animate(t.effects.clipToBox(f),u,e.easing).animate(t.effects.clipToBox(g),u,e.easing),i()}).animate(f,u,e.easing).animate(g,u,e.easing).queue(i),t.effects.unshift(s,_,4)}),t.effects.define("highlight","show",function(e,i){var s=t(this),n={backgroundColor:s.css("backgroundColor")};"hide"===e.mode&&(n.opacity=0),t.effects.saveStyle(s),s.css({backgroundImage:"none",backgroundColor:e.color||"#ffff99"}).animate(n,{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("size",function(e,i){var s,n,o,a=t(this),r=["fontSize"],h=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],l=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],c=e.mode,u="effect"!==c,d=e.scale||"both",p=e.origin||["middle","center"],f=a.css("position"),g=a.position(),m=t.effects.scaledDimensions(a),_=e.from||m,v=e.to||t.effects.scaledDimensions(a,0);t.effects.createPlaceholder(a),"show"===c&&(o=_,_=v,v=o),n={from:{y:_.height/m.height,x:_.width/m.width},to:{y:v.height/m.height,x:v.width/m.width}},("box"===d||"both"===d)&&(n.from.y!==n.to.y&&(_=t.effects.setTransition(a,h,n.from.y,_),v=t.effects.setTransition(a,h,n.to.y,v)),n.from.x!==n.to.x&&(_=t.effects.setTransition(a,l,n.from.x,_),v=t.effects.setTransition(a,l,n.to.x,v))),("content"===d||"both"===d)&&n.from.y!==n.to.y&&(_=t.effects.setTransition(a,r,n.from.y,_),v=t.effects.setTransition(a,r,n.to.y,v)),p&&(s=t.effects.getBaseline(p,m),_.top=(m.outerHeight-_.outerHeight)*s.y+g.top,_.left=(m.outerWidth-_.outerWidth)*s.x+g.left,v.top=(m.outerHeight-v.outerHeight)*s.y+g.top,v.left=(m.outerWidth-v.outerWidth)*s.x+g.left),a.css(_),("content"===d||"both"===d)&&(h=h.concat(["marginTop","marginBottom"]).concat(r),l=l.concat(["marginLeft","marginRight"]),a.find("*[width]").each(function(){var i=t(this),s=t.effects.scaledDimensions(i),o={height:s.height*n.from.y,width:s.width*n.from.x,outerHeight:s.outerHeight*n.from.y,outerWidth:s.outerWidth*n.from.x},a={height:s.height*n.to.y,width:s.width*n.to.x,outerHeight:s.height*n.to.y,outerWidth:s.width*n.to.x};n.from.y!==n.to.y&&(o=t.effects.setTransition(i,h,n.from.y,o),a=t.effects.setTransition(i,h,n.to.y,a)),n.from.x!==n.to.x&&(o=t.effects.setTransition(i,l,n.from.x,o),a=t.effects.setTransition(i,l,n.to.x,a)),u&&t.effects.saveStyle(i),i.css(o),i.animate(a,e.duration,e.easing,function(){u&&t.effects.restoreStyle(i)})})),a.animate(v,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){var e=a.offset();0===v.opacity&&a.css("opacity",_.opacity),u||(a.css("position","static"===f?"relative":f).offset(e),t.effects.saveStyle(a)),i()}})}),t.effects.define("scale",function(e,i){var s=t(this),n=e.mode,o=parseInt(e.percent,10)||(0===parseInt(e.percent,10)?0:"effect"!==n?0:100),a=t.extend(!0,{from:t.effects.scaledDimensions(s),to:t.effects.scaledDimensions(s,o,e.direction||"both"),origin:e.origin||["middle","center"]},e);e.fade&&(a.from.opacity=1,a.to.opacity=0),t.effects.effect.size.call(this,a,i)}),t.effects.define("puff","hide",function(e,i){var s=t.extend(!0,{},e,{fade:!0,percent:parseInt(e.percent,10)||150});t.effects.effect.scale.call(this,s,i)}),t.effects.define("pulsate","show",function(e,i){var s=t(this),n=e.mode,o="show"===n,a="hide"===n,r=o||a,h=2*(e.times||5)+(r?1:0),l=e.duration/h,c=0,u=1,d=s.queue().length;for((o||!s.is(":visible"))&&(s.css("opacity",0).show(),c=1);h>u;u++)s.animate({opacity:c},l,e.easing),c=1-c;s.animate({opacity:c},l,e.easing),s.queue(i),t.effects.unshift(s,d,h+1)}),t.effects.define("shake",function(e,i){var s=1,n=t(this),o=e.direction||"left",a=e.distance||20,r=e.times||3,h=2*r+1,l=Math.round(e.duration/h),c="up"===o||"down"===o?"top":"left",u="up"===o||"left"===o,d={},p={},f={},g=n.queue().length;for(t.effects.createPlaceholder(n),d[c]=(u?"-=":"+=")+a,p[c]=(u?"+=":"-=")+2*a,f[c]=(u?"-=":"+=")+2*a,n.animate(d,l,e.easing);r>s;s++)n.animate(p,l,e.easing).animate(f,l,e.easing);n.animate(p,l,e.easing).animate(d,l/2,e.easing).queue(i),t.effects.unshift(n,g,h+1)}),t.effects.define("slide","show",function(e,i){var s,n,o=t(this),a={up:["bottom","top"],down:["top","bottom"],left:["right","left"],right:["left","right"]},r=e.mode,h=e.direction||"left",l="up"===h||"down"===h?"top":"left",c="up"===h||"left"===h,u=e.distance||o["top"===l?"outerHeight":"outerWidth"](!0),d={};t.effects.createPlaceholder(o),s=o.cssClip(),n=o.position()[l],d[l]=(c?-1:1)*u+n,d.clip=o.cssClip(),d.clip[a[h][1]]=d.clip[a[h][0]],"show"===r&&(o.cssClip(d.clip),o.css(l,d[l]),d.clip=s,d[l]=n),o.animate(d,{queue:!1,duration:e.duration,easing:e.easing,complete:i})});var v;t.uiBackCompat!==!1&&(v=t.effects.define("transfer",function(e,i){t(this).transfer(e,i)}))}); \ No newline at end of file diff --git a/js/jquery.min.js b/js/jquery.min.js index ab28a247..d467083b 100644 --- a/js/jquery.min.js +++ b/js/jquery.min.js @@ -1,4 +1,2 @@ -/*! jQuery v1.11.1 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ -!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.1",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b=a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+-new Date,v=a.document,w=0,x=0,y=gb(),z=gb(),A=gb(),B=function(a,b){return a===b&&(l=!0),0},C="undefined",D=1<<31,E={}.hasOwnProperty,F=[],G=F.pop,H=F.push,I=F.push,J=F.slice,K=F.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},L="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",N="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=N.replace("w","w#"),P="\\["+M+"*("+N+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+O+"))|)"+M+"*\\]",Q=":("+N+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+P+")*)|.*)\\)|)",R=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),S=new RegExp("^"+M+"*,"+M+"*"),T=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),V=new RegExp(Q),W=new RegExp("^"+O+"$"),X={ID:new RegExp("^#("+N+")"),CLASS:new RegExp("^\\.("+N+")"),TAG:new RegExp("^("+N.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+Q),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("^(?:"+L+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ab=/[+~]/,bb=/'|\\/g,cb=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),db=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{I.apply(F=J.call(v.childNodes),v.childNodes),F[v.childNodes.length].nodeType}catch(eb){I={apply:F.length?function(a,b){H.apply(a,J.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fb(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],!a||"string"!=typeof a)return d;if(1!==(k=b.nodeType)&&9!==k)return[];if(p&&!e){if(f=_.exec(a))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return I.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return I.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=9===k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(bb,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+qb(o[l]);w=ab.test(a)&&ob(b.parentNode)||b,x=o.join(",")}if(x)try{return I.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function gb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function hb(a){return a[u]=!0,a}function ib(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function jb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function kb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||D)-(~a.sourceIndex||D);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function lb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function mb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function nb(a){return hb(function(b){return b=+b,hb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function ob(a){return a&&typeof a.getElementsByTagName!==C&&a}c=fb.support={},f=fb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fb.setDocument=function(a){var b,e=a?a.ownerDocument||a:v,g=e.defaultView;return e!==n&&9===e.nodeType&&e.documentElement?(n=e,o=e.documentElement,p=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){m()},!1):g.attachEvent&&g.attachEvent("onunload",function(){m()})),c.attributes=ib(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ib(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(e.getElementsByClassName)&&ib(function(a){return a.innerHTML="
    ",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=ib(function(a){return o.appendChild(a).id=u,!e.getElementsByName||!e.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==C&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){var c=typeof a.getAttributeNode!==C&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==C?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==C&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(e.querySelectorAll))&&(ib(function(a){a.innerHTML="",a.querySelectorAll("[msallowclip^='']").length&&q.push("[*^$]="+M+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+M+"*(?:value|"+L+")"),a.querySelectorAll(":checked").length||q.push(":checked")}),ib(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+M+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ib(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",Q)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===v&&t(v,a)?-1:b===e||b.ownerDocument===v&&t(v,b)?1:k?K.call(k,a)-K.call(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],i=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:k?K.call(k,a)-K.call(k,b):0;if(f===g)return kb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?kb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},e):n},fb.matches=function(a,b){return fb(a,null,null,b)},fb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fb(b,n,null,[a]).length>0},fb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&E.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fb.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fb.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fb.selectors={cacheLength:50,createPseudo:hb,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(cb,db),a[3]=(a[3]||a[4]||a[5]||"").replace(cb,db),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fb.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(cb,db).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+M+")"+a+"("+M+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==C&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fb.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?hb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=K.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:hb(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?hb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:hb(function(a){return function(b){return fb(a,b).length>0}}),contains:hb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:hb(function(a){return W.test(a||"")||fb.error("unsupported lang: "+a),a=a.replace(cb,db).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:nb(function(){return[0]}),last:nb(function(a,b){return[b-1]}),eq:nb(function(a,b,c){return[0>c?c+b:c]}),even:nb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:nb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:nb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:nb(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function rb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function sb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function tb(a,b,c){for(var d=0,e=b.length;e>d;d++)fb(a,b[d],c);return c}function ub(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function vb(a,b,c,d,e,f){return d&&!d[u]&&(d=vb(d)),e&&!e[u]&&(e=vb(e,f)),hb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||tb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ub(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ub(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?K.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ub(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):I.apply(g,r)})}function wb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=rb(function(a){return a===b},h,!0),l=rb(function(a){return K.call(b,a)>-1},h,!0),m=[function(a,c,d){return!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>i;i++)if(c=d.relative[a[i].type])m=[rb(sb(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return vb(i>1&&sb(m),i>1&&qb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&wb(a.slice(i,e)),f>e&&wb(a=a.slice(e)),f>e&&qb(a))}m.push(c)}return sb(m)}function xb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=G.call(i));s=ub(s)}I.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&fb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?hb(f):f}return h=fb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xb(e,d)),f.selector=a}return f},i=fb.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(cb,db),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(cb,db),ab.test(j[0].type)&&ob(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qb(j),!a)return I.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&ob(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ib(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ib(function(a){return a.innerHTML="
    ","#"===a.firstChild.getAttribute("href")})||jb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ib(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||jb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ib(function(a){return null==a.getAttribute("disabled")})||jb(L,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fb}(a);m.find=s,m.expr=s.selectors,m.expr[":"]=m.expr.pseudos,m.unique=s.uniqueSort,m.text=s.getText,m.isXMLDoc=s.isXML,m.contains=s.contains;var t=m.expr.match.needsContext,u=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/^.[^:#\[\.,]*$/;function w(a,b,c){if(m.isFunction(b))return m.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return m.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(v.test(b))return m.filter(b,a,c);b=m.filter(b,a)}return m.grep(a,function(a){return m.inArray(a,b)>=0!==c})}m.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?m.find.matchesSelector(d,a)?[d]:[]:m.find.matches(a,m.grep(b,function(a){return 1===a.nodeType}))},m.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(m(a).filter(function(){for(b=0;e>b;b++)if(m.contains(d[b],this))return!0}));for(b=0;e>b;b++)m.find(a,d[b],c);return c=this.pushStack(e>1?m.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(w(this,a||[],!1))},not:function(a){return this.pushStack(w(this,a||[],!0))},is:function(a){return!!w(this,"string"==typeof a&&t.test(a)?m(a):a||[],!1).length}});var x,y=a.document,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=m.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||x).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof m?b[0]:b,m.merge(this,m.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:y,!0)),u.test(c[1])&&m.isPlainObject(b))for(c in b)m.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=y.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return x.find(a);this.length=1,this[0]=d}return this.context=y,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):m.isFunction(a)?"undefined"!=typeof x.ready?x.ready(a):a(m):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),m.makeArray(a,this))};A.prototype=m.fn,x=m(y);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};m.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!m(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),m.fn.extend({has:function(a){var b,c=m(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(m.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=t.test(a)||"string"!=typeof a?m(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&m.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?m.unique(f):f)},index:function(a){return a?"string"==typeof a?m.inArray(this[0],m(a)):m.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(m.unique(m.merge(this.get(),m(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}m.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return m.dir(a,"parentNode")},parentsUntil:function(a,b,c){return m.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return m.dir(a,"nextSibling")},prevAll:function(a){return m.dir(a,"previousSibling")},nextUntil:function(a,b,c){return m.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return m.dir(a,"previousSibling",c)},siblings:function(a){return m.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return m.sibling(a.firstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:m.merge([],a.childNodes)}},function(a,b){m.fn[a]=function(c,d){var e=m.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=m.filter(d,e)),this.length>1&&(C[a]||(e=m.unique(e)),B.test(a)&&(e=e.reverse())),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return m.each(a.match(E)||[],function(a,c){b[c]=!0}),b}m.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):m.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){m.each(b,function(b,c){var d=m.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&m.each(arguments,function(a,c){var d;while((d=m.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?m.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},m.extend({Deferred:function(a){var b=[["resolve","done",m.Callbacks("once memory"),"resolved"],["reject","fail",m.Callbacks("once memory"),"rejected"],["notify","progress",m.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return m.Deferred(function(c){m.each(b,function(b,f){var g=m.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&m.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?m.extend(a,d):d}},e={};return d.pipe=d.then,m.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&m.isFunction(a.promise)?e:0,g=1===f?a:m.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&m.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;m.fn.ready=function(a){return m.ready.promise().done(a),this},m.extend({isReady:!1,readyWait:1,holdReady:function(a){a?m.readyWait++:m.ready(!0)},ready:function(a){if(a===!0?!--m.readyWait:!m.isReady){if(!y.body)return setTimeout(m.ready);m.isReady=!0,a!==!0&&--m.readyWait>0||(H.resolveWith(y,[m]),m.fn.triggerHandler&&(m(y).triggerHandler("ready"),m(y).off("ready")))}}});function I(){y.addEventListener?(y.removeEventListener("DOMContentLoaded",J,!1),a.removeEventListener("load",J,!1)):(y.detachEvent("onreadystatechange",J),a.detachEvent("onload",J))}function J(){(y.addEventListener||"load"===event.type||"complete"===y.readyState)&&(I(),m.ready())}m.ready.promise=function(b){if(!H)if(H=m.Deferred(),"complete"===y.readyState)setTimeout(m.ready);else if(y.addEventListener)y.addEventListener("DOMContentLoaded",J,!1),a.addEventListener("load",J,!1);else{y.attachEvent("onreadystatechange",J),a.attachEvent("onload",J);var c=!1;try{c=null==a.frameElement&&y.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!m.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}I(),m.ready()}}()}return H.promise(b)};var K="undefined",L;for(L in m(k))break;k.ownLast="0"!==L,k.inlineBlockNeedsLayout=!1,m(function(){var a,b,c,d;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",k.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(d))}),function(){var a=y.createElement("div");if(null==k.deleteExpando){k.deleteExpando=!0;try{delete a.test}catch(b){k.deleteExpando=!1}}a=null}(),m.acceptData=function(a){var b=m.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var M=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,N=/([A-Z])/g;function O(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(N,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:M.test(c)?m.parseJSON(c):c}catch(e){}m.data(a,b,c)}else c=void 0}return c}function P(a){var b;for(b in a)if(("data"!==b||!m.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h; -if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML="
    a",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function ab(){return!0}function bb(){return!1}function cb(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=m.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(E)||[""],h=b.length;while(h--)f=_.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=m.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=m.event.special[o]||{},l=m.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&m.expr.match.needsContext.test(e),namespace:p.join(".")},i),(n=g[o])||(n=g[o]=[],n.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?n.splice(n.delegateCount++,0,l):n.push(l),m.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m.hasData(a)&&m._data(a);if(r&&(k=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=_.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=m.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,n=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=n.length;while(f--)g=n[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(n.splice(f,1),g.selector&&n.delegateCount--,l.remove&&l.remove.call(a,g));i&&!n.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||m.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)m.event.remove(a,o+b[j],c,d,!0);m.isEmptyObject(k)&&(delete r.handle,m._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,o=[d||y],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||y,3!==d.nodeType&&8!==d.nodeType&&!$.test(p+m.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[m.expando]?b:new m.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:m.makeArray(c,[b]),k=m.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!m.isWindow(d)){for(i=k.delegateType||p,$.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||y)&&o.push(l.defaultView||l.parentWindow||a)}n=0;while((h=o[n++])&&!b.isPropagationStopped())b.type=n>1?i:k.bindType||p,f=(m._data(h,"events")||{})[b.type]&&m._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&m.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&m.acceptData(d)&&g&&d[p]&&!m.isWindow(d)){l=d[g],l&&(d[g]=null),m.event.triggered=p;try{d[p]()}catch(r){}m.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=m.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(m._data(this,"events")||{})[a.type]||[],k=m.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=m.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((m.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?m(c,this).index(i)>=0:m.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h]","i"),hb=/^\s+/,ib=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,jb=/<([\w:]+)/,kb=/\s*$/g,rb={option:[1,""],legend:[1,"
    ","
    "],area:[1,"",""],param:[1,"",""],thead:[1,"","
    "],tr:[2,"","
    "],col:[2,"","
    "],td:[3,"","
    "],_default:k.htmlSerialize?[0,"",""]:[1,"X
    ","
    "]},sb=db(y),tb=sb.appendChild(y.createElement("div"));rb.optgroup=rb.option,rb.tbody=rb.tfoot=rb.colgroup=rb.caption=rb.thead,rb.th=rb.td;function ub(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==K?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==K?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||m.nodeName(d,b)?f.push(d):m.merge(f,ub(d,b));return void 0===b||b&&m.nodeName(a,b)?m.merge([a],f):f}function vb(a){W.test(a.type)&&(a.defaultChecked=a.checked)}function wb(a,b){return m.nodeName(a,"table")&&m.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function xb(a){return a.type=(null!==m.find.attr(a,"type"))+"/"+a.type,a}function yb(a){var b=pb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function zb(a,b){for(var c,d=0;null!=(c=a[d]);d++)m._data(c,"globalEval",!b||m._data(b[d],"globalEval"))}function Ab(a,b){if(1===b.nodeType&&m.hasData(a)){var c,d,e,f=m._data(a),g=m._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)m.event.add(b,c,h[c][d])}g.data&&(g.data=m.extend({},g.data))}}function Bb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!k.noCloneEvent&&b[m.expando]){e=m._data(b);for(d in e.events)m.removeEvent(b,d,e.handle);b.removeAttribute(m.expando)}"script"===c&&b.text!==a.text?(xb(b).text=a.text,yb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),k.html5Clone&&a.innerHTML&&!m.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&W.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}m.extend({clone:function(a,b,c){var d,e,f,g,h,i=m.contains(a.ownerDocument,a);if(k.html5Clone||m.isXMLDoc(a)||!gb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(tb.innerHTML=a.outerHTML,tb.removeChild(f=tb.firstChild)),!(k.noCloneEvent&&k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||m.isXMLDoc(a)))for(d=ub(f),h=ub(a),g=0;null!=(e=h[g]);++g)d[g]&&Bb(e,d[g]);if(b)if(c)for(h=h||ub(a),d=d||ub(f),g=0;null!=(e=h[g]);g++)Ab(e,d[g]);else Ab(a,f);return d=ub(f,"script"),d.length>0&&zb(d,!i&&ub(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,l,n=a.length,o=db(b),p=[],q=0;n>q;q++)if(f=a[q],f||0===f)if("object"===m.type(f))m.merge(p,f.nodeType?[f]:f);else if(lb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(jb.exec(f)||["",""])[1].toLowerCase(),l=rb[i]||rb._default,h.innerHTML=l[1]+f.replace(ib,"<$1>")+l[2],e=l[0];while(e--)h=h.lastChild;if(!k.leadingWhitespace&&hb.test(f)&&p.push(b.createTextNode(hb.exec(f)[0])),!k.tbody){f="table"!==i||kb.test(f)?""!==l[1]||kb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)m.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}m.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),k.appendChecked||m.grep(ub(p,"input"),vb),q=0;while(f=p[q++])if((!d||-1===m.inArray(f,d))&&(g=m.contains(f.ownerDocument,f),h=ub(o.appendChild(f),"script"),g&&zb(h),c)){e=0;while(f=h[e++])ob.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=m.expando,j=m.cache,l=k.deleteExpando,n=m.event.special;null!=(d=a[h]);h++)if((b||m.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)n[e]?m.event.remove(d,e):m.removeEvent(d,e,g.handle);j[f]&&(delete j[f],l?delete d[i]:typeof d.removeAttribute!==K?d.removeAttribute(i):d[i]=null,c.push(f))}}}),m.fn.extend({text:function(a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?m.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||m.cleanData(ub(c)),c.parentNode&&(b&&m.contains(c.ownerDocument,c)&&zb(ub(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&m.cleanData(ub(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&m.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return m.clone(this,a,b)})},html:function(a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fb,""):void 0;if(!("string"!=typeof a||mb.test(a)||!k.htmlSerialize&&gb.test(a)||!k.leadingWhitespace&&hb.test(a)||rb[(jb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ib,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ub(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,m.cleanData(ub(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,n=this,o=l-1,p=a[0],q=m.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&nb.test(p))return this.each(function(c){var d=n.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(i=m.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=m.map(ub(i,"script"),xb),f=g.length;l>j;j++)d=i,j!==o&&(d=m.clone(d,!0,!0),f&&m.merge(g,ub(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,m.map(g,yb),j=0;f>j;j++)d=g[j],ob.test(d.type||"")&&!m._data(d,"globalEval")&&m.contains(h,d)&&(d.src?m._evalUrl&&m._evalUrl(d.src):m.globalEval((d.text||d.textContent||d.innerHTML||"").replace(qb,"")));i=c=null}return this}}),m.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){m.fn[a]=function(a){for(var c,d=0,e=[],g=m(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),m(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Cb,Db={};function Eb(b,c){var d,e=m(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:m.css(e[0],"display");return e.detach(),f}function Fb(a){var b=y,c=Db[a];return c||(c=Eb(a,b),"none"!==c&&c||(Cb=(Cb||m("