From e59816de207fa6e565e21f9330dc035a6dc1b1f9 Mon Sep 17 00:00:00 2001 From: Christian Moser Date: Thu, 28 Nov 2024 01:57:21 +0100 Subject: [PATCH] 2024.11.28 01:57:21 --- PO/POTFILES | 12 + PO/compilemessages | 5 +- PO/de.po | 145 +++++- PO/makemessages | 35 ++ PO/messages.pot | 134 +++++- PO/mkpotfiles.sh | 61 --- assets/styles/app.css | 16 + config/config.yaml | 2 + config/packages/translation.yaml | 8 +- config/services.yaml | 10 +- ...26213642.php => Version20241127204952.php} | 2 +- scripts/run_dispatched | 41 ++ src/Constants/const.php | 3 + src/Controller/SetupController.php | 175 ++++--- src/Controller/WebrootSetupController.php | 435 +++++++++++++++++- src/Repository/WebrootRoleRepository.php | 8 + src/Utility/i18n.php | 39 ++ templates/setup/initial-setup.html.twig | 116 ++++- translations/de/LC_MESSAGES/messages.mo | Bin 337 -> 0 bytes .../de/LC_MESSAGES/mydevel-webroot.mo | Bin 0 -> 1876 bytes .../de/LC_MESSAGES/mydevel.webroot.mo | Bin 337 -> 0 bytes translations/security.de.yaml | 19 + translations/security.en.yaml | 19 + translations/validators.de.yaml | 187 ++++++++ translations/validators.en.yaml | 187 ++++++++ 25 files changed, 1480 insertions(+), 179 deletions(-) create mode 100644 PO/makemessages delete mode 100644 PO/mkpotfiles.sh create mode 100644 config/config.yaml rename migrations/{Version20241126213642.php => Version20241127204952.php} (98%) create mode 100644 scripts/run_dispatched create mode 100644 src/Constants/const.php create mode 100644 src/Utility/i18n.php delete mode 100644 translations/de/LC_MESSAGES/messages.mo create mode 100644 translations/de/LC_MESSAGES/mydevel-webroot.mo delete mode 100644 translations/de/LC_MESSAGES/mydevel.webroot.mo create mode 100644 translations/security.de.yaml create mode 100644 translations/security.en.yaml create mode 100644 translations/validators.de.yaml create mode 100644 translations/validators.en.yaml diff --git a/PO/POTFILES b/PO/POTFILES index e2894a8..f1229f0 100644 --- a/PO/POTFILES +++ b/PO/POTFILES @@ -1,4 +1,16 @@ +../src/Constants/const.php ../src/Controller/MainController.php ../src/Controller/SecurityController.php ../src/Controller/SetupController.php +../src/Controller/WebrootController.php +../src/Controller/WebrootSetupController.php +../src/Entity/WebrootFile.php +../src/Entity/WebrootFilePermission.php +../src/Entity/WebrootRole.php +../src/Entity/WebrootUser.php ../src/Kernel.php +../src/Repository/WebrootFilePermissionRepository.php +../src/Repository/WebrootFileRepository.php +../src/Repository/WebrootRoleRepository.php +../src/Repository/WebrootUserRepository.php +../src/Utility/i18n.php diff --git a/PO/compilemessages b/PO/compilemessages index 4766057..54f499d 100644 --- a/PO/compilemessages +++ b/PO/compilemessages @@ -13,10 +13,7 @@ for i in `cat LINGUAS`; do fi if [ -f $i.po ]; then - msgfmt -o "$msgdir/messages.mo" $i.po - fi - if [ -f webroot/$i.po ]; then - msgfmt -o "$msgdir/mydevel.webroot.mo" "webroot/$i.po" + msgfmt -o "$msgdir/mydevel-webroot.mo" $i.po fi done diff --git a/PO/de.po b/PO/de.po index 4ee1245..e8a5ee7 100644 --- a/PO/de.po +++ b/PO/de.po @@ -6,13 +6,146 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" +"Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-11-26 20:44+0100\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: \n" +"POT-Creation-Date: 2024-11-27 19:03+0100\n" +"PO-Revision-Date: 2024-11-27 19:12+0100\n" +"Last-Translator: Christian Moser \n" +"Language-Team: \n" +"Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.5\n" + +#: ../src/Controller/SetupController.php:45 +msgid "Email Settings" +msgstr "Email Einstellungen" + +#: ../src/Controller/SetupController.php:46 +msgid "Site Settings" +msgstr "Site Einstellungen" + +#: ../src/Controller/SetupController.php:47 +msgid "Database Settings" +msgstr "Datenbank Einstellungen" + +#: ../src/Controller/SetupController.php:48 +msgid "User Settings" +msgstr "Nutzer Einstellungen" + +#: ../src/Controller/SetupController.php:56 +msgid "Enter the site name that should be displayed in titles." +msgstr "Gib den Setiennamen and, der in Titeln angezeigt werden soll." + +#: ../src/Controller/SetupController.php:57 +msgid "Site name" +msgstr "Name der Site" + +#: ../src/Controller/SetupController.php:61 +msgid "Site root directory" +msgstr "Wurzelverzeichnis" + +#: ../src/Controller/SetupController.php:65 +msgid "Contact email" +msgstr "Kontakt Email" + +#: ../src/Controller/SetupController.php:69 +msgid "Username" +msgstr "Nutzername" + +#: ../src/Controller/SetupController.php:73 +msgid "Email" +msgstr "Email" + +#: ../src/Controller/SetupController.php:77 +#: ../src/Controller/SetupController.php:117 +#: ../src/Controller/SetupController.php:144 +msgid "Password" +msgstr "Passwort" + +#: ../src/Controller/SetupController.php:81 +msgid "Confirm Password" +msgstr "Passwort bestätigen" + +#: ../src/Controller/SetupController.php:84 +msgid "Run Migrations?" +msgstr "Migrationen anwenden?" + +#: ../src/Controller/SetupController.php:93 +msgid "SQLite3" +msgstr "SQLite3" + +#: ../src/Controller/SetupController.php:94 +msgid "MySQL/MariaDB" +msgstr "MySQL/MariaDB" + +#: ../src/Controller/SetupController.php:95 +msgid "PostgreSQL" +msgstr "PostgreSQL" + +#: ../src/Controller/SetupController.php:96 +#: ../src/Controller/SetupController.php:120 +msgid "Database URL" +msgstr "Datenbank URL" + +#: ../src/Controller/SetupController.php:101 +msgid "Database" +msgstr "Datenbank" + +#: ../src/Controller/SetupController.php:105 +msgid "Host" +msgstr "Host" + +#: ../src/Controller/SetupController.php:109 +msgid "Port" +msgstr "Port" + +#: ../src/Controller/SetupController.php:113 +#: ../src/Controller/SetupController.php:140 +msgid "User" +msgstr "Nutzer" + +#: ../src/Controller/SetupController.php:124 +msgid "Backend" +msgstr "Backend" + +#: ../src/Controller/SetupController.php:127 +msgid "No email support" +msgstr "Keine Emailunterstützung" + +#: ../src/Controller/SetupController.php:128 +msgid "SMTP" +msgstr "SMTP" + +#: ../src/Controller/SetupController.php:129 +msgid "Sendmail" +msgstr "Sendmail" + +#: ../src/Controller/SetupController.php:130 +msgid "Naitve" +msgstr "Nativ" + +#: ../src/Controller/SetupController.php:131 +msgid "User DSN" +msgstr "Nutzer DSN" + +#: ../src/Controller/SetupController.php:136 +msgid "Email Path" +msgstr "Email-Pfad" + +#: ../src/Controller/SetupController.php:148 +msgid "SMTP Host" +msgstr "SMTP Host" + +#: ../src/Controller/SetupController.php:152 +msgid "SMTP Port" +msgstr "SMTP Port" + +#: ../src/Controller/SetupController.php:156 +msgid "DSN" +msgstr "DSN" + +#: ../src/Controller/SetupController.php:160 +msgid "Sender address" +msgstr "Adresse des Senders" diff --git a/PO/makemessages b/PO/makemessages new file mode 100644 index 0000000..c036930 --- /dev/null +++ b/PO/makemessages @@ -0,0 +1,35 @@ +#!/bin/sh + +SELF="$(realpath "$0")" +PODIR="$(dirname "$SELF")" +PROJECT_ROOT="$(dirname "$PODIR")" + +cd "$PODIR" + +echo "Creating POTFILES" +rm -v POTFILES + +for i in $(find ../src | grep '\.*php$'); do + echo $i >> POTFILES +done +if [ -f messages.pot ]; then + JOIN="--join-existing" +else + JOIN="" +fi +echo "extracting messages" + +xgettext -f POTFILES -d mydevel.webroot -L PHP $JOIN --force-po -o messages.pot +if [ -z "$JOIN" ]; then + sed -i s/charset=CHARSET/charset=UTF-8/g messages.pot +fi + +for i in `cat LINGUAS`; do + if [ ! -f $i.po ]; then + cp messages.pot $i.po + else + msgmerge $i.po messages.pot + fi +done + + diff --git a/PO/messages.pot b/PO/messages.pot index 4ee1245..c5fc16e 100644 --- a/PO/messages.pot +++ b/PO/messages.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-11-26 20:44+0100\n" +"POT-Creation-Date: 2024-11-27 19:03+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -16,3 +16,135 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" + +#: ../src/Controller/SetupController.php:45 +msgid "Email Settings" +msgstr "" + +#: ../src/Controller/SetupController.php:46 +msgid "Site Settings" +msgstr "" + +#: ../src/Controller/SetupController.php:47 +msgid "Database Settings" +msgstr "" + +#: ../src/Controller/SetupController.php:48 +msgid "User Settings" +msgstr "" + +#: ../src/Controller/SetupController.php:56 +msgid "Enter the site name that should be displayed in titles." +msgstr "" + +#: ../src/Controller/SetupController.php:57 +msgid "Site name" +msgstr "" + +#: ../src/Controller/SetupController.php:61 +msgid "Site root directory" +msgstr "" + +#: ../src/Controller/SetupController.php:65 +msgid "Contact email" +msgstr "" + +#: ../src/Controller/SetupController.php:69 +msgid "Username" +msgstr "" + +#: ../src/Controller/SetupController.php:73 +msgid "Email" +msgstr "" + +#: ../src/Controller/SetupController.php:77 +#: ../src/Controller/SetupController.php:117 +#: ../src/Controller/SetupController.php:144 +msgid "Password" +msgstr "" + +#: ../src/Controller/SetupController.php:81 +msgid "Confirm Password" +msgstr "" + +#: ../src/Controller/SetupController.php:84 +msgid "Run Migrations?" +msgstr "" + +#: ../src/Controller/SetupController.php:93 +msgid "SQLite3" +msgstr "" + +#: ../src/Controller/SetupController.php:94 +msgid "MySQL/MariaDB" +msgstr "" + +#: ../src/Controller/SetupController.php:95 +msgid "PostgreSQL" +msgstr "" + +#: ../src/Controller/SetupController.php:96 +#: ../src/Controller/SetupController.php:120 +msgid "Database URL" +msgstr "" + +#: ../src/Controller/SetupController.php:101 +msgid "Database" +msgstr "" + +#: ../src/Controller/SetupController.php:105 +msgid "Host" +msgstr "" + +#: ../src/Controller/SetupController.php:109 +msgid "Port" +msgstr "" + +#: ../src/Controller/SetupController.php:113 +#: ../src/Controller/SetupController.php:140 +msgid "User" +msgstr "" + +#: ../src/Controller/SetupController.php:124 +msgid "Backend" +msgstr "" + +#: ../src/Controller/SetupController.php:127 +msgid "No email support" +msgstr "" + +#: ../src/Controller/SetupController.php:128 +msgid "SMTP" +msgstr "" + +#: ../src/Controller/SetupController.php:129 +msgid "Sendmail" +msgstr "" + +#: ../src/Controller/SetupController.php:130 +msgid "Naitve" +msgstr "" + +#: ../src/Controller/SetupController.php:131 +msgid "User DSN" +msgstr "" + +#: ../src/Controller/SetupController.php:136 +msgid "Email Path" +msgstr "" + +#: ../src/Controller/SetupController.php:148 +msgid "SMTP Host" +msgstr "" + +#: ../src/Controller/SetupController.php:152 +msgid "SMTP Port" +msgstr "" + +#: ../src/Controller/SetupController.php:156 +msgid "DSN" +msgstr "" + +#: ../src/Controller/SetupController.php:160 +msgid "Sender address" +msgstr "" diff --git a/PO/mkpotfiles.sh b/PO/mkpotfiles.sh deleted file mode 100644 index 738b6f3..0000000 --- a/PO/mkpotfiles.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/bin/sh - -SELF="$(realpath "$0")" -PODIR="$(dirname "$SELF")" -PROJECT_ROOT="$(dirname "$PODIR")" - -cd "$PODIR" - -echo "Creating POTFILES" -rm -v POTFILES - -for i in $(find ../src | grep '\.php' | grep -v '\.\./src/MyDevel'); do - echo $i >> POTFILES -done -if [ -f messages.pot ]; then - JOIN="--join-existing" -else - JOIN="" -fi -echo "extracting messages" - -xgettext -f POTFILES -d messages -L PHP $JOIN --force-po -o messages.pot -if [ -z "$JOIN" ]; then - sed -i s/charset=CHARSET/charset=UTF-8/g messages.pot -fi - -for i in `cat LINGUAS`; do - if [ ! -f $i.po ]; then - cp messages.pot $i.po - else - msgmerge $i.po messages.pot - fi -done - -echo "Creating POTFILES.webroot" -rm -v POTFILES.webroot -for i in $(find ../src/MyDevel/Webroot | grep '\.php'); do - echo $i >> POTFILES.webroot -done - -if [ ! -d webroot ]; then - mkdir -v webroot -fi - -if [ -f webroot/messages.pot ]; then - JOIN="--join-existing" -else - JOIN="" -fi -xgettext -d mydevel.webroot -f POTFILES.webroot -L PHP $JOIN --force-po -o webroot/messages.pot -if [ -z "$JOIN" ]; then - sed -i s/charset=CHARSET/charset=UTF-8/g webroot/messages.pot -fi -for i in `cat LINGUAS`; do - if [ ! -f webroot/$i.po ]; then - cp webroot/messages.pot webroot/$i.po - else - msgmerge webroot/$i.po webroot/messages.pot - fi -done - diff --git a/assets/styles/app.css b/assets/styles/app.css index 1d84a8d..ad8375f 100644 --- a/assets/styles/app.css +++ b/assets/styles/app.css @@ -274,3 +274,19 @@ code { background-color: var(--color-background); color: var(--color-text); } + +.shrink-to-fit { + width:0.1%; + white-space:nowrap; +} + +.standard-background { + background-color: var(--color-background); +} + +fieldset { + border: 2px var(--color-text) solid; + border-radius: 4px; + margin-top: 5px; + margin-bottom: 5px; +} diff --git a/config/config.yaml b/config/config.yaml new file mode 100644 index 0000000..0b4096f --- /dev/null +++ b/config/config.yaml @@ -0,0 +1,2 @@ +framework: + default_locale: de diff --git a/config/packages/translation.yaml b/config/packages/translation.yaml index b3f8f9c..a1d4d3e 100644 --- a/config/packages/translation.yaml +++ b/config/packages/translation.yaml @@ -1,7 +1,13 @@ framework: - default_locale: en + default_locale: de translator: default_path: '%kernel.project_dir%/translations' fallbacks: - en providers: + mo: + dsn: '%kernel.project_dir%/translations' + locales: [de] + domains: [mydevel_webroot,messages] + + diff --git a/config/services.yaml b/config/services.yaml index b66817b..c675c86 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -29,7 +29,15 @@ services: tags: ['controller.service_arguments'] - + translation.loader.po: + class: Symfony\Component\Translation\Loader\PoFileLoader + tags: + - { name: translation.loader, alias: po } + tranlation.loader.mo: + class: Symfony\Component\Translation\Loader\MoFileLoader + tags: + - { name: translation.loader, alias: mo } + # add more service definitions when explicit configuration is needed # please note that last definitions always *replace* previous ones diff --git a/migrations/Version20241126213642.php b/migrations/Version20241127204952.php similarity index 98% rename from migrations/Version20241126213642.php rename to migrations/Version20241127204952.php index 08ebc8d..918a4b2 100644 --- a/migrations/Version20241126213642.php +++ b/migrations/Version20241127204952.php @@ -10,7 +10,7 @@ use Doctrine\Migrations\AbstractMigration; /** * Auto-generated Migration: Please modify to your needs! */ -final class Version20241126213642 extends AbstractMigration +final class Version20241127204952 extends AbstractMigration { public function getDescription(): string { diff --git a/scripts/run_dispatched b/scripts/run_dispatched new file mode 100644 index 0000000..18f68d9 --- /dev/null +++ b/scripts/run_dispatched @@ -0,0 +1,41 @@ +#!/bin/sh +# vim: syn=sh ts=4 sts=4 sw=4 ff=unix smartindent expandtab + + +#set default script interval to 5 minutes +: ${SCRIPT_INTERVAL:=300} +: ${TASK_SLEEP_TIME:=2} +: ${TASK_DIR:=${HOME}/.tasks} +: ${TASK_WAITING_DIR:=${TASK_DIR}/waiting} +: ${TASK_RUNNING_DIR:=${TASK_DIR}/running} + +$start=`time +%s` +$end=$(( $start + $SCRIPT_INTERVAL )) + +if [ ! -d "$TASK_DIR" ]; then + mkdir -p "$TASK_DIR" +fi +if [ ! -d "$TASK_WAITING_DIR" ]; then + mkdir -p "$TASK_WAITING_DIR" +fi +if [ ! -d "$TASK_RUNNING_DIR" ]; then + mkdir -p "$TASK_RUNNING_DIR" +if + +run_task() { + task="$1" + $task + rm $task +} + +while [ `time +%s` -lt $end ]; do + for waiting in `ls ${TASK_WAITING_DIR}`; do + if [ -x $waiting ]; then + task=${TASK_RUNNING_DIR}/`basename $waiting` + mv $waiting $task + run_task "$task" & + fi + done + sleep $TASK_SLEEP_TIME +done + diff --git a/src/Constants/const.php b/src/Constants/const.php new file mode 100644 index 0000000..16122ca --- /dev/null +++ b/src/Constants/const.php @@ -0,0 +1,3 @@ +getProjectDir(),".env"]); $dotenvlocal_file = join(DIRECTORY_SEPARATOR,[$this->getProjectDir(),".env.local"]); $errors = array(); @@ -30,93 +35,40 @@ class SetupController extends WebrootSetupController fclose($file); } - $form = $this->createFormBuilder() - ->add('language',FormType\TextType::class,) - ->add('site_name',FormType\TextType::class,[ - "mapped"=>false, - "label" => "Site name"]) - ->add('site_rootdir',FormType\TextType::class,[ - "mapped"=>false, - "label" => "Site Root Directory"]) - ->add('site_email',FormType\EmailType::class,[ - "mapped"=>false, - "label" => "Contact email"]) - ->add('user_username',FormType\TextType::class,[ - "mapped"=>false, - "label"=>"Username"]) - ->add('user_email',FormType\EmailType::class,[ - "mapped"=>false, - "label"=> "Email address"]) - ->add("user_password0", FormType\PasswordType::class,[ - "mapped"=>false, - "label"=>"Password"]) - ->add("user_password1",FormType\PasswordType::class,[ - "mapped"=>false, - "label"=>"Confirm Password"]) - ->add('db_backend',FormType\ChoiceType::class,[ - "mapped" => false, - "label" => "Database Backend", - "choices" => [ - "sqlite" => "SQLite3", - "mysql" => "MySQL/MariaDB", - "postgresql" => "PostgreSQL", - ]]) - ->add('db_database',FormType\TextType::class,[ - "mapped"=>false, - "label"=>"Database"]) - ->add('db_host', FormType\TextType::class,[ - "mapped"=>false, - "label"=>"Host"]) - ->add('db_port', FormType\IntegerType::class,[ - "mapped"=>false, - "label"=>"Port"]) - ->add('db_user',FormType\TextType::class,[ - "mapped"=>false, - "label"=>"User"]) - ->add('db_password',FormType\TextType::class,[ - "mapped"=>false, - "label"=>"Password"]) - ->add('email_backend', FormType\ChoiceType::class, [ - "mapped"=>false, - "label" => "Email Backend", - "choices"=> [ - "none", "None", - "smtp", "SMTP", - "sendmail","Sendmail", - "native","Naitve", - ]]) - ->add('email_path',FormType\TextType::class,[ - "mapped"=>false, - "label"=>"Email Path"]) - ->add('email_user',FormType\TextType::class,[ - "mapped"=>false, - "label"=>"User"]) - ->add('email_password', FormType\PasswordType::class,[ - "mapped"=>false, - "label"=> "Password"]) - ->add('email_host',FormType\TextType::class,[ - "mapped"=>false, - "label"=>"SMTP Host"]) - ->add('email_port',FormType\TextType::class,[ - "mapped"=>false, - "label"=>"SMTP Port"]) - ->add('email_address', FormType\EmailType::class,[ - "mapped"=>false, - "label"=>"Sender address"]) - ->add('submit', FormType\SubmitType::class) - ->getForm(); + $command_output=['migration'=>"",'migrate'=>""]; + $have_migration_output=false; + + $translations=[ + 'email'=>_("Email Settings"), + 'site' => _("Site Settings"), + 'db' => _("Database Settings"), + 'user' => _("User Settings"), + ]; + + $form = $this->createSetupForm(); + $this->setSetupFormDefaultsFromEnv($form); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { - $password0 = $form.get('user_password0')->getData(); - $password1 = $form.get('user_password1')->get_data(); - $errors[] = "Passwords dont match"; + $password0 = $form->get('user_password0')->getData(); + $password1 = $form->get('user_password1')->getData(); + if (strlen($password0) < 8) { + array_push($errors,"Password does not have the minimal length of 8 characters!"); + } + if (strcmp($password0,$password1)) { + array_push($errors,"Passwords dont match!"); + } //if passwords don't match rerender form. - return $this->render("setup/initial-setup.html.twig",[ - "error" => $errors, - "form" => $form]); + if (count($errors) > 0) { + return $this->render("setup/initial-setup.html.twig",[ + "errors" => $errors, + "form" => $form, + "translations" => $translations, + "have_migration_output"=>false, + "command_output"=>$command_output]); + } $dotevnlocal = join(DIRECTORY_SEPARATOR,[$this->getProjectDir(),'.env.local']); @@ -126,20 +78,21 @@ class SetupController extends WebrootSetupController if ($language || strlen($language) > 1) { fwrite($file,"LANG=\"" . $language . "\"\n"); } + fwrite($file,"APP_LOCALEDIR=\"%kernel.project_dir%/Translations\""); fwrite($file,"SITE_NAME=\"" . $form->get("site_name")->getNormData() . "\"\n"); fwrite($file,"SITE_EMAIL=\"". $form->get('site_email')->getNormData() . "\"\n"); $db_backend=$form->get('db_backend')->getNormData(); if ($db_backend === "sqlite") { - fwrite("DATABASE_URL=\"sqlite://" . $form.get('db_database') . "\"\n"); + fwrite($file,"DATABASE_URL=\"sqlite://" . $form->get('db_database')->getNormData() . "\"\n"); } elseif ($db_backend === "mysql") { fwrite("DATABASE_URL=\"msysql://" . urlencode($form.get('db_user')->getNormData()) - . ":" . urlencode($form.get('db_password')->getNormData()) - . "@" . urlencode($form.get('db_host')->getNormData()) + . ":" . urlencode($form->get('db_password')->getNormData()) + . "@" . urlencode($form->get('db_host')->getNormData()) . ":" . $form.get('db_port')->getNormData() - . "/" . urlencode($form.get('db_database')->getNormData()) + . "/" . urlencode($form->get('db_database')->getNormData()) . "?charset=utf8mb4\"\n"); } elseif ($db_backend === "postgresql") { fwrite("DATABASE_URL=\"postgresql://" @@ -147,22 +100,30 @@ class SetupController extends WebrootSetupController . ":" . urlencode($form->get('db_password')->getNormData()) . "@" . urlencode($form->get('db_host')->getNormData()) . ":" . $form->get('db_port')->getNormData() - . "/" . urlencode($form.get('db_database')->getNormData()) + . "/" . urlencode($form->get('db_database')->getNormData()) . "?charset=utf8"); } fclose($file); (new Dotenv())->loadEnv(join(DIRECTORY_SEPARATOR,[$this->getProjectDir(),".env"])); try { - $migration_message = $this->runMakeMigration(); - $migrate_message = $this->runMigrate(); + $have_migration_output=true; + + $command_output["migration"] = $this->runMakeMigration(); + $create_database = $form->get('db_create')->getNormData(); + if ($create_database) { + $command_output["create_database"] = $this->runCreateDatabase(); + } + + $command_output["migrate"] = $this->runMigrate(); $user = new WebrootUser(); $user->setAdmin(true); $user->setUsername($form->get('user_username')->getNormData()); $user->setRoles(["ROLE_SUPERADMIN","ROLE_ADMIN","ROLE_USER"]); $user->setEmail($form->get("user_email")->getNormData()); - $user->set_password($passwd_hasher->hashPassword($user, $password0)); + $user->setPassword($passwd_hasher->hashPassword($user, $password0)); $em->persist($user); + $em->flush(); foreach($this->getInitialRoles() as $roledata) { $role = new WebrootRole(); @@ -171,19 +132,46 @@ class SetupController extends WebrootSetupController $role->setDescription($roledata["description"]); $em->persist($role); } + $em->flush(); + + $rootdir = $form->get("site_rootdir")->getNormData(); + $db_rootdir = new WebrootFile(); + $db_rootdir->setUrl("/weboot"); + $db_rootdir->setPath($rootdir); + $db_rootdir->setDescription($webroot); + $em->persist($db_rootdir); + $em->flush(); + + $db_file_repos = $em->getRespository(WebrootFile::class); + $db_role_repos = $em->getRepository(WebroorRole::class); + + $role = findByRoleName("ROLE_SUPERADMIN"); + $perm = new App\Entity\WebrootFilePermission(); + $perm->setWebrootFile($db_rootdir); + $perm->setReadable(true); + $perm->setWriteable(true); + $perm->setDeleteable(true); + $perm->setRole($role); + + $rm->persist($perm); + $rm->flush(); + return redirectToRoute("app_login"); } catch (\Exception $ex) { + array_push($errors,$ex->getMessage()); unlink($dotevnlocal); - $errors[] = $ex->getMessage(); + throw $ex; } finally { - } - + } } return $this->render('setup/initial-setup.html.twig', [ "form" => $form, - "errors" => $errors + "errors" => $errors, + "translations" => $translations, + "have_migration_output"=>true, + "command_output"=>$command_output, ]); } @@ -204,7 +192,6 @@ class SetupController extends WebrootSetupController ]); } - #[Route('/setup/login',name:'webroot.setup.login')] public function login() { diff --git a/src/Controller/WebrootSetupController.php b/src/Controller/WebrootSetupController.php index 242c595..264e697 100644 --- a/src/Controller/WebrootSetupController.php +++ b/src/Controller/WebrootSetupController.php @@ -6,15 +6,19 @@ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\HttpKernel\KernelInterface; +use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface; use Symfony\Bundle\FrameworkBundle\Console\Application; use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Output\BufferedOutput; +use Symfony\Component\Form\Form; +use Symfony\Component\Form\Extension\Core\Type as FormType; +use Symfony\Component\Yaml\Yaml; - -use MyDevel\Webroot\Entity\WebrootUser; +use App\Utility; +use App\Entity\WebrootUser; abstract class WebrootSetupController extends AbstractController { @@ -24,11 +28,18 @@ abstract class WebrootSetupController extends AbstractController */ private ?KernelInterface $kernel = null; private ?string $project_dir = null; + private ?UserPasswordHasherInterface $password_hasher; - public function __construct(KernelInterface $kernel) { + public function __construct(KernelInterface $kernel, UserPasswordHasherInterface $password_hasher) { $this->kernel = $kernel; $this->project_dir = $kernel->getProjectDir(); + $this->password_hasher = $password_hasher; + Utility\gettext_lib_init( + WEBROOT_GETTEXT_DOMAIN, + join(DIRECTORY_SEPARATOR,[$this->project_dir,"translations"]), + getenv("LANG")); + } /** @@ -97,6 +108,7 @@ abstract class WebrootSetupController extends AbstractController "command" => "make:migration", "--formatted" => true, "--no-interaction" => true, + "--quiet" => true, ]); $output = new BufferedOutput(); @@ -106,7 +118,29 @@ abstract class WebrootSetupController extends AbstractController $content=$output->fetch(); if ($errc) { - throw new \Exception("make:migration failed!"); + throw new \Exception("make:migration failed!\n" . $content); + } + + return $content; + } + + protected function runCreateDatabase(): string + { + $application = new Application($this->kernel); + $application->setAutoExit(false); + + $input = new ArrayInput([ + "command" => "doctrine:database:create", + "--no-interaction" => true, + "--quiet" => true, + ]); + + $output = new BufferedOutput(); + $errc = $application->run($input,$output); + + $content = $output->fetch(); + if ($errc) { + throw new \Exception("doctrine:database:create failed!\n". $content); } return $content; @@ -122,13 +156,15 @@ abstract class WebrootSetupController extends AbstractController $application->setAutoExit(false); $input = new ArrayInput([ - "command" => "doctrine:migrations:migrate", - "--no-interaction" => true, + "command" => "doctrine:migration:migrate", + "--no-interaction" => true, + "--quiet" => true, ]); + $output = new BufferedOutput(); - $ercode = $application->run($input,$output); + $errcode = $application->run($input,$output); if ($errcode) { - throw new \Excpetion("runMigrate failed!"); + throw new \Exception("runMigrate failed!\n". $output->fetch()); } $content = $output->fetch(); @@ -145,4 +181,387 @@ abstract class WebrootSetupController extends AbstractController ["role"=>"ROLE_PUBLIC","name"=>"Public Access","description"=>"Role for public access."], ]; } + + public function createSetupForm(): Form + { + return $this->createFormBuilder() + ->add('env', FormType\ChoiceType::class,[ + "label"=>"Environment", + "mapped"=>false, + "required"=>true, + "choices"=>[ + "Production" => "prod", + "Development" => "dev" + ], + "data" => "prod"]) + ->add('locale',FormType\TextType::class,[ + "mapped"=>false, + "required"=>false]) + ->add('tempdir',FormType\TextType::class,[ + "mapped"=>false, + "required"=>false]) + ->add('site_name',FormType\TextType::class,[ + "mapped"=>false, + "required"=>true, + "help"=>_("Enter the site name that should be displayed in titles."), + "label" => _("Site name")]) + ->add('site_rootdir',FormType\TextType::class,[ + "mapped"=>false, + "required"=>true, + "label" => _("Site root directory")]) + ->add('site_email',FormType\EmailType::class,[ + "mapped"=>false, + "required"=>false, + "label" => _("Contact email")]) + ->add('user_username',FormType\TextType::class,[ + "mapped"=>false, + "required"=>true, + "label"=>_("Username")]) + ->add('user_email',FormType\EmailType::class,[ + "mapped"=>false, + "required"=>true, + "label"=> _("Email")]) + ->add("user_password0", FormType\PasswordType::class,[ + "mapped"=>false, + "required"=>true, + "label"=>_("Password")]) + ->add("user_password1",FormType\PasswordType::class,[ + "mapped"=>false, + "required"=>true, + "label"=>"Confirm Password"]) + ->add('db_migrate', FormType\CheckboxType::class,[ + "mapped"=>false, + "label"=>"Run Migrations?", + "attr"=>["checked"=>true], + "required"=>false]) + ->add('db_create', FormType\CheckboxType::class,[ + "mapped"=>false, + "label"=>"Create Database", + "required"=>false, + "attr"=>["checked"=>false]]) + ->add('db_backend',FormType\ChoiceType::class,[ + "mapped" => false, + "label" => "Backend", + "required" => true, + "choices" => [ + _("SQLite3")=>"sqlite", + _("MySQL/MariaDB")=>"mysql", + _("PostgreSQL")=>"postgresql", + _("Database URL")=>"url", + ]]) + ->add('db_database',FormType\TextType::class,[ + "mapped"=>false, + "required"=>true, + "label"=>_("Database")]) + ->add('db_host', FormType\TextType::class,[ + "mapped"=>false, + "required"=>false, + "label"=>_("Host")]) + ->add('db_port', FormType\IntegerType::class,[ + "mapped"=>false, + "required"=>false, + "label"=>_("Port")]) + ->add('db_user',FormType\TextType::class,[ + "mapped"=>false, + "required"=>false, + "label"=>_("User")]) + ->add('db_password',FormType\TextType::class,[ + "mapped"=>false, + "required"=>false, + "label"=>_("Password")]) + ->add('db_url',FormType\TextType::class,[ + "mapped"=>false, + "label"=>_("Database URL"), + "required"=>false]) + ->add('email_backend', FormType\ChoiceType::class, [ + "mapped"=>false, + "label" => _("Backend"), + "required"=>true, + "choices"=> [ + _("No email support")=>"none", + _("SMTP")=>"smtp", + _("Sendmail")=>"sendmail", + _("Naitve")=>"native", + _("User DSN")=>"dsn", + ]]) + ->add('email_path',FormType\TextType::class,[ + "mapped"=>false, + "required"=>false, + "label"=>_("Email Path")]) + ->add('email_user',FormType\TextType::class,[ + "mapped"=>false, + "required"=>false, + "label"=>_("User")]) + ->add('email_password', FormType\PasswordType::class,[ + "mapped"=>false, + "required"=>false, + "label"=> _("Password")]) + ->add('email_host',FormType\TextType::class,[ + "mapped"=>false, + "required"=>false, + "label"=>_("SMTP Host")]) + ->add('email_port',FormType\TextType::class,[ + "mapped"=>false, + "required"=>false, + "label"=>_("SMTP Port")]) + ->add('email_dsn',FormType\TextType::class,[ + "mapped"=>false, + "required"=>false, + "label"=>_("DSN")]) + ->add('email_address', FormType\EmailType::class,[ + "mapped"=>false, + "required"=>true, + "label"=>_("Sender address")]) + ->add('submit', FormType\SubmitType::class) + ->getForm(); + } + + public function setSetupFormFromData(Form $form,array $values) + { + if (array_key_exists("locale",$values)) { + $form->get("locale")->setData($values["locale"]); + } + if (array_key_exists("tempdir",$values)) { + $form->get("locale")->setData($values["tempdir"]); + } + if (array_key_exists("site", $values)) { + $site=$values["site"]; + if (array_key_exists("name", $site)) { + $form->get("site_name")->setData($site["name"]); + } + if (array_key_exists("email",$site)) { + $form->get("site_email")->setData($site["email"]); + } + } + if (array_key_exists("database",$values)) { + $db = $values["database"]; + if (array_key_exists("backend",$values)) { + $form->get("db_backend")->setData($db["backend"]); + } + if (array_key_exists("database", $db)) { + $form->get("db_database")->setData($db["database"]); + } + if (array_key_exists("host", $db)) { + $form->get("db_host")->setData($db["host"]); + } + if (array_key_exists("port",$db)) { + $form->get("db_host")->setData($db["port"]); + } + if (array_key_exists("user",$db)) { + $form->get("db_user")->setData($db["user"]); + } + if (array_key_exists("password", $db["password"])) { + $form->get("db_password")->setData($db["password"]); + } + if (array_key_exists("url",$db)) { + $form->get("db_url")->setData($db["url"]); + } + } + if (array_key_exists("user", $values)) { + $user = $values["user"]; + if (array_key_exists("username", $user)) { + $form->get("user_username")->setData($user["username"]); + } + if (array_key_exists("email",$user)) { + $form->get("user_email")->setData($user["email"]); + } + } + if (array_key_exists("email", $values)) { + $email = $values["email"]; + if (array_key_exists("backend",$email)) { + $form->get("email_backend")->setData($email["backend"]); + } + if (array_key_exists("path",$email)) { + $form->get("email_path")->setData($email["path"]); + } + if (array_key_exists("user", $email)) { + $form->get("email_user")->setData($email["user"]); + } + if (array_key_exists("password", $email["password"])) { + $form->get("email_password")->setData($email["password"]); + } + if (array_key_exists("host",$email)) { + $form->get("email_host")->setData($email["host"]); + } + if (array_key_exists("port", $email)) { + $form->get("email_port")->setData($email["port"]); + } + if (array_key_exists("dsn", $email)) { + $form->get("email_dsn")->setData($email["dsn"]); + } + if (array_key_exists("address", $email)) { + $form->get("email_address")->setData($email["address"]); + } + } + } + + public function setSetupFormDefaultsFromEnv(Form $form) + { + if (getenv("LOCALE") && strlen(getenv("LOCALE"))) { + $form->get('locale')->setData(getenv("LOCALE")); + } elseif (getenv("LANG") && strlen(getenv("LANG"))) { + $form->get('locale')->setData(getenv("LANG")); + } + if (getenv("WEBROOT_TEMP") && strlen(getenv("WEBROOT_TEMP"))) { + $form->get('tempdir')->setData(getenv("WEBROOT_TEMP")); + } elseif (getenv("TMP") && strlen(getenv("TMP"))) { + $form->get('tempdir')->setData(join(DIRECTORY_SEPARATOR,[getenv("TMP"),"webroot"])); + } elseif (getenv('TEMP') && strlen(getenv("TEMP"))) { + $form->get("tempdir")->setData(join(DIRECTORY_SEPARATOR,[getenv("TEMP"),"webroot"])); + } else { + $form->get("tempdir")->setData(join(DIRECTORY_SEPARATOR,[$this->project_dir,"temp"])); + } + if (getenv("CONTACT_EMAIL") && strlen(getenv("CONTACT_EMAIL"))) { + form->get('site_email')->setData(getenv("CONTACT_EMAIL")); + } + if (getenv("SITE_NAME") && strlen(getenv("SITE_NAME"))) { + $form->get("site_name")->setData(getenv("SITE_NAME")); + } + if (getenv("SITE_ROOTDIR") && strlen("SITE_ROOTDIR")) { + form->set("site_rootdir")->setData(getenv("SITE_ROOTDIR")); + } + if (getenv("DATABASE_URL") && strlen("DATABASE_URL")) { + $form->get("db_url")->setData(getenv("DATABASE_URL")); + $form->get("db_backend")->setData("url"); + } + if (getenv("MAILER_DSN") && strlen(getenv("MAILER_DSN"))) { + $form->get("email_dsn")->setData(getenv("MAILER_DSN")); + $form->get("email_backend")->setData("dsn"); + } + } + + public function getDataFromSetupForm(Form $form) : array + { + $data=array(); + + $locale = $form->get('locale')->getNormData(); + if ($locale && strlen($locale)) { + $data['locale'] = $locale; + } + + $tempdir = $form->get('tempdir')->getNormData(); + if ($tempdir && strlen($tempdir)) { + $data["tempdir"] = $tempdir; + } + + $site=[ + "name" => $form->get("site_name")->getNormData(), + "email" => $form->get("site_name")->getNormData() + ]; + $data["site"] = $site; + + $user = array(); + $tmp_user = new WebrootUser(); + + $user_username = $form->get('user_username')->getNormData(); + if (!$username) { + $username=""; + } + $tmp_user->setUsername($username); + $user['username']=username; + + $user_email = $form->get('user_email')->getNormData(); + if (!$user_email) { + $user_email = ""; + } + $tmp_user->setEmail($user_email); + $user['email'] = $user_email; + + $password0 = $form->get('user_password0')->get('user_password0'); + $password1 = $form->get('user_password1')->get('user_password1'); + if ((strlen($password0) >= 8) && ($password0 == $password1)) { + $passwd = $this->password_hasher->hashPassword($tmp_user,$password0); + } + $user['password'] = $passwd; + $tmp_user->setPassword($passwd); + + $data['user'] = $user; + + $db = array(); + + $db["backend"] = $form->get("db_backend")->getNormData(); + + $db_url = $form->get('db_url')->getNormData(); + if ($db_url && strlen($db_url)) { + $db['url'] = $db_url; + } + $db_database = $form->get('db_database')->getNormData(); + if ($db_database && strlen($db_database)) { + $db["database"] = $db_database; + } + $db_host = $form->get('db_host')->getNormData(); + if ($db_host && strlen($db_host)) { + $db['host'] = db_host; + } + $db_port = $form->get('db_port')->getNormData(); + if ($db_port && (int) $db_port) { + $db['port'] = "db_port"; + } + $db_user = $form->get('db_user')->getNormData(); + if ($db_user && strlen($db_user)) { + $db["user"] = $db_user; + } + $db_password = $form->get('db_password')->getNormData(); + if ($db_password && strlen($db_password)) { + $db['password'] = $db_password; + } + $data["user"] = user; + + $email = [ + "backend" => $form->get("email_backend")->getNormData(), + "address" => $form->get("email_address")->getNormData(), + ]; + + $email_path = $form->get("email_path")->getNormData(); + if ($email_path && strlen($email_path)) { + $email["path"] = $email_path; + } + + $email_user = $form->get("email_user")->getNormData(); + if ($email_user && strlen($email_user)) { + $email["user"] = $email_user; + } + + $email_host = $form->get('email_host')->getNormData(); + if ($email_host && strlen($email_host)) { + $email["host"] = $email_host; + } + + $email_port = $form->get('email_port')->getNormData(); + if ($email_port && (int) $email_port) { + $email["port"] = $email_port; + } + + $email_dsn = $form->get('email_dsn')->getNormData(); + if ($email_dsn && strlen($email_dsn)) { + $email["dsn"] = $email_dsn; + } + $data["email"] = $email; + + return $data; + } + + public function exportSetupFormToFile(Form $form,string $yaml_file) + { + $data = (new Yaml())->dump($this->getDataFromSetupForm($form)); + $file = fopen("yaml_file","w"); + fwrite($file, $data); + $fclose($file); + } + + public function setSetupFormFromFile(Form $form,string $yaml_file) + { + $this->setSetupFormFromData($form,(new Yaml())->parseFile($yaml_file)); + } + + public function setSetupDataCookie(Form $form): string + { + $old_file = filter_input($_COOKIE["--webroot-setup--"], FILTER_DEFAULT); + if ($old_file && strlen($old_file)) { + unlink($old_file); + } + $filename = tempnam($form->get("tempdir")->getNormData(),"wrsetup-"); + $this->exportSetupFormToFile($form, $filename); + setcookie("--webroot-setup--", $filename); + } } diff --git a/src/Repository/WebrootRoleRepository.php b/src/Repository/WebrootRoleRepository.php index 2dca5be..c09b100 100644 --- a/src/Repository/WebrootRoleRepository.php +++ b/src/Repository/WebrootRoleRepository.php @@ -16,6 +16,14 @@ class WebrootRoleRepository extends ServiceEntityRepository parent::__construct($registry, WebrootRole::class); } + public function findByRoleName(string $rolename): ?WebrootRole + { + return $this->createQueryBuilder("wr") + ->andWhere("wr.role = :val") + ->setParameter("val", $rolename) + ->getQuery() + ->getOneOrNullResult(); + } // /** // * @return WebrootRole[] Returns an array of WebrootRole objects // */ diff --git a/src/Utility/i18n.php b/src/Utility/i18n.php new file mode 100644 index 0000000..e7a5f57 --- /dev/null +++ b/src/Utility/i18n.php @@ -0,0 +1,39 @@ + +

Webroot Setup

+
+
+
    + {% for error in errors %} +
  • {{ error }}
  • + {% endfor %} +
+
+ {{ form_start(form) }} - {{ form_widget(form) }} +
+ {{ translations.site }} + + + + + + + + + + + + + + + + + + + + +
{{ form_label(form.locale) }}{{ form_widget(form.locale) }}{{ form_label(form.env) }}{{ form_widget(form.env) }}
{{ form_label(form.site_name) }}{{ form_widget(form.site_name) }}{{ form_label(form.site_email) }}{{ form_widget(form.site_email) }}
{{ form_label(form.site_rootdir) }}{{ form_widget(form.site_rootdir) }}{{ form_label(form.tempdir) }}{{ form_widget(form.tempdir) }}
+
+
+ {{ translations.user }} + + + + + + + + + + + + + +
{{ form_label(form.user_username) }}{{ form_widget(form.user_username) }}{{ form_label(form.user_password0) }}{{ form_widget(form.user_password0) }}
{{ form_label(form.user_email) }}{{ form_widget(form.user_email) }}{{ form_label(form.user_password1) }}{{ form_widget(form.user_password1) }}
+
+
+ {{ translations.db }} + + + + + + + + + + + + + + + + + + + + + + + + + + +
{{ form_widget(form.db_migrate) }} {{ form_label(form.db_migrate) }}{{ form_widget(form.db_create) }} {{ form_label(form.db_create) }}
{{ form_label(form.db_backend) }}{{ form_widget(form.db_backend) }}{{ form_label(form.db_database) }}{{ form_widget(form.db_database) }}
{{ form_label(form.db_host) }}{{ form_widget(form.db_host) }}{{ form_label(form.db_port) }}{{ form_widget(form.db_port) }}
{{ form_label(form.db_user) }}{{ form_widget(form.db_user) }}{{ form_label(form.db_password) }}{{ form_widget(form.db_password) }}
{{ form_label(form.db_url) }}{{ form_widget(form.db_url) }}
+
+
+ {{ translations.email }} + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{{ form_label(form.email_backend) }}{{ form_widget(form.email_backend) }}{{ form_label(form.email_address) }}{{ form_widget(form.email_address) }}
{{ form_label(form.email_user) }}{{ form_widget(form.email_user) }}{{ form_label(form.email_password) }}{{ form_widget(form.email_password) }}
{{ form_label(form.email_host) }}{{ form_widget(form.email_host) }}{{ form_label(form.email_port) }}{{ form_widget(form.email_port) }}
{{ form_label(form.email_path) }}{{ form_widget(form.email_path) }}
{{ form_label(form.email_dsn) }}{{ form_widget(form.email_dsn) }}
+
+ {{ form_widget(form.submit) }} {{ form_end(form) }}
+ {% endblock %} diff --git a/translations/de/LC_MESSAGES/messages.mo b/translations/de/LC_MESSAGES/messages.mo deleted file mode 100644 index 6c5906d1cd061dff54de8b533942893de34efc9e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 337 zcmYL@Jx{|h5Qd9j%E-dP;DHUUz!pqFHI3Uw*h!U-O0b#M1fyU_j*H-j@b~yFTo(FD zk8Zg4bkFbc(a#8TfSe*{$RTop42h8wT;AXuI{#UD_pUbq(k-mD?~SvRtk~?4EjU^8 zqD=EFDs<<30NFQY3lF=dhsseBt#T;zrx|V_Q9)Dk#909{hlG)3PGx%joM$`|st-_k zW&2hI=P8-jLXeC}P9|KkR7_ct6ud0&v1*&0YBW?@eNZA;wx|b_i4fD)jGb@x9W;=s zq0bpO0?&f@s3sQrErIlVtK3`gDDK3AjQataIt*R~>GwH^lv|8Q-}@lrd*0T z4|D%}FedMtH6Fp_9dI1OWIr6#*v??=doiEdF@St`YEWZ7j>+*PCQ_?XjztfwmpyS% zYpj=p?{E~8`ru%HyhHY-W=wBYT&gbQZpHdF-7+C;=DsjQ(~DZxjLp<+dr{4rXu2lI z?ibyb7_IAvv1NH_LCqB>iWTAFU}P9O&$%dG$ARczqiAQ=1UnOT805n&)m_o44eOcN zl2lu#qm7w_DfMa|qH1onUt6d)jkjiYMlBi}H$*MwqcU|EuCM1ls@*PH#SRDiUT{z? z4V`YhD z>q@dD80u*5DFy zmT|7PV|cl@M$428U&JxjADX@-9WiT2x3h2PR4UE+=G?f#`c$m~=|pizw6%^(qP!cc zcs%P~(7l22LE`!4&c)=+*pCIRh)?ERFHfPLhCb7^vGQheNu1zmSZOPl)JA=B>iNp9 zM$1=?P)La1eHv|FoVtwcW;N=O>Pnr8>l(L8S&qKxIqO1{EE_tW8Qb^hHEFGwwAAbE zM=seex_5jyD~>Pbv~lSP7(GSWfgUoN`m!yyAN8hq`iDHr{zJOaZm7#*os4Q9@^68@ zuElLsxg%j{d5?s5>yI0pqVF0ZmZUd)0h3 literal 0 HcmV?d00001 diff --git a/translations/de/LC_MESSAGES/mydevel.webroot.mo b/translations/de/LC_MESSAGES/mydevel.webroot.mo deleted file mode 100644 index 6c5906d1cd061dff54de8b533942893de34efc9e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 337 zcmYL@Jx{|h5Qd9j%E-dP;DHUUz!pqFHI3Uw*h!U-O0b#M1fyU_j*H-j@b~yFTo(FD zk8Zg4bkFbc(a#8TfSe*{$RTop42h8wT;AXuI{#UD_pUbq(k-mD?~SvRtk~?4EjU^8 zqD=EFDs<<30NFQY3lF=dhsseBt#T;zrx|V_Q9)Dk#909{hlG)3PGx%joM$`|st-_k zW&2hI=P8-jLXeC}P9|KkR7_ct6ud0&v1*&0YBW?@eNZA;wx|b_i4fD)jGb@x9W;=s z