From 62ebcde2dec7123c2294639a455beac550f30cbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 30 Mar 2025 14:23:21 +0200 Subject: [PATCH 1/4] New Crowdin updates (#899) * New translations messages.en.xlf (English) * New translations messages.en.xlf (German) --- translations/messages.de.xlf | 24 +++++++++++ translations/messages.en.xlf | 79 ++++++++++++++++++------------------ 2 files changed, 63 insertions(+), 40 deletions(-) diff --git a/translations/messages.de.xlf b/translations/messages.de.xlf index b17243bc..24e140c8 100644 --- a/translations/messages.de.xlf +++ b/translations/messages.de.xlf @@ -12341,5 +12341,29 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön Externe Version anzeigen + + + part.table.actions.error + Es traten %count% Fehler bei der Aktion auf! + + + + + part.table.actions.error_detail + %part_name% (ID: %part_id%): %message% + + + + + part_list.action.action.change_location + Lagerort ändern (nur für Bauteile mit einzelnem Bestand) + + + + + parts.table.action_handler.error.part_lots_multiple + Dieses Bauteil enthält mehr als einen Bestand. Ändere den Lagerort bei Hand, um auszuwählen, welcher Bestand geändert werden soll. + + diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf index d52e45ac..e974d34a 100644 --- a/translations/messages.en.xlf +++ b/translations/messages.en.xlf @@ -242,7 +242,7 @@ part.info.timetravel_hint - Please note that this feature is experimental, so the info may not be correct.]]> + This is how the part appeared before %timestamp%. <i>Please note that this feature is experimental, so the info may not be correct.</i> @@ -731,10 +731,10 @@ user.edit.tfa.disable_tfa_message - all active two-factor authentication methods of the user and delete the backup codes! -
-The user will have to set up all two-factor authentication methods again and print new backup codes!

-Only do this if you are absolutely sure about the identity of the user (seeking help), otherwise the account could be compromised by an attacker!]]>
+ This will disable <b>all active two-factor authentication methods of the user</b> and delete the <b>backup codes</b>! +<br> +The user will have to set up all two-factor authentication methods again and print new backup codes! <br><br> +<b>Only do this if you are absolutely sure about the identity of the user (seeking help), otherwise the account could be compromised by an attacker!</b>
@@ -885,9 +885,9 @@ The user will have to set up all two-factor authentication methods again and pri entity.delete.message - -Sub elements will be moved upwards.]]> + This can not be undone! +<br> +Sub elements will be moved upwards. @@ -1441,7 +1441,7 @@ Sub elements will be moved upwards.]]> homepage.github.text - GitHub project page]]> + Source, downloads, bug reports, to-do-list etc. can be found on <a href="%href%" class="link-external" target="_blank">GitHub project page</a> @@ -1463,7 +1463,7 @@ Sub elements will be moved upwards.]]> homepage.help.text - GitHub page]]> + Help and tips can be found in Wiki the <a href="%href%" class="link-external" target="_blank">GitHub page</a> @@ -1705,7 +1705,7 @@ Sub elements will be moved upwards.]]> email.pw_reset.fallback - %url% and enter the following info]]> + If this does not work for you, go to <a href="%url%">%url%</a> and enter the following info @@ -1735,7 +1735,7 @@ Sub elements will be moved upwards.]]> email.pw_reset.valid_unit %date% - %date%.]]> + The reset token will be valid until <i>%date%</i>. @@ -3578,8 +3578,8 @@ Sub elements will be moved upwards.]]> tfa_google.disable.confirm_message - -Also note that without two-factor authentication, your account is no longer as well protected against attackers!]]> + If you disable the Authenticator App, all backup codes will be deleted, so you may need to reprint them.<br> +Also note that without two-factor authentication, your account is no longer as well protected against attackers! @@ -3599,7 +3599,7 @@ Also note that without two-factor authentication, your account is no longer as w tfa_google.step.download - Google Authenticator oder FreeOTP Authenticator)]]> + Download an authenticator app (e.g. <a class="link-external" target="_blank" href="https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2">Google Authenticator</a> oder <a class="link-external" target="_blank" href="https://play.google.com/store/apps/details?id=org.fedorahosted.freeotp">FreeOTP Authenticator</a>) @@ -3841,8 +3841,8 @@ Also note that without two-factor authentication, your account is no longer as w tfa_trustedDevices.explanation - all computers here.]]> + When checking the second factor, the current computer can be marked as trustworthy, so no more two-factor checks on this computer are needed. +If you have done this incorrectly or if a computer is no longer trusted, you can reset the status of <i>all </i>computers here. @@ -5313,7 +5313,7 @@ If you have done this incorrectly or if a computer is no longer trusted, you can label_options.lines_mode.help - Twig documentation and Wiki for more information.]]> + If you select Twig here, the content field is interpreted as Twig template. See <a href="https://twig.symfony.com/doc/3.x/templates.html">Twig documentation</a> and <a href="https://docs.part-db.de/usage/labels.html#twig-mode">Wiki</a> for more information. @@ -9388,25 +9388,25 @@ Element 3 filter.parameter_value_constraint.operator.< - + Typ. Value < filter.parameter_value_constraint.operator.> - ]]> + Typ. Value > filter.parameter_value_constraint.operator.<= - + Typ. Value <= filter.parameter_value_constraint.operator.>= - =]]> + Typ. Value >= @@ -9514,7 +9514,7 @@ Element 3 parts_list.search.searching_for - %keyword%]]> + Searching parts with keyword <b>%keyword%</b> @@ -10174,13 +10174,13 @@ Element 3 project.builds.number_of_builds_possible - %max_builds% builds of this project.]]> + You have enough stocked to build <b>%max_builds%</b> builds of this project. project.builds.check_project_status - "%project_status%". You should check if you really want to build the project with this status!]]> + The current project status is <b>"%project_status%"</b>. You should check if you really want to build the project with this status! @@ -10282,7 +10282,7 @@ Element 3 entity.select.add_hint - to create nested structures, e.g. "Node 1->Node 1.1"]]> + Use -> to create nested structures, e.g. "Node 1->Node 1.1" @@ -10306,13 +10306,13 @@ Element 3 homepage.first_steps.introduction - documentation or start to creating the following data structures:]]> + Your database is still empty. You might want to read the <a href="%url%">documentation</a> or start to creating the following data structures: homepage.first_steps.create_part - create a new part.]]> + Or you can directly <a href="%url%">create a new part</a>. @@ -10324,7 +10324,7 @@ Element 3 homepage.forum.text - discussion forum]]> + For questions about Part-DB use the <a href="%href%" class="link-external" target="_blank">discussion forum</a> @@ -10978,7 +10978,7 @@ Element 3 parts.import.help_documentation - documentation for more information on the file format.]]> + See the <a href="%link%">documentation</a> for more information on the file format. @@ -11158,7 +11158,7 @@ Element 3 part.filter.lessThanDesired - + In stock less than desired (total amount < min. amount) @@ -11970,13 +11970,13 @@ Please note, that you can not impersonate a disabled user. If you try you will g part.merge.confirm.title - %other% into %target%?]]> + Do you really want to merge <b>%other%</b> into <b>%target%</b>? part.merge.confirm.message - %other% will be deleted, and the part will be saved with the shown information.]]> + <b>%other%</b> will be deleted, and the part will be saved with the shown information. @@ -12346,26 +12346,25 @@ Please note, that you can not impersonate a disabled user. If you try you will g - + part.table.actions.error - %count% errors occured, while performing action: + %count% errors occured, while performing action: - + part.table.actions.error_detail - %part_name% (ID: %part_id%): %message% - + %part_name% (ID: %part_id%): %message% - + part_list.action.action.change_location Change location (only for parts with single stock) - + parts.table.action_handler.error.part_lots_multiple This part contains more than one stock. Change the location by hand to select, which stock to choose. From c8375def1ab4a734c84e44b8674833714f506382 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 30 Mar 2025 14:47:48 +0200 Subject: [PATCH 2/4] Added an database automigration feature to the docker image --- .docker/partdb-entrypoint.sh | 42 ++++++++++++++++++++++++ docs/installation/installation_docker.md | 12 +++++++ 2 files changed, 54 insertions(+) diff --git a/.docker/partdb-entrypoint.sh b/.docker/partdb-entrypoint.sh index 5bfc6b48..ffd2b24a 100644 --- a/.docker/partdb-entrypoint.sh +++ b/.docker/partdb-entrypoint.sh @@ -42,6 +42,48 @@ fi # Start PHP-FPM (the PHP_VERSION is replaced by the configured version in the Dockerfile) service phpPHP_VERSION-fpm start + +# Run migrations if automigration is enabled via env variable DB_AUTOMIGRATE +if [ "$DB_AUTOMIGRATE" = "true" ]; then + echo "Waiting for database to be ready..." + ATTEMPTS_LEFT_TO_REACH_DATABASE=60 + until [ $ATTEMPTS_LEFT_TO_REACH_DATABASE -eq 0 ] || DATABASE_ERROR=$(sudo -E -u www-data php bin/console dbal:run-sql -q "SELECT 1" 2>&1); do + if [ $? -eq 255 ]; then + # If the Doctrine command exits with 255, an unrecoverable error occurred + ATTEMPTS_LEFT_TO_REACH_DATABASE=0 + break + fi + sleep 1 + ATTEMPTS_LEFT_TO_REACH_DATABASE=$((ATTEMPTS_LEFT_TO_REACH_DATABASE - 1)) + echo "Still waiting for database to be ready... Or maybe the database is not reachable. $ATTEMPTS_LEFT_TO_REACH_DATABASE attempts left." + done + + if [ $ATTEMPTS_LEFT_TO_REACH_DATABASE -eq 0 ]; then + echo "The database is not up or not reachable:" + echo "$DATABASE_ERROR" + exit 1 + else + echo "The database is now ready and reachable" + fi + + # Check if there are any available migrations to do, by executing doctrine:migrations:up-to-date + # and checking if the exit code is 0 (up to date) or 1 (not up to date) + if sudo -E -u www-data php bin/console doctrine:migrations:up-to-date --no-interaction; then + echo "Database is up to date, no migrations necessary." + else + echo "Migrations available..." + echo "Do backup of database..." + + sudo -E -u www-data mkdir -p /var/www/html/uploads/.automigration-backup/ + # Backup the database + sudo -E -u www-data php bin/console partdb:backup -n --database /var/www/html/uploads/.automigration-backup/backup-$(date +%Y-%m-%d_%H-%M-%S).zip + + # Check if there are any migration files + sudo -E -u www-data php bin/console doctrine:migrations:migrate --no-interaction + fi + +fi + # first arg is `-f` or `--some-option` (taken from https://github.com/docker-library/php/blob/master/8.2/bullseye/apache/docker-php-entrypoint) if [ "${1#-}" != "$1" ]; then set -- apache2-foreground "$@" diff --git a/docs/installation/installation_docker.md b/docs/installation/installation_docker.md index cb24e6c1..c9b46fdb 100644 --- a/docs/installation/installation_docker.md +++ b/docs/installation/installation_docker.md @@ -47,6 +47,12 @@ services: - DATABASE_URL=sqlite:///%kernel.project_dir%/var/db/app.db # In docker env logs will be redirected to stderr - APP_ENV=docker + + # Uncomment this, if you want to use the automatic database migration feature. With this you have you do not have to + # run the doctrine:migrations:migrate commands on installation or upgrade. A database backup is written to the uploads/ + # folder (under .automigration-backup), so you can restore it, if the migration fails. + # This feature is currently experimental, so use it at your own risk! + # - DB_AUTOMIGRATE=true # You can configure Part-DB using environment variables # Below you can find the most essential ones predefined @@ -130,6 +136,12 @@ services: # In docker env logs will be redirected to stderr - APP_ENV=docker + # Uncomment this, if you want to use the automatic database migration feature. With this you have you do not have to + # run the doctrine:migrations:migrate commands on installation or upgrade. A database backup is written to the uploads/ + # folder (under .automigration-backup), so you can restore it, if the migration fails. + # This feature is currently experimental, so use it at your own risk! + # - DB_AUTOMIGRATE=true + # You can configure Part-DB using environment variables # Below you can find the most essential ones predefined # However you can add add any other environment configuration you want here From f802c6c1762b77b43819ba294384dd73e5db961c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 30 Mar 2025 14:50:52 +0200 Subject: [PATCH 3/4] Exclude automigration-backup folder from clean attachments folder --- src/Command/Attachments/CleanAttachmentsCommand.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Command/Attachments/CleanAttachmentsCommand.php b/src/Command/Attachments/CleanAttachmentsCommand.php index e9ffd286..59bc99ee 100644 --- a/src/Command/Attachments/CleanAttachmentsCommand.php +++ b/src/Command/Attachments/CleanAttachmentsCommand.php @@ -73,6 +73,9 @@ class CleanAttachmentsCommand extends Command //Ignore image cache folder $finder->exclude('cache'); + //Ignore automigration folder + $finder->exclude('.automigration-backup'); + $fs = new Filesystem(); $file_list = []; From f9e769a6e34e9cdca97baa9f8f4f3e77f8ae031f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 30 Mar 2025 15:01:28 +0200 Subject: [PATCH 4/4] Fixed phpstan issue --- src/Services/Parts/PartsTableActionHandler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Services/Parts/PartsTableActionHandler.php b/src/Services/Parts/PartsTableActionHandler.php index 767dc2ba..616df229 100644 --- a/src/Services/Parts/PartsTableActionHandler.php +++ b/src/Services/Parts/PartsTableActionHandler.php @@ -65,7 +65,7 @@ final class PartsTableActionHandler /** * @param Part[] $selected_parts * @return RedirectResponse|null Returns a redirect response if the user should be redirected to another page, otherwise null - * @phpstan-param-out array $errors + * //@param-out list|array $errors */ public function handleAction(string $action, array $selected_parts, ?int $target_id, ?string $redirect_url = null, array &$errors = []): ?RedirectResponse {